บันทึกและลบการแจ้งเตือน
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
คู่มือนี้จะอธิบายวิธีใช้ Callback กับ Google Wallet API เมื่อ
สร้างหรือลบบัตรแล้ว Google สามารถดำเนินการเรียกกลับไปยัง HTTPS
ปลายทางที่คุณเลือก
Callback นี้เป็นแบบเฉพาะชั้นเรียนและมีข้อมูล
เกี่ยวกับเหตุการณ์ เช่น คลาส ออบเจ็กต์ และประเภทเหตุการณ์
การตั้งค่านี้สามารถใช้เพื่อ
ติดตามจำนวนการเพิ่มและการลบผู้ใช้ที่เกิดขึ้น สำหรับ
ตัวอย่างเช่น คุณสามารถกำหนดค่าให้ Callback ส่งเหตุการณ์ไปยัง Analytics ได้
แอปพลิเคชันสำหรับติดตามการมีส่วนร่วมของลูกค้าระหว่างกิจกรรมส่งเสริมการขาย
ข้อกำหนดเบื้องต้น
โปรดอ่านข้อกำหนดเบื้องต้นต่อไปนี้ก่อนเริ่มใช้งาน
-
สร้างปลายทาง HTTPS ที่จัดการคำขอ POST ปลายทางนี้ต้องการ
เผยแพร่ต่อสาธารณะ
-
อัปเดตปลายทาง Callback แบบเป็นโปรแกรมสำหรับแต่ละคลาส โปรดดู
callbackOptions
ตามคลาสใน REST API
- แนะนำ: ใช้ไลบรารี Tink เพื่อยืนยันลายเซ็น
ใช้ Callback
สำหรับการเพิ่มหรือลบทุกรายการที่ผู้ใช้ดำเนินการใน
วัตถุ
Google จะติดต่อกลับหาผู้ขายพร้อมด้วยรายละเอียดเกี่ยวกับการเพิ่มหรือลบใน
ต่อชั้นเรียน
URL ผู้ขายต้องใช้คีย์สาธารณะเพื่อยืนยันความถูกต้องของ
ข้อความนั้น หลังจาก Callback ยืนยันข้อความแล้ว คุณจะใช้ Callback ได้
สำหรับการดำเนินงานดาวน์สตรีม
ยืนยันลายเซ็น
เราขอแนะนำให้ใช้ไลบรารี Tink เพื่อยืนยันลายเซ็นของข้อความ
เมื่อคุณใช้ปลายทาง HTTPS
ไลบรารีของ Tik
ให้ 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 ที่แปลงเป็นสตริงที่มีข้อมูลต่อไปนี้
พร็อพเพอร์ตี้:
ตัวระบุ |
คำอธิบาย |
classId |
รหัสคลาสที่มีคุณสมบัติครบถ้วน ใช้รูปแบบต่อไปนี้
<issuer_id.class_id>
|
objectId |
รหัสออบเจ็กต์ที่สมบูรณ์ในตัวเอง ใช้รูปแบบต่อไปนี้
<issuer_id.object_id>
|
expTimeMillis |
เวลาหมดอายุเป็นมิลลิวินาทีตั้งแต่ EPOCH หลังจากเวลาหมดอายุ
ข้อความจะต้องถือว่าไม่ถูกต้อง
|
eventType |
อาจเป็น del หรือ save ก็ได้สำหรับ
DELETE และ SAVE
|
nonce |
Nonce เพื่อติดตามการจัดส่งที่ซ้ำกัน |
จัดการคำขอจากเซิร์ฟเวอร์ของ Google
รายการช่องคีย์ในส่วนหัวของคำขอที่
ที่ส่งไปยังปลายทาง Callback
- User-Agent:
Googlebot
- ประเภทเนื้อหา:
application/json
กำหนดค่าเซิร์ฟเวอร์เพื่อให้ไม่ปฏิเสธคำขอ วิธีการคือ
ตั้งค่าต่อไปนี้ใน robots.txt
:
User-agent: Googlebot
Disallow:
ลองอีกครั้ง
เราจะพยายามอย่างเต็มที่ Callback Google จะใช้กลยุทธ์การลองอีกครั้งทั่วไป
มีความยืดหยุ่นในกรณีที่ปลายทาง Callback ไม่ตอบสนองหรือมี
การหยุดทำงานเกิดขึ้นเป็นพักๆ และจะพยายามชดเชยให้ไม่สำเร็จ
การนำส่งที่ซ้ำกัน
อาจมีการจัดส่งซ้ำในบางกรณี เราขอแนะนำให้คุณใช้
nonce
เพื่อกรองข้อมูลที่ซ้ำกันออก
เนื้อหาของหน้าเว็บนี้ได้รับอนุญาตภายใต้ใบอนุญาตที่ต้องระบุที่มาของครีเอทีฟคอมมอนส์ 4.0 และตัวอย่างโค้ดได้รับอนุญาตภายใต้ใบอนุญาต Apache 2.0 เว้นแต่จะระบุไว้เป็นอย่างอื่น โปรดดูรายละเอียดที่นโยบายเว็บไซต์ Google Developers Java เป็นเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-08-29 UTC
[null,null,["อัปเดตล่าสุด 2025-08-29 UTC"],[[["\u003cp\u003eGoogle Wallet API allows you to set up callbacks to an HTTPS endpoint to track pass creation and deletion events.\u003c/p\u003e\n"],["\u003cp\u003eThese callbacks provide data like class ID, object ID, and event type, allowing you to monitor user engagement and perform analytics.\u003c/p\u003e\n"],["\u003cp\u003eBefore implementing callbacks, ensure you have a publicly available HTTPS endpoint, update the callback endpoint for each class, and consider using the Tink library for signature verification.\u003c/p\u003e\n"],["\u003cp\u003eGoogle uses a JSON message format for callbacks, containing details about the event, and employs retry strategies for delivery.\u003c/p\u003e\n"],["\u003cp\u003eYou should handle potential duplicate deliveries using the provided 'nonce' and configure your server to accept requests from Googlebot.\u003c/p\u003e\n"]]],["Google Wallet API callbacks notify merchants via HTTPS endpoints when a pass is added or deleted. These class-specific callbacks provide details like class ID, object ID, event type (save/delete), and a nonce for deduplication. Merchants must set up a public HTTPS endpoint, update the callback URL per class, and verify message signatures using the Tink library. The endpoint should accept POST requests and expect JSON-formatted messages; it should also allow requests from the Googlebot user-agent.\n"],null,["# Save and delete notifications\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/tickets/transit-passes/qr-code/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."]]