Add and delete callbacks

This guide explains how to use callbacks with the Google Wallet API. When a pass is created or deleted, Google can perform a callback to an HTTPS endpoint of your choosing. This callback is class-specific, and includes data about the event such as the class, object, and event type. This can be used to keep track of the number of user adds and deletions that occur. For example, callbacks can be configured to send events to an analytics application to track customer engagement during promotional events.

Prerequisites

Before you start, review the following prerequisites:

  • Stand up an HTTPS endpoint that handles POST requests. This endpoint needs to be publicly available.
  • Programmatically update the callback endpoint for each class. See the callbackOptions property by class in the REST API.
  • Recommended: Use the Tink library to verify the signatures.

Implement callbacks

For every add or delete performed by the user on an an object , Google makes callbacks to the merchants with details about the add or delete on a per-class URL. Merchants need to first use the Public Keys to verify the authenticity of the message. After the callbacks verify the message, the callbacks can be used for downstream operations.

Verify the signature

We recommend that you use the Tink library to verify the message signature when you implement your HTTPS endpoint. The Tink library provides PaymentMethodTokenRecipient , a utility that automatically verifies the signature and returns the actual message upon successful verification.

The following example shows how to use the Tink library to implement PaymentMethodTokenRecipient :

 import 
  
 java.io.IOException 
 ; 
 import 
  
 javax.servlet.http. 
 * 
 ; 
 import 
  
 com.google.common.io.CharStreams 
 ; 
 import 
  
 com.google.crypto.tink.apps.paymentmethodtoken. 
 * 
 ; 
 // 
 Replace 
 ISSUER_ID 
 with 
 your 
 issuer 
 id 
 private 
 static 
 final 
 String 
 RECIPIENT_ID 
 = 
 " ISSUER_ID 
" 
 ; 
 private 
 static 
 final 
 String 
 PUBLIC_KEY_URL 
 = 
 "https://pay.google.com/gp/m/issuer/keys" 
 ; 
 private 
 static 
 final 
 String 
 SENDER_ID 
 = 
 "GooglePayPasses" 
 ; 
 private 
 static 
 final 
 String 
 PROTOCOL 
 = 
 "ECv2SigningOnly" 
 ; 
 private 
 static 
 final 
 GooglePaymentsPublicKeysManager 
 keysManager 
 = 
 new 
 GooglePaymentsPublicKeysManager 
 . 
 Builder 
 () 
 . 
 setKeysUrl 
 ( 
 PUBLIC_KEY_URL 
 ) 
 . 
 build 
 (); 
 public 
 void 
 doPost 
 ( 
 HttpServletRequest 
 request 
 , 
 HttpServletResponse 
 response 
 ) 
 throws 
 IOException 
 { 
 try 
 { 
 // 
 Extract 
 signed 
 message 
 with 
 signature 
 from 
  
 POST 
 request 
 body 
 . 
 String 
 signedMessage 
 = 
 CharStreams 
 . 
 toString 
 ( 
 request 
 . 
 getReader 
 ()); 
 PaymentMethodTokenRecipient 
 recipient 
 = 
 new 
 PaymentMethodTokenRecipient 
 . 
 Builder 
 () 
 . 
 protocolVersion 
 ( 
 PROTOCOL 
 ) 
 . 
 fetchSenderVerifyingKeysWith 
 ( 
 keysManager 
 ) 
 . 
 senderId 
 ( 
 SENDER_ID 
 ) 
 . 
 recipientId 
 ( 
 RECIPIENT_ID 
 ) 
 . 
 build 
 (); 
 String 
 serializedJsonMessage 
 = 
 recipient 
 . 
 unseal 
 ( 
 signedMessage 
 ); 
 // 
 Use 
 serializedJsonMessage 
 to 
 extract 
 the 
 details 
 } 
 catch 
 ( 
 Exception 
 e 
 ) 
 { 
 // 
 Handle 
 the 
 error 
 } 
 } 

Expected message format

The message format is JSON that's serialized into a string with the following properties:

Identifier Description
classId

Fully qualified class ID. Uses the following format:

<issuer_id.class_id>
objectId

Fully qualified object ID. Uses the following format:

<issuer_id.object_id>
expTimeMillis Expiration time in milliseconds since EPOCH. After the expiration time, the message needs to be deemed invalid.
eventType Can be either del or save for DELETE and SAVE .
nonce Nonce to track any duplicate deliveries.

Handle the request from a Google server

The following is a list of the key fields in the header of the request that's sent to your callback endpoint:

  • User-Agent: Googlebot
  • Content-Type: application/json

Configure your server so that it doesn't reject the request. To do so, you can set the following in robots.txt :

User-agent: Googlebot
Disallow:

Retries

Callbacks are on a best-effort basis. Google will use common retry strategies to be resilient in cases where the callback endpoint is not responding or has an intermittent outage and will gracefully back off attempts.

Duplicate deliveries

There might be duplicate deliveries in some cases. We recommend that you use nonce to dedupe them.

Create a Mobile Website
View Site in Mobile | Classic
Share by: