Accept XAF payments with one REST call.
A single endpoint creates a hosted-checkout intent. Redirect the customer, listen for the webhook, ship. No card form, no PCI scope, no terminal.
- Idempotency keys built in
- HMAC-SHA256 webhook signatures
- Sandbox keys with simulated wallets
- Test → live in one secret swap
curl -X POST https://api.quatapay.com/api/v1/gateway/sandbox/payments \
-H "Authorization: Bearer qpay_test_…" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "XAF",
"customer_reference": "order_12345",
"return_url": "https://shop.example.com/pay/return"
}'
# → 201
{
"success": true,
"data": {
"payment": {
"id": "pay_01HZ9X...",
"status": "requested",
"slug": "abcd1234"
},
"checkout_url": "https://quatapay.com/checkout/abcd1234"
},
"error": null
}<10 min
Quickstart
First payment live
490+
API endpoints
Per-role + per-event
<24h
Sandbox approval
Test keys immediately
v1
API version
Stable since 2026
Why us
Designed by engineers who got tired of payment APIs.
Every choice here was made because the alternative wasted somebody's afternoon.
Single source of truth
One JSON envelope on every response: `{ data, error, code }`. No bespoke field names per endpoint.
Idempotency keys
Send a UUID in `Idempotency-Key` on every POST. Replays return the cached response — never double-charge.
Signed webhooks
HMAC-SHA256 with your endpoint secret. Reject anything that doesn't match. We retry with exponential backoff.
Test/live key prefixes
`qpay_test_…` and `qpay_live_…` — impossible to ship sandbox keys to prod by accident.
Sandbox wallets
Pre-funded, deterministic. Simulate success, failure, timeout, refund — all without touching real money.
PCI-free
We host the checkout. Your servers never see card numbers. Card-network compliance is on us.
How it works
Three calls. That's it.
1. Create intent
POST /api/v1/gateway/payments with amount + currency + your order reference. We return a checkout URL.
2. Redirect customer
Send them to the checkout URL. They confirm in the QuataPay app or pay via mobile money. We bring them back to your success / cancel URL.
3. Listen for webhook
We POST to your endpoint on payment.succeeded / .failed / .refunded. You verify the signature and fulfil the order.
Reliable delivery, every time.
Webhooks are signed with HMAC-SHA256. If your endpoint returns anything other than 2xx, we retry with exponential backoff for up to 24 hours — and surface the failures in the admin panel so they don't get lost.
- Event types: payment.* / refund.* / settlement.* / dispute.*
- Up to 10 endpoints per merchant — fan out to backend, analytics, ops Slack
- Replay any past event from the merchant panel
POST /webhooks/qpay HTTP/1.1
Host: shop.example.com
X-QuataPay-Signature: sha256=a3f1c0…
Content-Type: application/json
{
"event": "gateway.payment.succeeded",
"data": {
"id": "pay_01HZ9X...",
"customer_reference": "order_12345",
"amount": 5000,
"currency": "XAF",
"status": "succeeded"
}
}The toolkit
Everything a payment integration actually needs.
API reference
Every endpoint, every field, with examples in cURL, JS, Python, PHP.
ReadSandbox
Test keys + simulated wallets. Fund / drain / reset from the merchant panel.
ReadCode examples
Drop-in snippets for Node, Python, PHP. Includes webhook verification + idempotency loops.
ReadWebhook guide
Event types, signature verification, retry policy, debugging tips.
ReadBase URL + environments
Sandbox vs production endpoints, IP allow-listing, TLS requirements.
ReadAuth + access tokens
API keys, Bearer tokens, JWT access tokens for user-side calls, rotation.
ReadBuild today
Sandbox keys in 30 seconds.
Create a merchant account, grab a test key, charge a simulated payment. No KYC required for sandbox.