IAP Gateway (Copub)
IAP Gateway is a server-to-server API for co-published (copub) games — games that run their own game server and their own client, with no Alogame SDK involved anywhere in the purchase flow. Alogame's only role is to verify the receipt with Apple/Google Play on request; your game server decides when and how to grant items to the player.
The standard flow: the player purchases in-game (your own client, driving StoreKit/Google Play Billing directly) → the client sends the result to your game backend → your game backend calls Alogame's IAP Gateway to verify the transaction → Alogame returns the verified result to your game backend, which then grants the item.
Two platform guides build on this page:
Before you start
Contact Alogame to receive:
client_idandclient_secret— used by your game server to authenticate with Alogame IAP Gateway
client_secret is issued only once. Save it securely immediately — it cannot be retrieved again.
Base URL
Every endpoint on this page and the platform guides (/iap/gateway/verify, /iap/gateway/lookup-receipt) is relative to one of these two base URLs — never mix them:
| Environment | Base URL |
|---|---|
| Development / Sandbox | https://api-sdk.dev.alogame.vn |
| Production | https://api-sdk.alogame.vn |
e.g. the verify endpoint is POST {base_url}/iap/gateway/verify.
How it works
- App retrieves the receipt — platform-specific. See iOS Step 1 (StoreKit JWS/base64) or Android Step 1 (Billing Library
purchaseToken). - App sends the receipt to your own game server — an internal API you design yourself; not part of this contract.
- Your game server calls Alogame's
/iap/gateway/verify— identical on both platforms except the request body. Covered below.
Authentication
Endpoint
POST {base_url}/iap/gateway/verify
See Base URL for the {base_url} value per environment.
Request signing
Every request must include three authentication headers signed with HMAC-SHA256:
X-Client-ID: <client_id>
X-Timestamp: <unix_timestamp_seconds>
X-Signature: <hmac_hex>
Signature algorithm:
body_hash = SHA256(raw_request_body_bytes) # hex string
message = "{client_id}.{timestamp}.{body_hash}"
signature = HMAC-SHA256(client_secret, message) # hex string
Replay protection: Alogame rejects requests where |server_time − X-Timestamp| > 300 seconds (5-minute window).
The request body itself differs by platform (Android requires an extra package field) — see the full signed request example on the iOS or Android page.
Response & error handling
Both platforms return the same envelope shape. receipt_info fields differ by platform — see iOS or Android.
{ "success": true, "transaction_id": "...", "product_id": "...", "receipt_info": { "...": "..." } }
{ "success": false, "error": "ERROR_CODE", "message": "human-readable detail" }
Errors common to both platforms:
| Case | HTTP | error |
|---|---|---|
| Verification successful | 200 | — |
| Receipt already verified | 409 | DUPLICATE_TRANSACTION |
product_id in request doesn't match the receipt | 422 | PRODUCT_MISMATCH |
| Receipt rejected by Apple/Google | 422 | VERIFICATION_FAILED |
| Apple/Google server unreachable / unexpected error | 502 | VERIFIER_ERROR |
| Missing required fields | 400 | MISSING_FIELDS |
os_id value not 1 or 2 | 400 | INVALID_OS_ID |
| Invalid credentials or signature | 401 | UNAUTHORIZED |
iOS has one additional case — sandbox/production mismatch (412 ENVIRONMENT_MISMATCH) — see the iOS error table.
success: true→ grant the item.4xx→ request was wrong (bad fields, invalidos_id, auth failure). Fix the request; do not retry blindly.409 DUPLICATE_TRANSACTION→ Alogame already verified this receipt (common on retry after crash). Check if the item was already granted; do not re-grant.422 PRODUCT_MISMATCH/422 VERIFICATION_FAILED→ do not grant the item.5xx→ upstream or server error. Safe to retry with exponential back-off.
Looking up a receipt directly (support tool)
Both platforms expose POST /iap/gateway/lookup-receipt — a read-only tool for support/CS to re-check a purchase without going through delivery logic again. Same HMAC auth as /verify. The request contract differs by platform:
- iOS — Apple supports looking up a bare, human-readable Order ID (what a player sees in Report a Problem or an order email). See the iOS lookup-receipt contract.
- Android — Google Play has no equivalent lookup-by-order-ID API; the request needs the same
product_id+package+purchaseTokenthat/verifyitself needs. See the Android lookup-receipt contract.
Refunds
Alogame can notify your server when Apple refunds a purchase — see the iOS refund callback. There is currently no equivalent callback for Android; reconcile Android refunds against Google Play's own Voided Purchases reports instead.
Integration checklist (shared)
- Received
client_idandclient_secretfrom Alogame — stored securely server-side - Game server signs every request with HMAC-SHA256 (see Authentication)
- Game server checks the
successfield — not just HTTP status — before granting an item - Game server treats
409 DUPLICATE_TRANSACTIONas "already verified" — checks local state, does not re-grant - Game server treats
422 VERIFICATION_FAILEDas "do not grant" - Game server retries with exponential back-off on
5xx(VERIFIER_ERROR) - Game server stores
transaction_idfor idempotent delivery — prevents double-granting
Platform-specific checklist items (receipt type, package field, refund callback, etc.) are on the iOS and Android pages.