QuataPay
Developers

Accept XAF payments with one REST call.

A single endpoint creates a hosted-checkout intent. Redirect the customer, listen for the webhook, ship. No payment form to build, 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
}

REST

API style

JSON over HTTPS

60 / 60 s

Rate limit

Per API key and route

5

Webhook attempts

5 s timeout each

v1

API version

Path-versioned: /api/v1

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. Failed deliveries are retried up to 5 times.

Test/live key prefixes

`qpay_test_…` and `qpay_live_…` — impossible to ship sandbox keys to prod by accident.

Sandbox wallets

Test mode runs against sandbox data, with no real money involved.

Hosted checkout

We host the checkout page, so you build no payment form.

How it works

Three calls. That's it.

  1. 1. Create intent

    POST /api/v1/gateway/payments with amount + currency + your order reference. We return a checkout URL.

  2. 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. 3. Listen for webhook

    We POST to your endpoint on payment.succeeded / .failed / .refunded. You verify the signature and fulfil the order.

Webhooks

Reliable delivery, every time.

Webhooks are signed with HMAC-SHA256 over a timestamp and the body. If your endpoint does not answer 2xx within 5 seconds, we retry after 1 minute, 5 minutes, 30 minutes and 2 hours (five attempts in all) — and every attempt shows in your delivery log so it doesn'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
Read the webhooks guide
POST /webhooks/qpay HTTP/1.1
Host:                  shop.example.com
X-QuataPay-Timestamp:  1791370800
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"
  }
}

Build today

Test with sandbox keys.

Create a merchant account, grab a test key, charge a simulated payment. No KYC required for sandbox.