API Basics
All Merchant API requests must be made from your backend over HTTPS. Do not call secret-key endpoints directly from a browser or mobile app.
Authentication
Send your test or live secret key as a bearer token:
Authorization: Bearer <secret_key>
Content-Type: application/json
Accept: application/jsonIf the header is missing or the key cannot be resolved, the API returns HTTP 401 with a JSON error such as:
{
"status": false,
"message": "Invalid Merchant Authorization"
}The key determines whether the request runs in test or live mode. Use test keys for test traffic and live keys only after your integration has passed QA.
Product Access
Some endpoints require the corresponding business product to be enabled. For example, checkout endpoints require checkout access, reserved account endpoints require reserved account access, and payout endpoints require payout access.
If access is not enabled or the merchant account is blocked, the API can return HTTP 403.
IP Allowlisting
If IP allowlisting is enabled for your business, requests must originate from an allowed IP address or CIDR range. Unauthorized IPs are rejected with HTTP 403.
For production, allowlist only stable outbound IPs from your backend or NAT gateway. Avoid routing API calls through developer laptops, browser clients, or dynamic residential networks.
Request and Response Format
Plain requests and responses use JSON unless AES encryption is enabled for your business. Encrypted responses are returned as application/octet-stream; see API Encryption.
Most responses include one of these envelope styles:
{
"success": true,
"message": "Transaction Initialized Successfully",
"data": {}
}{
"status": true,
"message": "Verification successful",
"data": {}
}Use both the HTTP status code and the response body. Some payment and payout status values are business statuses, not HTTP statuses.
Rate Limits
Rate limits are enforced server-side and may be tuned per environment. Current implementation defaults include:
| Scope | Default limit |
|---|---|
| Merchant API | 600 requests per minute |
| Verification endpoints | 200 requests per minute |
| HMAC signature generation | 30 requests per minute |
| Webhook resend endpoints | 10 requests per minute |
When you receive HTTP 429, retry with exponential backoff and avoid parallel retry storms.
Common HTTP Responses
| HTTP status | Meaning | Typical cause |
|---|---|---|
200 | Request processed | Successful reads and many successful writes. |
400 | Bad request | Invalid encrypted payload, invalid type, malformed data. |
401 | Unauthorized | Missing/invalid secret key or validation failures on some payout endpoints. |
403 | Forbidden | Account blocked, product access denied, IP not allowed, invalid RSA signature. |
404 | Not found | Transaction, transfer, customer, or account reference was not found. |
429 | Too many requests | Rate limit exceeded. |
503 | Temporarily unavailable | Downstream payout processing or central system unavailable. |
Production Checklist
- Store secret keys, encryption keys, webhook keys, and RSA private keys in a secret manager.
- Generate unique references for every transaction and payout.
- Send
Idempotency-Keyon payout creation. - Verify all final states through webhooks and verify endpoints.
- Log Cashonrails references, your internal order IDs, HTTP status, and response status without logging secrets or full PII payloads.
- Build retry logic only for network failures, HTTP
429, and clearly temporary5xxresponses.