You can use the Merchant Notifications API to get push notifications for changes to account data. For example, if you subscribe to product status change notifications, you can be notified in real time when a product is disapproved. You can subscribe to notifications for any of your sub-accounts or other linked accounts.
This guide provides examples of how to manage notifications for product status
changes. You can use these examples to manage notifications for other events by
changing the value of the registeredEvent
field in your requests. For a full
list of the event types, see the Merchant Notifications API
reference.
Subscribe
To receive notifications, you need a callBackUri
. Your callback URI must
meet the following requirements:
- Must be a publicly accessible HTTPS address with a valid SSL certificate, signed by a certificate authority.
- Must accept HTTP
POST
requests with theContent-Type
header andapplication/json
value. - Must return one of the following response codes to acknowledge that the
notification was received.
102
200
201
202
204
You can use the same callback URI for multiple subscriptions. We recommend using a unique callback URI per advanced account, per event type to minimize the load of push requests to a single URI.
Here's a sample request to subscribe to notifications for product status changes
for a specific merchant account. Use the merchant ID of the account that should
receive the notifications as the merchantId
in the request URL, and the
merchant ID of the account to receive notifications for as the
targetMerchantId
in the request body. If your account is a standalone
account with no linked accounts, and you want to receive notifications for your
own account, use your own merchant ID in both places.
POST https://merchantapi.googleapis.com/notifications/v1beta/accounts/merchantId/notificationsubscriptions/
{
"registeredEvent": "PRODUCT_STATUS_CHANGE",
"targetAccount": "accounts/targetMerchantId",
"callBackUri": "https://example.com"
}
Successful calls return a
name
for your
subscription, including a subscription ID:
{
"name":"accounts/merchantId/notificationsubscriptions/subscriptionId",
"registeredEvent": "PRODUCT_STATUS_CHANGE",
"targetAccount": "accounts/targetMerchantId",
"callBackUri": "https://example.com"
}
You can use this name
to GET
and DELETE
individual subscriptions.
You can subscribe to notifications for product status changes for all of your
linked accounts by including "allManagedAccounts": true
instead of a
targetAccount
in your request:
POST https://merchantapi.googleapis.com/notifications/v1beta/accounts/merchantId/notificationsubscriptions/
{
"registeredEvent": "PRODUCT_STATUS_CHANGE",
"allManagedAccounts": true,
"callBackUri": "https://example.com"
}
To update an existing subscription, use PATCH
with an update_mask
to specify
the fields you want to update, and the new values in the JSON body:
PATCH /notifications/v1beta/accounts/merchantId/notificationsubscriptions/subscriptionId?update_mask=callBackUri
{
"callBackUri": "https://my-own-personal-domain.com"
}
Decode notifications
After you create a subscription, you receive notifications to the specified
callBackUri
in the following format:
{"message":{"data":"{base64_encoded_string}"}}
The notification data is encoded. You can decode the data to a readable text format to use in your implementation. Here's a sample spring boot controller you might use to process the encoded data:
@RestController
public class ExampleController {
@RequestMapping(value = "/push",
method = RequestMethod.POST,
consumes = {"application/json"},
produces = {"text/plain"})
@ResponseStatus(HttpStatus.OK)
public void doStuff(@RequestBody String message) {
//wrapped message
JSONObject jsonObject = new JSONObject(message);
JSONObject jsonMessage = jsonObject.getJSONObject("message");
message = jsonMessage.getString("data");
byte[] decodedBytes = Base64.getDecoder().decode(message);
String decodedMessage = new String(decodedBytes);
// Implement your business logic here
}
}
Here's an example of a base64_encoded_string
that has been decoded:
{
"account": "accounts/targetMerchantId",
"managing_account": "accounts/merchantId",
"resource_type": "PRODUCT",
"attribute": "STATUS",
"changes": [{
"old_value": "eligible",
"new_value": "disapproved",
"region_code": "US",
"reporting_context": "SHOPPING_ADS"
}, {
"old_value": "eligible",
"new_value": "disapproved",
"region_code": "JP",
"reporting_context": "SHOPPING_ADS"
},{
"old_value": "eligible",
"new_value": "disapproved",
"region_code": "GE",
"reporting_context": "SHOPPING_ADS"
}],
"resource_id": "ONLINE~en~US~1234",
"resource": "accounts/targetMerchantId/products/ONLINE~en~US~1234"
}
If there's no old_value
field in the notification, a new product was
added to your account. If there's no new_value
field, the product was deleted
from your account.
The reporting_context
field supports only (SHOPPING_ADS
, LOCAL_INVENTORY_ADS
, YOUTUBE_SHOPPING
) from the enum value ReportingContextEnum.
Test your implementation
Here's a sample notification you can use to test your callback URI and decoding:
curl --header "Content-Type: application/json" --header "Accept: text/plain" --request POST --data '{"message":{"data":
"ewogICJhY2NvdW50IjogImFjY291bnRzLzEyMzQiLAogICJtYW5hZ2luZ19hY2NvdW50IjogImFjY291bnRzLzU2NzgiLAogICJyZXNvdXJjZV90eXBlIjogIlBST0RVQ1QiLAogICJhdHRyaWJ1dGUiOiAiU1RBVFVTIiwKICAiY2hhbmdlcyI6IFt7CiAgICAib2xkX3ZhbHVlIjogImVsaWdpYmxlIiwKICAgICJyZWdpb25fY29kZSI6ICJVUyIsCiAgICAicmVwb3J0aW5nX2NvbnRleHQiOiAiU0hPUFBJTkdfQURTIgogIH1dLAogICJyZXNvdXJjZV9pZCI6ICJPTkxJTkV+ZW5+VVN+MDAwMDAwMDAwMDAwIiwKICAicmVzb3VyY2UiOiAiYWNjb3VudHMvMTIzNC9wcm9kdWN0cy9PTkxJTkV+ZW5+VVN+MDAwMDAwMDAwMDAwIgp9"}}' https://{callBackUri}
In response to this call, your callback URI should return a successful response code. The decoded message should have the following value:
{
"account": "accounts/1234",
"managing_account": "accounts/5678",
"resource_type": "PRODUCT",
"attribute": "STATUS",
"changes": [{
"old_value": "eligible",
"region_code": "US",
"reporting_context": "SHOPPING_ADS"
}],
"resource_id": "ONLINE~en~US~000000000000",
"resource": "accounts/1234/products/ONLINE~en~US~000000000000"
}