Server Verification and Entitlements
This guide defines the authoritative order state, the retry strategy, and the entitlement contract that turn a completed payment into usable access.
AppInChina Payments processes the payment transaction. Your backend makes the authoritative entitlement decision after checking the transaction state through the documented AppInChina interface. The payment result returned to the app is useful for user experience, but it is not, by itself, proof that access should be granted.
The app must grant or refresh access only after its backend has verified the order's authoritative status and applied the client's entitlement rules. Neither a successful wallet handoff nor arrival at an Android result/callback Activity proves that payment succeeded. Your backend must verify the order status through the documented AppInChina interface and apply your entitlement rules idempotently; the app should then refresh access from your backend.
Related docs
- Scope and ownership: Start Here: integrate AppInChina IAP
- Identity mapping: Login → Payments integration (customer identity)
- Endpoint contract: Payments API Reference
- History and refunds: Purchase History & Refund Workflows
- Android integration: Payments SDK Integration Guide for Android
1. The three states you must observe independently
A transaction can be paid while the app still shows an error or fails to grant access. Do not collapse these three states into one:
| State | Where it lives | How you observe it |
|---|---|---|
| Payment processing | WeChat Pay / Alipay + AppInChina | The wallet returns control to your app; an order exists in the AppInChina backend. |
| Backend verification | AppInChina order-status interface | Your backend queries /detail.json (or the SDK query) and reads paymentStatus == PAID. |
| Entitlement / UI state | Your backend + your app | Your backend records the grant; your app refreshes and unlocks the feature. |
All three must pass. A PAID transaction with no entitlement grant is an incomplete integration, not a completed payment.
2. The single "first purchase" recipe
Follow this recipe end to end. Every payment integration must be able to complete all eight steps before it is considered done.
| Step | Owner | Required behavior | Pass condition |
|---|---|---|---|
| 1. Authenticate user | Client app / backend | Only offer payment for a known app account; generate or load a stable internal user ID. | A stable customerIdentity is available before initiation. |
| 2. Create client order context | Client backend | Create a unique client business/order reference (bizNo) and record product, user, intended entitlement, and pending state. | The reference is unique and retry-safe. |
| 3. Start payment | Client app | Call the SDK/API with the required parameters, including the result/callback class where applicable. | Wallet flow opens or produces a diagnosable pre-payment failure. |
| 4. Receive return / callback | Client app | Return safely to the app and trigger a backend refresh/verification request. Do not grant durable access solely from a UI success signal. | App does not crash; verification begins. |
| 5. Verify order state | Client backend | Use the canonical documented query/verification endpoint; handle retryable states and failures. | Authoritative state is obtained and stored. |
| 6. Grant entitlement | Client backend | Use an idempotent state transition keyed by the transaction / bizNo; store audit fields required for support. | Correct access is active exactly once. |
| 7. Refresh app access | Client app | Fetch current entitlement state from the client backend and update the UI. | The product is usable without manual restart; relaunch also reflects access. |
| 8. Preserve history | Client backend / UI | Expose relevant completed orders/purchases and their client references as needed by product support. | A support case can map an app user to bizNo / order records. |
Treat the AppInChina backend's verified order state and your backend's entitlement record as authoritative. The app's immediate return from the wallet is not a substitute for verification. Conversely, a PAID transaction is not a substitute for granting access: your backend must complete the entitlement update and the app must refresh from that state.
For a fully worked example (login → CreateOrder → verify → fulfill → renew → restore), see Capabilities and Limitations → fixed-term subscription flow.
3. Idempotency, retries, and lifecycle behavior
3.1 Idempotency
Document and implement the unique key that prevents duplicate grants — normally the bizNo, or the AppInChina order identifier where returned. Your backend should be able to repeat the same verification request and receive the same entitlement result without extending or duplicating access.
- Key the entitlement transition on
bizNo(or order id), not on "the user tapped pay again". - A repeated verification for an already-fulfilled order must be a no-op, not a second grant.
3.2 Pending or interrupted flows
Payments can be interrupted (the user backgrounds the wallet, loses network, or returns much later). Document:
- What the app shows while verification is pending (a neutral "confirming your purchase" state, not "success").
- How the backend retries a status query for a
PENDINGorder. - How a user can refresh purchases after returning later.
Do not promise a specific polling frequency in client-facing docs unless Engineering has defined and supports one. Describe the retry behavior, not a guaranteed interval.
3.3 Restore points
Require an entitlement refresh after each of these events, where the product supports them:
- Payment return
- App relaunch
- Login
- Account switching
- Reinstall / restore
The app should retrieve access from your backend, not from a one-time device-local success state. See also Purchase Restore and SMS Authentication.
4. Minimum support record
State the minimum data your backend should retain for every payment attempt, so a support case is diagnosable:
- Internal user ID
- Product / SKU
bizNo- AppInChina order identifier (if returned)
- Payment method
- Timestamps
- Latest verified state
- Entitlement action taken
- Error reason (if any)
Never retain wallet credentials, full payment-card data, wallet authentication codes, or other secrets. Keep the support record to non-sensitive correlation fields.