API Reference
The routes below are the current Merchant API source of truth from mainApi.
Base Paths
| API area | Base path | Authentication |
|---|---|---|
| Merchant API | /api/v1 | Bearer secret key, optional AES encryption, product access gates. |
| Server-to-server payments | /api/v1/s2s | Bearer secret key, optional AES encryption, product access gates. |
| Signature helper | /api/hmac_signature | Bearer secret key. |
| Webhook signature test | /api/hmac_signature_test | Test webhook guard and HMAC signature middleware. |
Payments and Transactions
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/transaction/initialize | Create a hosted checkout transaction. |
POST | /api/v1/transaction/stripe/initialize | Create a Stripe-backed checkout transaction. |
POST | /api/v1/transaction_fee | Calculate a collection fee. |
GET | /api/v1/transaction/verify/{reference} | Verify a transaction by merchant reference. |
GET | /api/v1 | List transactions. |
GET | /api/v1/transaction/{id} | Fetch a transaction by internal ID. |
GET | /api/v1/transaction-reference/{reference} | Fetch a transaction by merchant reference. |
GET | /api/v1/resend_transaction_webhook/{reference} | Resend a transaction webhook. Throttled. |
POST | /api/v1/fund-test-account | Fund a test virtual account. Test usage only. |
Initialize Transaction Body
| Field | Required | Validation |
|---|---|---|
amount | Yes | Numeric, minimum 100. |
currency | Yes | 3-character currency code. |
reference | Yes | String, 3 to 100 characters. Must be unique per business/domain. |
customer_code | No | Existing customer code. |
email | No | Customer email. |
first_name | No | String, max 100. |
last_name | No | String, max 100. |
phone | No | String, 6 to 20 characters. |
redirectUrl | No | HTTPS URL, max 2048 characters. |
logoUrl | No | URL string, max 2048 characters. |
title | No | String, max 191. |
description | No | String, max 500. |
bvn, nin | No | 11 digits when supplied. |
dob | No | YYYY-MM-DD. |
tokenize | No | Boolean. |
bank_sweep_code, payer_id, payer_type, internalHeader | No | Optional metadata fields used by approved flows. |
Successful response:
{
"success": true,
"message": "Transaction Initialized Successfully",
"data": {
"authorization_url": "https://checkout.cashonrails.com/pay/<access_code>",
"qr_code": "data:image/png;base64,...",
"access_code": "<access_code>",
"transactionRef": "COR-...",
"reference": "merchant-reference"
}
}Customers
| Method | Path | Purpose |
|---|---|---|
POST | /api/v1/customer | Create a customer. |
GET | /api/v1/customer | List customers. Supports limit and page. |
GET | /api/v1/customer/{email_or_code} | Fetch a customer by email or customer code. |
PUT | /api/v1/customer/{code} | Update a customer. |
Create customer body: email, first_name, last_name, and phone are required. Optional fields are address, bvn, nin, dob, rc_number, company_name, incorporation_date, and metadata.
Reserved Accounts
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/get_reserved_account_providers | List reserved account providers. |
POST | /api/v1/reserved_virtual_account | Create a reserved virtual account for a customer. |
GET | /api/v1/list_reserved_accounts | List reserved accounts. Supports limit and page. |
GET | /api/v1/reserved_account/{id} | Fetch reserved account details. |
GET | /api/v1/reserved_account/{id}/transactions/{offset?} | Fetch reserved account transactions. |
Create reserved account body:
{
"customer_code": "CUS_...",
"provider": "optional-provider-code",
"otp": "123456"
}Payouts and Wallets
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/bank_list/{currency?} | List payout banks/providers. Defaults to NGN. |
POST | /api/v1/account_name | Validate recipient account name. |
POST | /api/v1/payout_fee | Calculate payout fee. |
POST | /api/v1/bank_transfer | Initiate a payout. Requires payout product access. |
GET | /api/v1/fetch_all_transfers | List payouts. |
GET | /api/v1/fetch_all_transfers/{status} | List payouts by status. |
GET | /api/v1/fetch_transfer_details/{reference} | Fetch payout details by reference. |
GET | /api/v1/wallet_balance/{currency?} | Fetch wallet balance. Defaults to NGN. |
GET | /api/v1/resend_payout_webhook/{reference} | Resend a payout webhook. Throttled. |
Payout creation body:
| Field | Required | Validation |
|---|---|---|
account_name | Yes | String, max 191. |
bank_code | Yes | String, max 20. |
amount | Yes | Numeric. Runtime rejects values below 1. |
currency | Yes | String, max 10. |
sender_name | Yes | String, max 191. |
narration | Yes | String, max 255. |
reference | Yes | String, 3 to 100 characters. |
account_number | Required unless currency is USDT | String, 5 to 20 characters. |
address | Required when currency is USDT | String, max 128. |
type | Optional | For ZAR, accepted values are EFT and RTC when supplied. For KES, accepted values are B2C and B2B when supplied. |
Payout headers:
Authorization: Bearer <secret_key>
Content-Type: application/json
X-Signature: <base64-rsa-sha256-signature>
Idempotency-Key: <stable-unique-key>If no RSA public key is configured for the business, the current implementation does not enforce X-Signature. Production integrations should still configure RSA and sign payout bodies.
Server-to-Server Payment Routes
| Method | Path | Product gate |
|---|---|---|
POST | /api/v1/s2s/card/initialize | card |
GET | /api/v1/s2s/banktransfer/list | dynamic_account |
POST | /api/v1/s2s/banktransfer/initialize | dynamic_account |
POST | /api/v1/s2s/moniepoint/initialize | dynamic_account |
GET | /api/v1/s2s/paywithussd/list | ussd |
POST | /api/v1/s2s/paywithussd/initialize | ussd |
POST | /api/v1/s2s/paywithphone/initialize | pay_with_phone |
POST | /api/v1/s2s/paywitheft/initialize | pay_with_eft |
POST | /api/v1/s2s/paywithmomo/initialize | pay_with_momo |
POST | /api/v1/s2s/paywithmomo/otp | pay_with_momo |
GET | /api/v1/s2s/paywithmomo/{currency} | pay_with_momo |
GET | /api/v1/s2s/paywithmomo-list | pay_with_momo |
POST | /api/v1/s2s/paywithcrypto/initialize | pay_with_crypto |
GET | /api/v1/s2s/paywithcrypto/list | pay_with_crypto |
POST | /api/v1/s2s/paywithbank/initialize | pay_with_bank |
GET | /api/v1/s2s/paywithbank/list | pay_with_bank |
GET | /api/v1/s2s/transaction/verify/{reference} | Authenticated verification. |
GET | /api/v1/s2s/transaction/cancel/{reference} | Authenticated cancellation. |
POST | /api/v1/s2s/test/encryption | Encryption utility. |
POST | /api/v1/s2s/test/decryption | Decryption utility. |
Public Checkout Utility Routes
These routes are exposed without Merchant API bearer authentication:
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/fetch-checkout/{identifier} | Fetch checkout information by identifier. |
GET | /api/v1/get-checkout-status/{identifier} | Get checkout status. |
GET | /api/v1/cancel-checkout/{transactionRef} | Cancel checkout by transaction reference. |
Unresolved Discrepancies
- Some older endpoint pages may still contain provider-specific sample payloads that require confirmation against sandbox provider behaviour.
- The encryption middleware encrypts all successful
200responses for enrolled businesses; this differs from older examples that described opt-in response encryption headers. - Payout validation currently returns HTTP
401for some malformed request bodies. Treat this as current behaviour, but it is a candidate for future normalization to HTTP422.
Last updated on