Skip to content
PayDirect Docs

Docs › Getting started

Environments and key types

The three kinds of API key - test, sandbox and production - what each does with money, and the limits that apply to each.

Every PayDirect API key has a key type: DEVELOPMENT (a test key), SANDBOX or PRODUCTION. The type decides what happens to money when you use the key. All three share one base URL and one set of endpoints, so the same deployed code runs with any of them - swapping credentials is how you move between them.

The three key types

DEVELOPMENT (test key) SANDBOX PRODUCTION
Public key prefix pk_test_… pk_live_… pk_live_…
Environment TEST LIVE LIVE
Money Never real. Every flow returns a mocked result Real Real
Amount per transaction Any amount, any currency Up to GHS 1.00, GHS only Up to GHS 1.00 until your Integrator is verified, then no cap
Use it for Building and testing your integration A small real transaction end to end, before launch Your customers

The type is fixed when a key is issued, and it fixes the prefix. You cannot change a key between DEVELOPMENT and SANDBOX/PRODUCTION - issue a new key instead. See API keys. A key's type is shown as keyType when you list your keys with GET /integrators/{id}/apikeys.

Warning

Test and live traffic share one webhook URL and one callback URL - there is no split. Every webhook payload carries an environment field (TEST or LIVE), and your receiver must branch on it, or a test payment will look like a real one. See Webhooks overview.

Test keys: everything is mocked

With a DEVELOPMENT key, no payment provider is ever contacted, in any flow: collections, hosted checkout, bill payments, payouts, withdrawals and transfers. Each returns an immediate SUCCESS with a provider reference starting SIMULATED-, and the rest behaves as it would for real - the transaction record, your test ledger balance, webhooks, idempotency, scopes and signing.

Because nothing real moves, test keys have no per-transaction cap: use whatever amounts and currencies your tests need. Your test ledger balance still applies, though. A payout or withdrawal needs a test balance to draw on, which mocked collections provide.

Because mocked outcomes are immediate, you will not see a PENDING result, a slow approval or a provider decline with a test key. Your code for those paths - waiting for the webhook, calling reconcile, handling FAILED - still has to be right. Review it carefully, and use a SANDBOX key to watch one real transaction before launch.

Sandbox keys: real money, GHS 1.00

A SANDBOX key moves real money through the real providers, limited to GHS 1.00 per transaction and to GHS only. It is how you see your integration handle a real payer, a real wallet prompt and a real settlement, for a cost of a few cedis. A request over the limit is refused with 403 before anything happens:

json
{
  "code": 403,
  "status": "error",
  "message": "SANDBOX keys are limited to GHS 1.00 per transaction."
}

The limit applies to every sandbox key, and does not change when your Integrator is verified.

Production keys

A PRODUCTION key moves real money for your customers. Until PayDirect has verified your Integrator, its production keys share the sandbox limit of GHS 1.00 per transaction; after verification there is no per-transaction cap from PayDirect beyond your configured limits. See Onboarding and verification.

Payments made from a signed-in dashboard session follow the same rule as a production key: they are real, and limited to GHS 1.00 per transaction until your Integrator is verified.

What is the same for every key

All key types
Endpoints, request and response shapes Identical
Idempotency, scopes, signing Identical
Rate limit One budget per Integrator, shared by all your keys
Webhook retry window Test keys: hourly, up to 10 hours. Sandbox and production: every 3 minutes for 4 tries, then hourly, up to 72 hours

Test and live balances and transactions are kept fully separate: a mocked collection can never fund a real payout.

A key whose type and prefix do not agree is refused with 403 "This API key's type does not match its environment. Contact support.". You should never see it; if you do, contact support.

Working with test keys

Exercise all of it before you go live:

  • Collections - POST /transactions/collect, then reconcile the transaction and confirm your records agree.
  • Payouts - POST /transactions/disburse to both a bank account and a wallet.
  • Withdrawals - POST /transactions/withdraw, once a settlement account is registered.
  • Webhooks - point webhookUrl at a tunnel (ngrok, localtunnel) and verify signatures against real deliveries, not hand-made ones.
  • Failure handling - force a 400 with a bad payload, reuse an Idempotency-Key, let a request expire. The unhappy paths are the ones that bite in production.

Then run one small real transaction with a sandbox key, and work through the go-live checklist.

Restricting where keys can be used

You can limit test and live traffic to a list of source addresses, so a leaked key is useless from anywhere else. See IP allowlisting.

Next

API keys and credentials - issuing, scoping, rotating and revoking.