Restore Google Play Subscriptions
POST https://api.botsi.com/v2/purchases/play-store/restoreGrant a Profile the access its Google Play subscriptions carry. It's the Google Play counterpart of Restore Apple Store Purchases. Use it behind a "Restore Purchases" button, after a reinstall, or when the user moves to a new device.
This route accepts $BOTSI_SECRET_KEY or $BOTSI_PUBLIC_KEY in the Authorization header, with no Bearer prefix. The sample sends the secret key. From inside the app, send the public key. See Authentication.
What to send#
Send every subscription that Play Billing's queryPurchasesAsync(ProductType.SUBS) returns for the signed-in account, one entry per purchase.
Request body#
# Authorization: $BOTSI_SECRET_KEY or $BOTSI_PUBLIC_KEY
curl -X POST "https://api.botsi.com/v2/purchases/play-store/restore" \
-H "Authorization: $BOTSI_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"profileId": "fff3c120-0ca8-480f-9b19-3955a5428e39",
"purchases": [
{
"productId": "premium_annual",
"purchaseToken": "algojlnkodhhjceoicbpjngh.AO-J1Owvcga8j2uUoKEpn5AnvpSFr8dxEFm0c6qk5"
}
]
}'What a restore does#
Botsi processes the purchases one at a time, in the order you send them.
Tokens Google doesn't recognize are skipped, not failed. That covers tokens Google doesn't know (a 404 from Google) and tokens it no longer reports, such as a subscription that expired long ago (a 410). The restore fails only when every token is skipped.
Each recognized purchase is handled the same way as an Apple restore:
Response#
A successful restore returns 200 with the Profile after the restore. It's the same shape Validate Google Play Store Purchase returns: the Profile object from Get a Profile, without custom.
{
"ok": true,
"data": {
"profileId": "fff3c120-0ca8-480f-9b19-3955a5428e39",
"appUserId": "user-123",
"state": "subscribed",
"totalRevenueUsd": 49.99,
"accessLevels": {
"premium": {
"isActive": true,
"store": "play_store",
"sourceProductId": "premium_annual",
"sourceBasePlanId": "annual-base",
"expiresAt": "2027-10-07",
"willRenew": true
}
},
"subscriptions": {
"premium_annual": {
"isActive": true,
"store": "play_store",
"sourceProductId": "premium_annual",
"sourceBasePlanId": "annual-base",
"expiresAt": "2027-10-07",
"willRenew": true
}
},
"nonSubscriptions": {}
}
}The entitlements above are trimmed to a few fields. The response carries every field listed under Entitlement fields.
Errors#
For example, a request where every token is skipped returns:
{
"error": "Google Play has no subscription for any of the purchase tokens.",
"code": "nothing_to_restore"
}