Skip to main content

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 authoritative payment-completion rule

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.

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:

StateWhere it livesHow you observe it
Payment processingWeChat Pay / Alipay + AppInChinaThe wallet returns control to your app; an order exists in the AppInChina backend.
Backend verificationAppInChina order-status interfaceYour backend queries /detail.json (or the SDK query) and reads paymentStatus == PAID.
Entitlement / UI stateYour backend + your appYour 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.

StepOwnerRequired behaviorPass condition
1. Authenticate userClient app / backendOnly 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 contextClient backendCreate 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 paymentClient appCall 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 / callbackClient appReturn 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 stateClient backendUse the canonical documented query/verification endpoint; handle retryable states and failures.Authoritative state is obtained and stored.
6. Grant entitlementClient backendUse an idempotent state transition keyed by the transaction / bizNo; store audit fields required for support.Correct access is active exactly once.
7. Refresh app accessClient appFetch current entitlement state from the client backend and update the UI.The product is usable without manual restart; relaunch also reflects access.
8. Preserve historyClient backend / UIExpose 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.
Authoritative state

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 PENDING order.
  • How a user can refresh purchases after returning later.
note

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)
Do not store

Never retain wallet credentials, full payment-card data, wallet authentication codes, or other secrets. Keep the support record to non-sensitive correlation fields.