QuataPay
Developer docs

Sandbox

Test your integration with pre-funded wallets and simulated payment scenarios — no real XAF required.

Browse developer docs
Back to developer docs

Test your integration without moving real money.


How the sandbox works

The sandbox is a path, not a separate host. There is no separate sandbox domain. Test traffic uses the same base URL as live — https://api.quatapay.com/api/v1 — but hits the /gateway/sandbox/ path with a test key:

POST https://api.quatapay.com/api/v1/gateway/sandbox/payments

The sandbox path mirrors the live /gateway/payments API — same request and response shape. Only the path and the key prefix differ, so choose the path from the key prefix in your code and going live becomes an environment-variable change.


Sandbox API keys

Use keys with the qpay_test_ prefix. Test payments never touch the real ledger. The live /gateway/payments endpoint rejects a test key with 403, and the sandbox path rejects a live key the same way. A test key only sees test payments.

Generate test keys in your merchant panel under Developer → API keys, with the mode set to Test. The key is shown once.

The Node and Python SDKs call the live path only, so they refuse a test key with 403. Use plain HTTP (cURL, fetch, requests…) while you test.


Completing a test payment

A test-mode checkout cannot be paid in the browser: the hosted page refuses Mobile Money and wallet payments for test payments. Finish a test payment from your server, your terminal or your integration tests with the simulate call, using the payment's slug and your test key:

POST https://api.quatapay.com/api/v1/gateway/sandbox/payments/{slug}/simulate
Authorization: Bearer qpay_test_YOUR_KEY
Content-Type: application/json

{ "outcome": "succeeded" }

To simulate a failure, send { "outcome": "failed", "failure_reason": "INSUFFICIENT_FUNDS" }. POST /gateway/sandbox/payments/{slug}/cancel cancels a test payment.

This sends the same gateway.payment.* webhooks as a real completion, with "simulated": true added to data. There are no special customer_reference values: send whatever your order needs.

A good test run covers: a succeeded payment, a failed one, a cancelled one, the same webhook delivered twice, a webhook with a wrong signature and one with an old timestamp.


Test checkout flow

  1. Create a test payment with POST /gateway/sandbox/payments and your qpay_test_ key.
  2. Keep data.payment.id and data.payment.slug.
  3. Optionally open data.checkout_url to see the hosted page (it shows the order but cannot take a test payment).
  4. Call the simulate endpoint.
  5. Watch the webhook arrive at your endpoint and check your order flips to paid exactly once.
  6. Read the payment back with GET /gateway/sandbox/payments/{id}.

Sandbox wallet in the merchant panel

Developer → Sandbox in the merchant panel has a separate throwaway sandbox wallet: fund it, drain it, run simulated payments with the documented test cards, and reset it (a reset clears the history and sets the balance to 0). It is independent of the gateway test mode above.


Differences from production

FeatureTest modeLive
Real moneyNoYes
Paying the checkout in a browserNot possible: use simulateWallet or MTN Mobile Money
Webhook signing and retriesSame as liveSigned, retried after 1 min, 5 min, 30 min, 2 h
Rate limit60 requests per 60 seconds per key and endpointSame
Key and pathqpay_test_…, /gateway/sandbox/…qpay_live_…, /gateway/…

Going live

  1. Create a qpay_live_ API key in Developer → API keys and set it only in your production environment.
  2. Register your production webhook URL (Developer → Webhooks) and store its signing secret in the production environment.
  3. Make sure no test key, test URL or simulate call is left in production code.
  4. Make one small real payment and confirm the order is marked paid exactly once.