新增及刪除回呼
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
本指南將說明如何透過 Google Wallet API 使用回呼。如果
Google 便可對 HTTPS 執行回呼
所選端點
這個回呼專屬於特定類別,且包含資料
關於事件,例如類別、物件和事件類型。
這項策略可用來
追蹤發生新增及刪除的使用者人數。適用對象
例如,您可以設定回呼來將事件傳送至數據分析
應用程式,以追蹤促銷活動期間的客戶參與度。
必要條件
開始之前,請詳閱下列必要條件:
-
啟動處理 POST 要求的 HTTPS 端點。這個端點需要
-
透過程式輔助方式更新每個類別的回呼端點。詳情請參閱
callbackOptions
敬上
定義屬性。
- 建議做法:使用 Tink 程式庫驗證簽名。
實作回呼
每當使用者在應用程式中新增或刪除
物件
,Google 會向商家進行回呼,並提供
每項類別
網址。商家必須先使用公開金鑰來驗證
訊息。在回呼驗證訊息之後,即可使用回呼
用於下游作業
驗證簽章
建議您使用 Tink 程式庫驗證訊息簽名
在您實作 HTTPS 端點時
Tink 程式庫
提供的 PaymentMethodTokenRecipient
公用程式
會自動驗證簽章,並在
驗證成功。
以下範例說明如何使用 Tink 程式庫進行實作
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
}
}
訊息格式為 JSON,已序列化為字串,包含下列內容
屬性:
ID |
說明 |
classId |
完整的類別 ID,格式如下:
<issuer_id.class_id>
|
objectId |
完整物件 ID。格式如下:
<issuer_id.object_id>
|
expTimeMillis |
自 EPOCH 起的到期時間 (以毫秒為單位)。到期後
進而視為無效。
|
eventType |
可以是 del 或 save ,
DELETE 和SAVE 。
|
nonce |
Nonce,可追蹤任何重複的傳送事件。 |
處理 Google 伺服器發出的要求
以下是要求標頭中的鍵欄位清單,
:
- 使用者代理程式:
Googlebot
- 內容類型:
application/json
設定伺服器,禁止伺服器拒絕要求。如要這麼做,
在 robots.txt
中設定以下內容:
User-agent: Googlebot
Disallow:
重試
回呼會盡可能履行。Google 會採用常見的重試策略
至於回呼端點未回應或
服務中斷,並且會在正常情況下及時停止嘗試。
重複提交
在某些情況下,系統可能會重複傳送訊息。建議您使用
nonce
即可刪除重複的資料。
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-08-29 (世界標準時間)。
[null,null,["上次更新時間:2025-08-29 (世界標準時間)。"],[[["\u003cp\u003eGoogle Wallet API callbacks allow you to receive real-time updates when passes are created or deleted by users.\u003c/p\u003e\n"],["\u003cp\u003eThese callbacks send data to your HTTPS endpoint, enabling you to track user engagement and perform custom actions.\u003c/p\u003e\n"],["\u003cp\u003eYou need to set up an HTTPS endpoint, update the callback endpoint for each class, and verify the signature using a library like Tink.\u003c/p\u003e\n"],["\u003cp\u003eThe callback message contains information about the event, such as class ID, object ID, event type, and a nonce to handle duplicates.\u003c/p\u003e\n"],["\u003cp\u003eCallbacks are on a best-effort basis with retry strategies, and you should handle potential duplicate deliveries using the nonce.\u003c/p\u003e\n"]]],["Google Wallet API uses callbacks to notify merchants of pass creation or deletion events. Merchants must set up a public HTTPS endpoint to receive these POST requests and update the callback endpoint per class via the API. Callbacks include class, object, and event type data (save or delete). Merchants should use the Tink library to verify message signatures using public keys, then utilize the JSON payload to process the event data. Google sends the requests with the header user-agent `Googlebot`.\n"],null,["# Add and delete callbacks\n\nThis guide explains how to use callbacks with the Google Wallet API. When a\npass is created or deleted, Google can perform a callback to an HTTPS\nendpoint of your choosing.\n\nThis callback is class-specific, and includes data\nabout the event such as the class, object, and event type.\n\nThis can be used to\nkeep track of the number of user adds and deletions that occur. For\nexample, callbacks can be configured to send events to an analytics\napplication to track customer engagement during promotional events.\n\nPrerequisites\n-------------\n\nBefore you start, review the following prerequisites:\n\n- Stand up an HTTPS endpoint that handles POST requests. This endpoint needs to be publicly available.\n- Programmatically update the callback endpoint for each class. See the [`callbackOptions`](/wallet/retail/gift-cards/rest/v1/CallbackOptions) property by class in the REST API.\n- Recommended: Use the [Tink](https://developers.google.com/tink) library to verify the signatures.\n\nImplement callbacks\n-------------------\n\n\nFor every add or delete performed by the user on an\n\nan object\n\n, Google makes callbacks to the merchants with details about the add or delete on a\n\nper-class\n\nURL. Merchants need to first use the Public Keys to verify the authenticity of\nthe message. After the callbacks verify the message, the callbacks can be used\nfor downstream operations.\n\nVerify the signature\n--------------------\n\n\nWe recommend that you use the Tink library to verify the message signature\nwhen you implement your HTTPS endpoint. The\n[Tink library](https://github.com/google/tink)\nprovides `PaymentMethodTokenRecipient`, a utility that\nautomatically verifies the signature and returns the actual message upon\nsuccessful verification.\n\n\nThe following example shows how to use the Tink library to implement\n`PaymentMethodTokenRecipient`: \n\n```python\nimport java.io.IOException;\nimport javax.servlet.http.*;\nimport com.google.common.io.CharStreams;\nimport com.google.crypto.tink.apps.paymentmethodtoken.*;\n\n// Replace ISSUER_ID with your issuer id\nprivate static final String RECIPIENT_ID = \"\u003cvar translate=\"no\"\u003eISSUER_ID\u003c/var\u003e\";\n\nprivate static final String PUBLIC_KEY_URL = \"https://pay.google.com/gp/m/issuer/keys\";\nprivate static final String SENDER_ID = \"GooglePayPasses\";\nprivate static final String PROTOCOL = \"ECv2SigningOnly\";\n\nprivate static final GooglePaymentsPublicKeysManager keysManager = new GooglePaymentsPublicKeysManager.Builder()\n .setKeysUrl(PUBLIC_KEY_URL)\n .build();\n\npublic void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {\n try {\n // Extract signed message with signature from POST request body.\n String signedMessage = CharStreams.toString(request.getReader());\n PaymentMethodTokenRecipient recipient =\n new PaymentMethodTokenRecipient.Builder()\n .protocolVersion(PROTOCOL)\n .fetchSenderVerifyingKeysWith(keysManager)\n .senderId(SENDER_ID)\n .recipientId(RECIPIENT_ID)\n .build();\n\n String serializedJsonMessage = recipient.unseal(signedMessage);\n\n // Use serializedJsonMessage to extract the details\n } catch (Exception e) {\n // Handle the error\n }\n}\n```\n\nExpected message format\n-----------------------\n\n\nThe message format is JSON that's serialized into a string with the following\nproperties:\n\n| Identifier | Description |\n|-----------------|-----------------------------------------------------------------------------------------------------------------|\n| `classId` | Fully qualified class ID. Uses the following format: ``` \u003cissuer_id.class_id\u003e ``` |\n| `objectId` | Fully qualified object ID. Uses the following format: ``` \u003cissuer_id.object_id\u003e ``` |\n| `expTimeMillis` | Expiration time in milliseconds since EPOCH. After the expiration time, the message needs to be deemed invalid. |\n| `eventType` | Can be either `del` or `save` for `DELETE` and `SAVE`. |\n| `nonce` | Nonce to track any duplicate deliveries. |\n\n### Handle the request from a Google server\n\n\nThe following is a list of the key fields in the header of the request that's\nsent to your callback endpoint:\n\n- User-Agent: `Googlebot`\n- Content-Type: `application/json`\n\n\nConfigure your server so that it doesn't reject the request. To do so, you can\nset the following in `robots.txt`: \n\n```\nUser-agent: Googlebot\nDisallow:\n```\n\n### Retries\n\n\nCallbacks are on a best-effort basis. Google will use common retry strategies\nto be resilient in cases where the callback endpoint is not responding or has an\nintermittent outage and will gracefully back off attempts.\n\n### Duplicate deliveries\n\n\nThere might be duplicate deliveries in some cases. We recommend that you use\n`nonce` to dedupe them."]]