Authentication
Three headers on every request. Keys are secret, shown once, and stored only as a hash.
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer pdr_test_sk_… | Always |
X-Merchant-Id | mch_test_… | Always |
Idempotency-Key | A unique string, up to 255 characters | Every POST |
Content-Type | application/json | When sending a body |
curl -s $BASE/v1/checkouts/ORD-1001 \
-H "Authorization: Bearer $KEY" \
-H "X-Merchant-Id: $MID"API keys
- Create and revoke keys in the console. You can have up to 10 active keys per merchant, for example one per service.
- The full key is shown once, when you create it. Afterwards only a masked version is shown. If you lose it, create a new key and revoke the old one.
- Revoking a key stops it working immediately.
- Keep keys on your server. Never put them in a mobile app, a browser, or a public repository.
If a key leaks
Environments
Sandbox keys start with pdr_test_sk_ and only work on sandbox-api.payder.ng. Live keys start with pdr_live_sk_ and only work on api.payder.ng. Crossing them returns 403 wrong_environment.
Idempotency
Networks fail. If you retry a request that may have succeeded, send the same Idempotency-Key and Payder will not do the work twice.
| You send | You get |
|---|---|
| Same key, same body | The original response, replayed. No second checkout, refund or payout. |
| Same key, different body | 409 idempotency_key_reused |
| Same key while the first request is still running | 409 request_in_progress. Retry in a moment. |
| No key on a POST | 400 idempotency_key_required |
Keys are remembered for 24 hours. Use a fresh random UUID per new operation, and reuse it only to retry that same operation. A 5xx response is never stored, so retrying with the same key is always safe.
Separately, every reference you send is unique per merchant. Reusing a reference with a different request returns 409 duplicate_reference.
Rate limits
120 requests per minute per API key. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Past the limit you get 429 rate_limited with a Retry-After header in seconds.