Guide · 10 / 10
Going live
The production readiness checklist.
Before you switch traffic from sandbox to production, work through this checklist.
Credentials & environment
- Use production keys against the production base URL. Swap
https://sandbox.api.wasaapay.com/v1forhttps://api.wasaapay.com/v1and issue a fresh production API key from the dashboard. Sandbox keys do not work in production. - Scope keys tightly. Give each workload the narrowest scope it needs —
read_only,write,payout_only, orfull. Isolate payout ability in a dedicatedpayout_onlykey. See Authentication → Scopes. - Store secrets in a secret manager, never in source or client bundles. The web SDK's HMAC signer runs server-side only — the secret must never reach a browser or a mobile binary.
- Rotate on a schedule and immediately if a key is exposed. Rotation returns a new secret once and revokes the old key.
Security
- HTTPS everywhere. All production traffic — API calls and webhook endpoints — must be HTTPS. Webhook endpoints resolving to private/loopback ranges, or served over plain HTTP, are rejected in production.
- Verify every webhook signature. Reject deliveries whose
X-WasaaPay-Signaturedoesn't match and whoseX-WasaaPay-Timestampis more than 300 seconds old. See Webhooks → Verifying the signature. - Keep clocks in sync (NTP). Request signing and webhook verification both
enforce a ±300s timestamp window; clock drift causes spurious
AUTH_SIGNATURE_MISMATCH. - Consider an IP allowlist on production keys (issued with an
ip_allowlist) so a leaked key is unusable from an unknown source.
PCI — never touch card data
- Never send a raw PAN or CVV to WasaaPay. The card rail accepts only
tokens. Use the tokenizing checkout SDK / CyberSource Unified
Checkout so card data goes straight to the certified processor and only a
tok_*reference reaches your servers and this API. - On mobile, inject the certified card tokenizer into the SDK's
CheckoutConfiguration— the default tokenizer is a sandbox placeholder and must not ship in production. - Prefer the hosted checkout session or the mobile checkout UI so you keep card handling out of your own systems entirely.
Correctness & resilience
- Send an
Idempotency-Keyon every fund-moving POST (collections, refunds, checkout-session create/pay, sub-merchant create, payouts, bulk payouts). Reuse the same key across retries of one logical attempt; use a new key for a new operation. See Making requests → Idempotency. - Treat the create response as non-final. A collection/payout is usually
pending; wait for thetransaction.*/payout.*webhook (or poll) for the terminal state. Make your webhook handler idempotent and dedupe onevent.id— events fire on every status change and can be redelivered. - Handle the full error catalog. Branch on
error.codeand HTTP status: back off on429(honorRetry-After) and503 RAIL_UNAVAILABLE, surface402 INSUFFICIENT_FUNDSand403 COMPLIANCE_HOLD, and never retry a422 VALIDATION_ERRORunchanged. See Making requests. - Log
meta.request_idon every call — it's the fastest path to support. - Respond
2xxto webhooks quickly and do heavy work asynchronously; slow responses count as failed deliveries and get retried.
Operational
- Register production webhook endpoints and store each
signing_secretsecurely (it's shown once). Subscribe only to the events you consume. - Rehearse failure paths in sandbox first using the magic values — declines, timeouts, insufficient funds, 3-D Secure — so your handling is proven before real money is involved. See Testing.
- Reconcile. Keep your own ledger in step with
transaction.*,payout.*, andescrow.*webhooks and withGET /transactions.
Account provisioning. Self-serve production signup is not yet available — production merchant accounts and go-live are provisioned with WasaaPay. Reach out to your WasaaPay contact to complete KYB and enable live processing.