QuataPay
Developer

Best practices

Patterns we recommend after seeing how integrations fail.

Browse developer docs
Back to developer docs

Trust the webhook, never the redirect

Customers can bookmark, share, or be redirected by a flaky browser. The webhook is the only ground truth. Don't fulfil an order on success_url alone.

Validate webhook signatures

Every webhook is HMAC-SHA256 signed with your endpoint secret. Reject any delivery whose signature doesn't match — without this check, anyone who knows your URL can mark orders paid.

Make the webhook handler idempotent

We retry deliveries on non-2xx responses, and at-least-once means you will sometimes get the same event twice. Look up the event id before acting; ignore if you've seen it.

Use idempotency keys on every money-moving POST

Generate a fresh UUID per logical operation (per order, per refund, per transfer). On retries, send the same key — the server returns the original response instead of doing the work twice.

Keep secrets in a vault, not in env files committed to git

At minimum, use a .env file that's in .gitignore. Better, use your platform's secret manager (AWS Secrets Manager, Doppler, 1Password). Rotate on every offboard.

Use the sandbox to test failure modes

Don't wait for production to discover what happens when a customer cancels mid-flow. The sandbox lets you simulate every state explicitly.

Cap your timeouts

Set a connect timeout of 5s and a read timeout of 30s. Anything longer is almost certainly a hung connection — fail fast and let your retry loop handle it.