Guides

Go-live checklist

What to check before real customers deposit and withdraw through your site.

There is no sandbox. Every deposit and withdrawal moves real money. Run these checks with your own Deriv account and small amounts before you open the cashier to customers.

Keys and secrets

  • The API key lives only on your server, in a secrets manager or server environment variable (DERIPAY_API_KEY).
  • No key appears in browser code, mobile apps, repositories, logs, analytics or screenshots.
  • Each server has a key with only the scopes it needs.
  • Keys used from fixed servers have an IP allowlist.
  • The webhook secret (DERIPAY_WEBHOOK_SECRET) is stored the same way.
  • Your logs redact Deriv access tokens, API keys, withdrawal codes, OTPs and connection ids.
  • You know how to revoke a key and rotate a webhook secret in the dashboard.

Deriv connection

  • Your Deriv OAuth app uses the new client ID (not a numeric App ID) and is added under Deriv apps.
  • It requests trade account_manage payment.
  • The redirect URI is https and matches Deriv and Deripay exactly.
  • Your callback checks state and uses PKCE with S256.
  • You never store the Deriv access token after POST /connections.
  • You store the con_… id against your customer, server side.
  • You handle DERIV_RECONNECT_REQUIRED and its prefixed forms by sending the customer through OAuth again, and retry DERIV_REFRESH_UNAVAILABLE instead.

Deposits

  • You read GET /markets and offer only the markets and operators it returns.
  • You read GET /rates?country=… when the form opens and enforce deposit_limits and deposits_available.
  • Amounts are whole numbers in the local currency, labelled with the market's currency.
  • Every deposit sends an idempotency key you saved first, and retries reuse it.
  • You handle customer_action steps otp, redirect, ussd and unsupported in Tanzania and Uganda.
  • One test deposit per market you launch reached completed and the Deriv account was credited once.
  • Replaying that request with the same key returned the same transaction with Idempotent-Replayed: true.

Withdrawals

  • You check withdraw_limits_usd and the main wallet balance before you offer an amount.
  • You read the payout number back to the customer.
  • You save the transaction id before asking for the Deriv code, and confirm only that transaction.
  • You offer Resend code while the state is awaiting_code.
  • You handle WITHDRAWAL_ALREADY_ACTIVE, WITHDRAWAL_COOLDOWN and WITHDRAWAL_VELOCITY_LIMIT, honouring Retry-After.
  • You show success only at completed, and treat WITHDRAWAL_B2C_FAILED as still processing.
  • One test withdrawal per market reached completed and the money arrived on the phone.

Status and webhooks

  • A webhook endpoint is set up on https and the test event passes.
  • You verify Deripay-Signature on the raw body and reject timestamps older than 5 minutes.
  • You deduplicate events by Deripay-Event-Id and reply 2xx within 10 seconds.
  • Your cashier screen also polls or relays the event stream from your server, never from the browser with the key.
  • Polling stops at terminal: true and backs off on 429, 502 and 503.
  • A job alerts you about transactions that stay in processing too long. It never starts a replacement transaction.

Errors and support

  • Your code branches on error.code, not on error.message.
  • You log X-Request-Id for every call.
  • Customers can see their pending transactions after they leave and come back.
  • Your support team knows where to find a transaction by id in the dashboard.