1. Create a payment intent
POST /api/v1/gateway/payments
Authorization: Bearer qpay_test_xxx
Idempotency-Key: 9b2c4f3e-...
{
"amount": 1500,
"currency": "XAF",
"reference": "order_12345",
"description": "Lunch combo #3",
"success_url": "https://shop.example.com/pay/success",
"cancel_url": "https://shop.example.com/pay/cancel"
}Amount is in the smallest currency unit (whole XAF for now — sub-unit support coming with the multi-currency rollout).
2. Redirect the customer
The response includes a hosted checkout_url. Redirect the customer to it. They confirm in their QuataPay app or with mobile money, then are returned to your success_url or cancel_url.
{
"data": {
"id": "pay_01HZ...",
"status": "pending",
"checkout_url": "https://quatapay.com/pay/abcd1234",
"expires_at": "2026-05-11T13:42:00Z"
}
}3. Trust the webhook, not the redirect
The redirect tells the customer the payment finished. The webhook tells your server it actually settled. Listen for payment.succeeded before you fulfil the order — never rely on the redirect alone, since the customer can bookmark or share the success URL.
Idempotency
Send a fresh UUID in Idempotency-Keyon every create call. We cache the response for 24 hours so retries don't double-charge the customer — replays return the exact same payload.