通知資料已編碼。您可以將資料解碼為可讀取的文字格式,以便在實作中使用。以下是您可能用於處理經過編碼的資料的 Spring Boot 控制器範例:
@RestControllerpublicclassExampleController{@RequestMapping(value="/push",method=RequestMethod.POST,consumes={"application/json"},produces={"text/plain"})@ResponseStatus(HttpStatus.OK)publicvoiddoStuff(@RequestBodyStringmessage){//wrapped messageJSONObjectjsonObject=newJSONObject(message);JSONObjectjsonMessage=jsonObject.getJSONObject("message");message=jsonMessage.getString("data");byte[]decodedBytes=Base64.getDecoder().decode(message);StringdecodedMessage=newString(decodedBytes);// Implement your business logic here}}
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-08-08 (世界標準時間)。"],[[["\u003cp\u003eReceive real-time push notifications for changes to your Google Merchant Center account data, such as product disapprovals, through the Merchant Notifications API.\u003c/p\u003e\n"],["\u003cp\u003eSubscribe to notifications by providing a valid HTTPS callback URI that can accept POST requests and acknowledge receipt with specific response codes.\u003c/p\u003e\n"],["\u003cp\u003eCustomize your notifications by specifying the target account, event type (like \u003ccode\u003ePRODUCT_STATUS_CHANGE\u003c/code\u003e), and whether to include all managed accounts.\u003c/p\u003e\n"],["\u003cp\u003eDecode the base64-encoded notification data to access information about the change, including the affected product, attribute, old and new values, and reporting context.\u003c/p\u003e\n"],["\u003cp\u003eTest your implementation using a provided sample notification and ensure your callback URI returns a successful response code and decodes the message correctly.\u003c/p\u003e\n"]]],["The Merchant Notifications API enables real-time push notifications for account data changes, like product status updates. To receive notifications, you must subscribe with a `callBackUri`, a publicly accessible HTTPS address accepting `POST` requests, returning `102`, `200`, `201`, `202`, or `204` response codes. Subscriptions are made via a `POST` request with a `registeredEvent`, `targetAccount` or `allManagedAccounts`, and `callBackUri`. Notifications are base64 encoded and sent to the callback URI. `PATCH` requests can update subscriptions.\n"],null,["# Get push notifications for changes to your product data\n\nYou can use the Merchant Notifications API to get push notifications for changes\nto product data. For example, if you subscribe to product status change\nnotifications, you can be notified in real time when a product is disapproved.\nYou can subscribe to notifications for any of your\n[sub-accounts](//support.google.com/merchants/answer/188487) or other [linked\naccounts](/shopping-content/guides/flagging/overview).\n\nThis guide provides examples of how to manage notifications for product status\nchanges. You can use these examples to manage notifications for other events by\nchanging the value of the `registeredEvent` field in your requests. For a full\nlist of the event types, see the [Merchant Notifications API\nreference](/merchant/api/reference/rest/notifications_v1/accounts.notificationsubscriptions#notificationeventtype).\n\nSubscribe\n---------\n\nTo receive notifications, you need a `callBackUri`. Your callback URI must\nmeet the following requirements:\n\n- Must be a publicly accessible HTTPS address with a valid SSL certificate, signed by a certificate authority.\n- Must accept HTTP `POST` requests with the `Content-Type`header and `application/json` value.\n- Must return one of the following response codes to acknowledge that the notification was received.\n - `102`\n - `200`\n - `201`\n - `202`\n - `204`\n\nYou can use the same callback URI for multiple subscriptions. We recommend using\na unique callback URI per [advanced\naccount](//support.google.com/merchants/answer/188487), per event type to\nminimize the load of push requests to a single URI.\n\nHere's a sample request to subscribe to notifications about product status\nchanges for a specific merchant account. \n\n POST https://merchantapi.googleapis.com/notifications/v1/accounts/\u003cvar translate=\"no\"\u003eMERCHANT_ID\u003c/var\u003e/notificationsubscriptions/\n\n {\n \"registeredEvent\": \"PRODUCT_STATUS_CHANGE\",\n \"targetAccount\": \"accounts/\u003cvar translate=\"no\"\u003eTARGETMERCHANT_ID\u003c/var\u003e\",\n \"callBackUri\": \"\u003cvar translate=\"no\"\u003ehttps://example.com\u003c/var\u003e\"\n }\n\nReplace the following:\n\n- \u003cvar translate=\"no\"\u003eMERCHANT_ID\u003c/var\u003e: The unique identifier of the account that should receive the notifications.\n- \u003cvar translate=\"no\"\u003eTARGETMERCHANT_ID\u003c/var\u003e: The unique identifier of the account about which you want to receive notifications.\n\nIf your Merchant Center account is a standalone account with no linked accounts,\nand you want to receive notifications for your own account, replace both these\nvariables with your account ID.\n\nSuccessful calls return a\n[`name`](/merchant/api/guides/compatibility/overview#name_replaces_id) for your\nsubscription, including a subscription ID: \n\n {\n \"name\":\"accounts/\u003cvar class=\"readonly\" translate=\"no\"\u003eMERCHANT_ID\u003c/var\u003e/notificationsubscriptions/subscriptionId\",\n \"registeredEvent\": \"PRODUCT_STATUS_CHANGE\",\n \"targetAccount\": \"accounts/\u003cvar class=\"readonly\" scope=\"targetMerchantId\" translate=\"no\"\u003eTARGETMERCHANT_ID\u003c/var\u003e\",\n \"callBackUri\": \"\u003cvar class=\"readonly\" scope=\"https://example.com\" translate=\"no\"\u003ehttps://example.com\u003c/var\u003e\"\n }\n\nYou can use this `name` to `GET` and `DELETE` individual subscriptions.\n\nYou can subscribe to notifications for product status changes for all of your\nlinked accounts by including `\"allManagedAccounts\": true`instead of a\n`targetAccount` in your request: \n\n POST https://merchantapi.googleapis.com/notifications/v1/accounts/\u003cvar class=\"readonly\" scope=\"merchantId\" translate=\"no\"\u003eMERCHANT_ID\u003c/var\u003e/notificationsubscriptions/\n\n {\n \"registeredEvent\": \"PRODUCT_STATUS_CHANGE\",\n \"allManagedAccounts\": true,\n \"callBackUri\": \"\u003cvar class=\"readonly\" scope=\"https://example.com\" translate=\"no\"\u003ehttps://example.com\u003c/var\u003e\"\n }\n\nTo update an existing subscription, use `PATCH` with an `update_mask` to specify\nthe fields you want to update, and the new values in the JSON body: \n\n PATCH https://merchantapi.googleapis.com/notifications/v1/accounts/\u003cvar class=\"readonly\" scope=\"merchantId\" translate=\"no\"\u003eMERCHANT_ID\u003c/var\u003e/notificationsubscriptions/\u003cvar translate=\"no\"\u003eSUBSCRIPTION_ID\u003c/var\u003e?update_mask=callBackUri\n\n {\n \"callBackUri\": \"\u003cvar translate=\"no\"\u003ehttps://my-own-personal-domain.com\u003c/var\u003e\"\n }\n\nDecode notifications\n--------------------\n\nAfter you create a subscription, you receive notifications to the specified\n`callBackUri` in the following format: \n\n {\"message\":{\"data\":\"{base64_encoded_string}\"}}\n\nThe notification data is encoded. You can decode the data to a readable text\nformat to use in your implementation. Here's a sample spring boot controller you\nmight use to process the encoded data: \n\n @RestController\n public class ExampleController {\n @RequestMapping(value = \"/push\",\n method = RequestMethod.POST,\n consumes = {\"application/json\"},\n produces = {\"text/plain\"})\n @ResponseStatus(HttpStatus.OK)\n public void doStuff(@RequestBody String message) {\n //wrapped message\n JSONObject jsonObject = new JSONObject(message);\n JSONObject jsonMessage = jsonObject.getJSONObject(\"message\");\n message = jsonMessage.getString(\"data\");\n byte[] decodedBytes = Base64.getDecoder().decode(message);\n String decodedMessage = new String(decodedBytes);\n // Implement your business logic here\n }\n }\n\nHere's an example of a `base64_encoded_string` that has been decoded: \n\n {\n \"account\": \"accounts/\u003cvar class=\"readonly\" scope=\"targetMerchantId\" translate=\"no\"\u003eTARGETMERCHANT_ID\u003c/var\u003e\",\n \"managingAccount\": \"accounts/\u003cvar class=\"readonly\" scope=\"merchantId\" translate=\"no\"\u003eMERCHANT_ID\u003c/var\u003e\",\n \"resourceType\": \"PRODUCT\",\n \"attribute\": \"STATUS\",\n \"changes\": [{\n \"oldValue\": \"approved\",\n \"newValue\": \"disapproved\",\n \"regionCode\": \"US\",\n \"reportingContext\": \"SHOPPING_ADS\"\n }, {\n \"oldValue\": \"approved\",\n \"newValue\": \"disapproved\",\n \"regionCode\": \"JP\",\n \"reportingContext\": \"SHOPPING_ADS\"\n },{\n \"oldValue\": \"approved\",\n \"newValue\": \"disapproved\",\n \"regionCode\": \"GE\",\n \"reportingContext\": \"SHOPPING_ADS\"\n }],\n \"resourceId\": \"ONLINE~en~US~1234\",\n \"resource\": \"accounts/\u003cvar class=\"readonly\" scope=\"targetMerchantId\" translate=\"no\"\u003eTARGETMERCHANT_ID\u003c/var\u003e/products/ONLINE~en~US~1234\",\n \"expirationTime\": \"2024-10-22T02:43:47.461464Z\",\n \"eventTime\": \"2024-03-21T02:43:47.461464Z\"\n }\n\nIf there's no `oldValue` field in the notification, a new product was\nadded to your account. If there's no `newValue` field, the product was deleted\nfrom your account.\n\nThe `expirationTime` field won't exist in case the product was deleted.\n\nThe `reportingContext` field supports only (`SHOPPING_ADS`, `LOCAL_INVENTORY_ADS`, `YOUTUBE_SHOPPING`, `YOUTUBE_CHECKOUT`, `YOUTUBE_AFFILIATE`) from the enum value [ReportingContextEnum](/merchant/api/reference/rest/Shared.Types/ReportingContextEnum).\n\nFor product status change event, `oldValue` and `newValue` fields will have one\nof these values : (`approved`, `pending`, `disapproved`, \\`\\`).\n\nThe `eventTime` field holds the creation time of the event itself, if you want\nto do message ordering you should rely on the value in that field and don't rely\non the order of receiving the messages.\n\nFollow the [ProductStatusChangeMessage](/merchant/api/reference/rest/Shared.Types/ProductStatusChangeMessage) format for\nmore details.\n\nTest your implementation\n------------------------\n\nHere's a sample notification you can use to test your callback URI and decoding: \n\n curl --header \"Content-Type: application/json\" --header \"Accept: text/plain\" --request POST --data '{\"message\":{\"data\":\n \"ewogICJhY2NvdW50IjogImFjY291bnRzLzEyMzQiLAogICJtYW5hZ2luZ0FjY291bnQiOiAiYWNjb3VudHMvNTY3OCIsCiAgInJlc291cmNlVHlwZSI6ICJQUk9EVUNUIiwKICAiYXR0cmlidXRlIjogIlNUQVRVUyIsCiAgImNoYW5nZXMiOiBbewogICAgIm9sZFZhbHVlIjogImFwcHJvdmVkIiwKICAgICJyZWdpb25Db2RlIjogIlVTIiwKICAgICJyZXBvcnRpbmdDb250ZXh0IjogIlNIT1BQSU5HX0FEUyIKICB9XSwKICAicmVzb3VyY2VJZCI6ICJPTkxJTkV+ZW5+VVN+MDAwMDAwMDAwMDAwIiwKICAicmVzb3VyY2UiOiAiYWNjb3VudHMvMTIzNC9wcm9kdWN0cy9PTkxJTkV+ZW5+VVN+MDAwMDAwMDAwMDAwIiwKICAiZXhwaXJhdGlvblRpbWUiOiAiMjAyNC0xMC0yMlQwMjo0Mzo0Ny40NjE0NjRaIiwKICAiZXZlbnRUaW1lIjogIjIwMjQtMDMtMjFUMDI6NDM6NDcuNDYxNDY0WiIKfQ==\"}}' https://{callBackUri}\n\nIn response to this call, your callback URI should return a [successful response\ncode](#subscribe). The decoded message should have the following value: \n\n {\n \"account\": \"accounts/1234\",\n \"managingAccount\": \"accounts/5678\",\n \"resourceType\": \"PRODUCT\",\n \"attribute\": \"STATUS\",\n \"changes\": [{\n \"oldValue\": \"approved\",\n \"regionCode\": \"US\",\n \"reportingContext\": \"SHOPPING_ADS\"\n }],\n \"resourceId\": \"ONLINE~en~US~000000000000\",\n \"resource\": \"accounts/1234/products/ONLINE~en~US~000000000000\",\n \"expirationTime\": \"2024-10-22T02:43:47.461464Z\",\n \"eventTime\": \"2024-03-21T02:43:47.461464Z\"\n }"]]