Server Webhook
One endpoint per application.
What it does
After every successful validation, we send the store's response to an endpoint of your choice. Use it to keep your own copy of what users own, or to feed your analytics.
Set the address in App Setup. The first time you save one, your endpoint has to answer with status 200 to prove it exists. A private header key is generated at the same time.
Only valid receipts are forwarded: a new purchase or a subscription renewal, meaning a validation that increased your transaction count. Subscription status changes such as paused or expired are forwarded as well.
Delivery and retries
If your server does not answer, the message is retried up to 6 times after the first attempt:
| Attempt | Sent after |
|---|---|
| 1st retry | 10 minutes |
| 2nd retry | 60 minutes |
| 3rd retry | 4 hours |
| 4th to 6th retry | 12 hours apart |
After the last failed attempt the message is dropped. Because a retry can arrive more than a day late, check the timestamp field before acting on it.
Header
| Field | Value |
|---|---|
Content-Type | application/json |
X-App-Id | Your application identifier. |
X-Auth-Key | The generated private key. Compare it on your server to be sure the request came from us. Contact Support if it was exposed. |
Content
A string in JSON format.
| Field | Value |
|---|---|
store | The originating store. GooglePlay, AppleAppStore or PayPal |
user | The user identifier, either the one your app sent or the one the server generated. Missing on store server notifications, which carry no user. |
transaction | The store's unique transaction identifier. |
data (object) | The receipt data of the purchase. Same shape as the validation response. |
timestamp | UNIX timestamp of when the message was created, not when it arrived. |
Treat the endpoint as public. Anyone can post to it, so reject anything without a matching X-App-Id and X-Auth-Key before you read the body.
Example
- PHP
/*
PHP Example for processing webhook data on your server
*/
//Read App ID from Request and compare
$appId = $_SERVER['HTTP_X_APP_ID'];
if($appId === null || $appId !== '<YOUR-APP-ID>')
{
exit;
}
//Read API Key from Request and compare
$appKey = $_SERVER['HTTP_X_AUTH_KEY'];
if($appKey === null || $appKey !== '<YOUR-API-KEY>')
{
exit;
}
//Receive content from incoming POST request
$body = json_decode(file_get_contents('php://input'), true);
//Read User ID from parsed content
$user = $body->user;
//Read Product ID from parsed content
$product = $body->data->productId;
//Your implementation
//e.g. connect to local database and award product to user
$this->grantToUser($user, $product)