> For the complete documentation index, see [llms.txt](https://apc-pay.gitbook.io/apc-pay-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://apc-pay.gitbook.io/apc-pay-docs/apc-pay/production-checklist.md).

# Production Checklist

Updated 2026-10-14

Complete this checklist before enabling live payouts.

> ❇️
>
> ### Confirm the environment
>
> The supplied materials do not document a sandbox. Confirm the base URL, test procedure, funding process, supported currencies, and operational support channel with APC Pay before making a payout.

## Portal and credentials

* [ ] The merchant number and app ID are stored in server-side configuration.
* [ ] The merchant public-key fingerprint matches the deployed private key.
* [ ] The merchant private key is stored in a secrets manager or comparably protected location.
* [ ] The private key is never present in browser, mobile, or other client-side code.
* [ ] The platform public key is pinned and loaded from a trusted source.
* [ ] The platform public-key fingerprint matches the portal.
* [ ] Every production server public egress IP is whitelisted.
* [ ] Every required fiat currency is enabled for the app.
* [ ] The production API base URL is confirmed with APC Pay.

## Request construction

* [ ] Server time is synchronized.
* [ ] `reqTime` uses UTC RFC 3339 format with milliseconds.
* [ ] Every request uses a cryptographically random, unique nonce.
* [ ] Canonical fields are ASCII-sorted and empty values are omitted.
* [ ] Values and the backend path use the documented RFC 3986 percent encoding.
* [ ] The signed path excludes the public `/v1` prefix unless APC Pay confirms otherwise.
* [ ] Requests use SHA256withRSA, PKCS#1 v1.5 padding, and standard Base64.
* [ ] Amounts are decimal strings, not binary floating-point values.
* [ ] Amount precision exactly matches `/currency/query`.

## Response verification

* [ ] Every successful non-empty response `data` object has a valid platform signature.
* [ ] Every response nonce matches the originating request nonce.
* [ ] Returned order identifiers match the request or stored order.
* [ ] Amount and currency match stored business data.
* [ ] Empty or unsigned success data is rejected.
* [ ] `requestId` is retained for support investigations.

## Payout and retry safety

* [ ] `mchOrderNo` has a database unique constraint.
* [ ] A genuinely new payout always receives a new `mchOrderNo`.
* [ ] A retry preserves the original order number and business parameters.
* [ ] Every retry uses a fresh request time, nonce, and signature.
* [ ] Timeouts, transport errors, and `4001` trigger a query before any create retry.
* [ ] The initial `payoutOrderId`, status, rates, fees, and USDT cost are stored.
* [ ] `ACCEPTED` and `PROCESSING` never trigger an automatic replacement payout.

## Callback safety

* [ ] The callback URL uses HTTPS and is publicly reachable.
* [ ] Request bodies are parsed with a strict size limit.
* [ ] Callback signatures are verified before any state change.
* [ ] Merchant number, app ID, and `PAYOUT_ORDER` notification type are validated.
* [ ] Only `SUCCESS` and `FAILED` are accepted as callback states.
* [ ] Order IDs, amount, and currency match stored data.
* [ ] `notifyId` has a durable database unique constraint.
* [ ] Deduplication and final-state application occur in one transaction.
* [ ] Duplicate valid callbacks return HTTP `200` with plain-text `success`.
* [ ] Invalid or mismatched callbacks never change payout state.

## Reconciliation and operations

* [ ] Missed or delayed final callbacks are reconciled with `/payout/query`.
* [ ] Query and callback paths share idempotent state-transition logic.
* [ ] Non-final orders are monitored and reconciled.
* [ ] Repeated signature failures and unmatched callbacks generate alerts.
* [ ] Support logs include `requestId`, order identifiers, and a safe correlation ID.
* [ ] Logs exclude keys, full QR payloads, payee data, and replayable signed bodies.
* [ ] Operators know how to resend eligible final callbacks from the portal's **Payouts** page.
* [ ] The operational team knows the escalation and support process for stuck orders.

## Final go-live review

1. Run `POST /currency/query` and confirm the live configuration.
2. Run `POST /balance/query` and confirm available USDT.
3. Confirm the callback endpoint is deployed, reachable, and writing durable deduplication records.
4. Confirm monitoring, alerts, and reconciliation jobs are active.
5. Review one payout's destination, amount, currency, callback URL, and merchant order number.
6. Create a payout only after APC Pay confirms that you are authorized to use the target environment.
7. Track it through `ACCEPTED` or `PROCESSING` to a verified `SUCCESS` or `FAILED` result.

## Documentation map

* [Overview](broken://pages/46c1e051475cc04fb947a804c29f28aeca06ef6d)
* [Quick Start](broken://pages/22c43dd09ce841ec9d903208e876a09fee1a58fe)
* [Native API Integration](broken://pages/7b501391f08adae344986212af9d57286f6b569e)
* [Balance and Currency](broken://pages/c374e00afa6fb109644d34b6d82fbe7b0d8b38c7)
* [Authentication and Request Signing](broken://pages/09fdb741f99cf1deb38cf1b90b063767f12807df)
* [Create a Payout](broken://pages/85bb23f0c564b16167e4d27ad120123daf5f90b3)
* [Query a Payout](broken://pages/d322bd86cc349f7eef7630c43fcea7a59ed35e89)
* [Payout Webhooks](broken://pages/3ddd4c5270f1825eb62c85633eddb69b50a33b8c)
* [Payout Statuses and Errors](broken://pages/1701152330ec298b264aa8660498f37921c96df6)
