Errors and recovery
An error response includes an error object. Use code for application decisions, message for context, and request_id when contacting NextAppMarket.
{
"error": {
"code": "VERSION_CONFLICT",
"message": "The order changed. Retrieve it before retrying.",
"request_id": "req_demo_1042",
"retryable": false,
"current_version": 5,
"operation_id": null,
"status_path": null,
"details": []
}
}
Do not depend on the exact wording of message. retryable does not authorize changing the business command or idempotency key.
Select a recovery path
| Code | What to check or do |
|---|---|
VALIDATION_FAILED | Correct the fields identified in details. |
UNAUTHENTICATED | Check the credential target, secret, expiry, revocation, and calling source. |
SCOPE_DENIED | Check the required scope and application authorization. |
RESOURCE_NOT_FOUND | Check the ID, API target, and authorized application. |
VERSION_CONFLICT | Retrieve the current resource and reassess the requested change. |
IDEMPOTENCY_CONFLICT | Compare the retry against the saved original command. |
REQUEST_IN_PROGRESS | Follow the existing operation or resource; wait before retrying. |
REFUND_WINDOW_EXPIRED | Review the recorded deadline and use the applicable support workflow. |
REFUND_CAPACITY_EXCEEDED | Recheck successful and pending refunds on the order. |
FUNDS_UNAVAILABLE | Review funding and the manual-review workflow. |
POLICY_NOT_ACCEPTED | Review and complete the required Console policy decision. |
PRODUCTION_NOT_READY, CAPABILITY_UNAVAILABLE, CONFIGURATION_INCOMPLETE | Resolve application activation or service configuration with NextAppMarket. |
AUTHORITATIVE_UNAVAILABLE | The contract's authoritative service is unavailable; preserve the original command and retry later. |
CURSOR_EXPIRED | Restart the list query and reconcile records by ID and version. |
RATE_LIMITED | Honor Retry-After and reduce concurrency. |
STATE_CONFLICT | Read current state before deciding on another action. |
The deployed Business gateway can also report AUTHORITY_UNAVAILABLE when its authorization authority cannot be reached. Treat this as an availability failure, not permission to bypass authorization.
The customer returned, but the order is still processing
Query the Payment API. A browser return or SDK callback only tells your client to check the order. Keep a visible pending state while the outcome is unresolved. Deliver after the authoritative result is paid.
A refund request was accepted, but the customer has not received it
Read both review_status and execution_status. Approval and provider acceptance are intermediate states. If execution is unknown, continue reconciling the existing refund. If it is succeeded, use the recorded provider result and customer support process to investigate arrival.
A webhook appears twice or arrives late
Use persistent deduplication by endpoint/application binding and event_id, then guard resource updates with resource_version. If the same event ID arrives with different body bytes, stop normal processing and investigate. See Webhook signatures.
Checkout could not be created
- Read the HTTP status, structured
error.code, andrequest_id. Keep the request ID with your business attempt. - For
UNAUTHENTICATED, confirm that the backend calledhttps://pay.appconnect.cn/payment/v1with the assigned Payment API key. A customer login token is not a Payment API credential. - For
SCOPE_DENIED, check the required scope and that the credential can access this platformapp_id. Do not substitute a WeChat/Alipay provider AppID for the platform ID. - For
VALIDATION_FAILED, follow the field paths indetails. Check integer minor units,CNY, the supportedpayment_entry, and its requiredscenevalues. Calculate the price on your backend. - For
CAPABILITY_UNAVAILABLE,CONFIGURATION_INCOMPLETE, orPRODUCTION_NOT_READY, resolve application activation with NextAppMarket. A guide's existence does not enable the provider adapter. - If the connection failed before you received a definitive response, preserve the command body and idempotency key. Retry that exact command or follow its known operation/order; do not create a replacement charge.
Checkout returned an order but no launch instructions
A null invocation means the session is not ready to launch. Save the returned order and session identifiers, then retrieve the original session. Show Preparing payment and provide an order-status action. Do not render a blank QR code or call an SDK with an empty string.
If the invocation has expired, query the order first. Expiry blocks a new launch; it does not establish that an earlier attempt failed. Close or resolve the unpaid attempt through the documented workflow before deliberately creating a replacement.
Repeated taps or retries create duplicate orders
Disable the Pay control while a checkout request or native launch is active. On the backend, enforce uniqueness for the business purchase and reuse its unresolved payment attempt. Persist the exact serialized request body and idempotency key before making the platform call. A process restart must reload them.
IDEMPOTENCY_CONFLICT means the request no longer matches the saved command identity. Compare route, application, key, and raw body. JSON with the same meaning can have different bytes. Do not regenerate timestamps, reorder fields, or change the amount on a retry. See Idempotency and safe retries.
The SDK or browser cannot open payment
Use the troubleshooting table for the selected entry:
| Integration | Start here |
|---|---|
| Alipay Android/iOS | Installation, signatures, schemes, Universal Links, SDK result codes |
| WeChat Android/iOS | AppID, signing certificate, callback Activity, iOS return routing |
| WeChat mobile web | Browser, client IP, referring domain, expiry |
| WeChat QR | URI rendering, scan quality, expired codes, cross-device confirmation |
| Alipay mobile web | Redirect/form handling, WebViews, return navigation |
| Alipay desktop web | Cashier links, pop-up blockers, return/status pages |
| Alipay QR | Cashier URLs encoded as QR, scanner behavior, order recovery |
| Huawei IAP | Environment, product mapping, owned purchases, evidence and consumption |
A provider client error is not a platform order state. Query the saved order before offering another payment.
Payment succeeded but the customer did not receive the product
Check the layers in this order:
- Retrieve the saved platform order and verify its application, business reference, amount, currency, and
paidstate. An SDK success screen alone is insufficient. - Find your durable fulfillment record for that purchase. If it is missing, enqueue the same idempotent delivery task; do not charge again.
- If fulfillment is already recorded, inspect the entitlement/credit ledger and the app's refresh path. The UI may be showing stale account state.
- For Huawei, check channel confirmation after delivery and submit any required fulfillment attestation. A provider-confirmation problem must not cause the same credits to be granted again.
Keep Payment received. Preparing your purchase distinct from an unpaid or failed state. Your backend reconciliation job must recover delivery even when the app never opens again.
A refund fails or remains unresolved
| Result | Next action |
|---|---|
VERSION_CONFLICT | Retrieve the order and recalculate remaining refundable principal. After the original command has definitively failed, persist a revised command with a new key if still appropriate. |
REFUND_CAPACITY_EXCEEDED | Include pending refunds in the reserved amount. Do not request the full original charge again after a partial refund. |
REFUND_WINDOW_EXPIRED | Check the recorded deadline and escalate using the applicable support workflow; changing the client clock or request timestamp cannot reopen it. |
FUNDS_UNAVAILABLE | Review the platform's funding/manual-review workflow. Keep the refund record instead of submitting competing refund requests. |
| Review is pending or rejected | Show the actual review state and permitted next action. Review acceptance is separate from provider execution. |
| Execution is pending or unknown | Poll the same refund and reconcile webhooks. A second request may return money twice. |
| Execution succeeded, customer reports no arrival | Preserve the refund/provider reference and timestamps, then use the support workflow. Do not promise a fixed bank-arrival time that the response does not guarantee. |
Follow the complete refund walkthrough for request examples, status handling, and entitlement decisions.
Webhook delivery is missing or rejected
Verify that the endpoint is public HTTPS, activation verification completed, the configured secret/key ID is current, and your framework preserves the raw request bytes for signature checks. Do not deserialize and reserialize JSON before verification. Check timestamp tolerance and clock synchronization.
Persist a valid event before acknowledging it, and process delivery asynchronously. Return a non-success response when durable receipt fails so the sender can retry. Use the supplied signature verifier and fixture to distinguish signature/configuration errors from your business handler. Order queries and periodic reconciliation remain the recovery path when webhook delivery is delayed.
Prepare a support report
Include the application ID, API target, endpoint, UTC timestamp, request ID, platform order/refund/operation ID, error code, and the last confirmed business state. Redact credentials and purchase evidence. Describe whether a retry used the original command identity.