Security Checklist
The security rules that matter most, in one place. Most crypto-payment incidents trace back to trusting a forgeable signal or leaking a credential — the items below prevent both.
Fulfilment — the money-losing mistakes
- Never fulfil from the callback. It is a browser redirect and every parameter can be forged. See Callback vs Webhook.
- Never fulfil from the webhook alone. It is a trigger, not the source of truth — it carries no amounts.
- Fulfil only on a verified
SUCCESS/ACCEPTABLE, from a server-side verify call. - Reconcile misses. Sweep-verify unresolved payments after expiry so a dropped webhook never strands an order — see Reconciliation.
Credentials
- Keep the API key server-side only — never in a browser bundle, mobile app, or client code.
- Store the webhook signing secret in server configuration; it is separate from the API key.
- Treat the cashout signing secret like the API key — it is shown once and moves money.
Webhook verification
- Verify the
X-Webhook-SignatureHMAC-SHA256 over the raw request body with a constant-time compare — before parsing the JSON. - Dedupe by
paymentId(delivery is at-least-once).
Money handling
- Parse every monetary value as a decimal string with a decimal library. Never parse money as a float.
API mode
- Keep the whole flow server-side; the browser talks only to your server.
- Maintain the server IP allowlist — API-mode create/read/select/expire/simulate are all IP-gated.
Cashout
- Every request is HMAC-signed over the exact raw body (
HMAC_SHA256(secret, timestamp + "." + rawBody)); GET signs an empty body. See Signing Requests. - Keep
X-Timestampcurrent — stale timestamps are rejected. - Send a unique
Idempotency-Keyon settlement creation; reuse it to safely retry. - Maintain the cashout server IP allowlist.