RoutePay Payment API
Welcome to the RoutePay Developer Portal.
Use this space to describe your platform at a high level: what it does, who it's for, and how the API fits into your product.
Getting started
Create a RoutePay account
Sign up on the RoutePay merchant portal and complete any required KYC so you can generate API credentials.
Obtain your API credentials
From the dashboard, generate your Client ID and Client Secret. Store them securely; you’ll use them to request an access token.
-
Log in to the RoutePay Merchant Portal.
-
Navigate to the Merchants section to view the list of all merchants.
-
Select the merchant for which you want to create an application.
-
Click the three-dots menu (⋮) next to the merchant.
-
Choose “Generate Client Secret” from the dropdown options.
-
The system will generate a ClientId and ClientSecret.
-
Copy and store these credentials securely — they are required for API integration.

Authenticate with the API
Use the Authentication endpoint to exchange your client credentials for an access_token:
POST https://auth{{Env}}.routepay.com/connect/token Content-Type: application/x-www-form-urlencoded
You can always jump into the full API reference for more details.
Common headers & conventions
- Use Content-Type: application/json for JSON payloads.
- Include Authorization: Bearer {{access_token}} for protected endpoints.
- Use merchantReference and transactionReference in your system to correlate requests and responses.
- Confirm successful payment using both HTTP 200 and payment-specific status values
Payment flow
Create payment (SetRequest)
Endpoint: POST {{baseUrl}}/payment/api/v1/Payment/SetRequest
POST {{baseUrl}}/payment/api/v1/Payment/SetRequest
Content-Type: application/json
Authorization: Bearer {access_token}
Request body example
{
"merchantId": "{{ClientId}}",
"returnUrl": "https://merchant.example.com/return",
"merchantReference": "A1B2",
"totalAmount": "500",
"currency": "NGN",
"paymentType": "PAYMENT",
"customer": {
"email": "test@example.com",
"mobile": "0800000000",
"firstname": "John",
"lastname": "Doe",
"username": "jdoe"
},
"products": [
{
"name": "product1",
"unitPrice": "100",
"quantity": 1
}
]
}
Response sample
{
"redirectUrl": "https://paymentqa.routepay.com/pay/2026020805182747256",
"transactionReference": "2026020805182747256",
"merchantReference": "2cf5ab3d-8366-4376-80c7-49e8a5fc3735",
"responseCode": "00",
"responseMessage": "success"
}
Redirect / Hosted payment page
Client should redirect the user to redirectUrl to complete the hosted payment flow (card checkout). The hosted page will handle card acceptance or other enabled payment methods.
Query transaction status
Endpoint: GET {{baseUrl}}/payment/api/v1/Payment/GetTransaction/{transactionReference}
Purpose: confirm final payment status. Rely on both the HTTP response and the paymentStatus in the response body.
Payment status codes
| Status Code | Meaning |
|---|---|
| 0 | Successful |
| 550 | Failed |
| 250 | Pending |
| 260 | Processing |
| 210 | Already Processed |
| 220 | Cancelled |
Error handling and idempotency
Treat non-2xx HTTP responses as errors. Log the full response and x-correlation-id (when present) for debugging.
Use merchantReference or transactionReference as idempotency keys on your side to prevent duplicate processing. The API will return AlreadyProcessed for duplicates in some flows.
If the payment returns an intermediate state (e.g., Pending/Processing), poll GetTransaction and avoid returning final confirmation to end-users until you see Successful or Failed.
Testing / Sandbox card data
Payment Approved: 5060990580000217498 — Expiry 05/2050, CVV 123
Payment Declined: 4242 4242 4242 4242 — Expiry 05/2050, CVV 123
Bills Payment flow
RoutePay exposes {{baseUrl}}/bills/api/v1/Payment/lookup and {{baseUrl}}/bills/api/v1/Payment/charge for operator lookups and charges.
You will need to enable the Bills Payment API feature from your merchant kebab menu.
Lookup (product info / bundle list)
Endpoint: POST {{baseUrl}}/bills/api/v1/Payment/lookup Checkout the API reference for full collection and examples
Common request body
{
"billCode": "AIRTEL_BUNDLE",
"payload": {}
}
Charge (execute payment)
Endpoint: POST {{baseUrl}}/bills/api/v1/Payment/charge
POST {{baseUrl}}/bills/api/v1/Payment/charge
Content-Type: application/json
Authorization: Bearer {access_token}
Request body example (airtime):
{
"billCode": "AIRTEL",
"merchantReference": "{{$guid}}",
"transactionReference": "",
"paymentMode": "purse",
"externalReference": "6747843745",
"payload": {
"mobileNumber": "08077722222",
"amount": "100"
}
}
Response sample
{
"status": 200,
"responseCode": "00",
"responseDescription": "Successful",
"billsReference": "4664683003593395673",
"merchantReference": "08979013-07ea-4d29-abe2-28838bcb4541"
}
Payout API
The Subaccounts API provides endpoints for creating and managing sub-accounts, checking balances, retrieving transaction history, and performing payouts or debits. All requests require JSON request bodies and return JSON responses.
Base URL: /api/v1/Subaccounts
Create Subaccount
POST /api/v1/Subaccounts
Description: Creates a new subaccount for a merchant user.
Request Body
{
"merchantId": "string",
"userId": "string",
"accountName": "string",
"bvn": "string",
"alias": "string"
}
Response Sample
{
"userId": "string",
"accountName": "string",
"accountNumber": "string",
"status": "string",
"responseCode": "string"
}
Error (400 – Bad Request):
{
"isSuccess": false,
"error": "string",
"message": "string",
"responseCode": "string"
}
Get Subaccount Details
GET /api/v1/Subaccounts/{id}
Path Parameter:
id (string, required) — Subaccount ID.
Response
{
"isSuccess": true,
"error": "string",
"message": "string",
"responseCode": "string",
"value": {
"accountName": "string",
"accountNumber": "string",
"availableBalance": 0,
"currency": "string",
"created": "2025-08-18T20:54:45.086Z"
}
}
Get Subaccount Balance
GET /api/v1/Subaccounts/{accountNumber}/balance
Path Parameter: accountNumber (string, required) — Subaccount Number.
Response
{
"isSuccess": true,
"error": "string",
"message": "string",
"responseCode": "string",
"value": {
"accountName": "string",
"accountNumber": "string",
"availableBalance": 0,
"currency": "string",
"created": "2025-08-18T20:54:45.086Z"
}
}
Get Transaction History
POST /api/v1/Subaccounts/{id}/GetTransactionHistory
Path Parameter: id (string, required) — Subaccount Number.
Request Body
{
"endDate": "string",
"startDate": "string",
"merchantId": "string",
"accountNumber": "string",
"pageSize": 0,
"pageNumber": 0,
"disablePagination": true
}
Response
{
"isSuccess": true,
"error": "string",
"message": "string",
"responseCode": "string",
"value": {
"accountName": "string",
"accountNumber": "string",
"availableBalance": 0,
"currency": "string",
"created": "2025-08-18T20:54:45.090Z"
}
}
Payouts
Transfer Funds
POST /api/v1/Subaccounts/{accountNumber}/payouts
Path Parameter: accountNumber (string, required) — Merchant AccountNumber.
Request Body
{
"transferNarration": "string",
"beneficiaryAccountNumber": "string",
"beneficiaryAccountName": "string",
"bankCode": "string",
"bankName": "string",
"amount": 0,
"merchantReference": "string"
}
Response Body
{
"isSuccess": true,
"message": "Transfer successful",
"responseCode": "00"
}
Debits
POST /api/v1/Subaccounts/{accountNumber}/debits
Path Parameter: accountNumber (string, required) — Subaccount Number.
Request Body
{
"transferNarration": "string",
"amount": 0,
"transferReference": "string"
}
Response Body
{
"isSuccess": true,
"message": "Debit successful",
"responseCode": "00"
}
Generate Customized QR Dynamic Payment Link
This API generates a customized QR code for a payment request to a merchant. The QR code can be scanned by customers to initiate and complete payment.
Endpoint
Post: {baseurl}/api/v1/QRCode/GenerateCustomizedQRDynamicPaymentLink Authentication Type: Bearer Token (JWT) Header: Authorization: Bearer <your_access_token>
Request Format
The API accepts a multipart/form-data payload.
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
| dynamicName | string | Yes | A dynamic identifier for the QR code (e.g., customer name, label). |
| amount | decimal | Yes | The payment amount to be linked to the QR code. |
| durationInSeconds | number | Yes | Expiry duration of the QR code in seconds (e.g., 259200 = 3 days). |
| merchantReference | string | Yes | Merchant’s unique reference for tracking the transaction. |
| merchantLogo | file | Yes | Merchant’s logo image (must be PNG format). |
| returnUrl | string | Yes | The callback URL to redirect after payment is completed. |
| verifyMe | boolean | No | Flag to enable extra verification on the payer (default: true). |
Example curl Request
curl --location '{baseurl}/api/v1/QRCode/GenerateCustomizedQRDynamicPaymentLink' \
--header 'Authorization: Bearer <your_access_token>' \
--form 'DynamicName="Rli"' \
--form 'Amount="2500"' \
--form 'DurationInSeconds="259200"' \
--form 'MerchantReference="INV-20251001-1246"' \
--form 'MerchantLogo=@"///Mac/Home/Downloads/download.png"' \
--form 'ReturnUrl="https://routepay.com "' \
--form 'VerifyMe="true"'
Response
{
"value": {
"qrCode": "https://staging.qr.routepay.com/QrCodes/images/175940007568de508b0c114.png",
"transactionReference": "2025100211141581551"
},
"isSuccess": true,
"error": "",
"message": null,
"responseCode": null
}
Response Fields
| Field | Type | Description |
|---|---|---|
| value.qrCode | string | URL link to the generated QR code image (PNG). |
| value.transactionReference | string | Unique reference ID for the generated payment transaction. |
| isSuccess | boolean | Indicates if the request was processed successfully. |
| error | string | Error message if the request failed. |
| message | string | Additional message details. |
| responseCode | string | Response code. |
Error Responses
| Code | Description |
|---|---|
| 400 | Bad request (missing/invalid parameters). |
| 401 | Unauthorized (invalid or missing bearer token). |
| 415 | Unsupported media type (invalid file format, only PNG is allowed). |
| 403 | Forbidden (insufficient permissions). |
| 404 | Not Found (invalid merchant reference). |
| 500 | Internal Server Error (unexpected error). |
Notes
MerchantLogo must be PNG format, otherwise the request will fail with a 415 Unsupported Media Type. The generated QR code is time-limited based on the DurationInSeconds parameter. Always store and track the transactionReference for reconciliation.
Webhook Payload (JSON)
{
"accountNumber": "0123456789",
"remarks": "Payment for order #INV-1029",
"transactionAmount": 15000.00,
"settledAmount": 14500.00,
"feeAmount": 400.00,
"vatAmount": 100.00,
"merchantReference": "INV-1029",
"transactionReference": "TXN-20260201-ABC123",
"transactionDateTime": "2026-02-01T14:32:45Z",
"notificationType": "TRANSACTION",
"status": "SUCCESS"
}
Field Definitions
| Field Name | Type | Required | Description |
|---|---|---|---|
| accountNumber | string | No | Customer or virtual account number associated with the transaction |
| remarks | string | No | Additional transaction description or narration |
| transactionAmount | decimal | Yes | Total amount paid by the customer |
| settledAmount | decimal | Yes | Net amount settled to the merchant after deductions |
| feeAmount | decimal | Yes | Transaction processing fee charged |
| vatAmount | decimal | Yes | VAT applied to the transaction fee |
| merchantReference | string | No | Merchant's unique reference for tracking the transaction |
| transactionReference | string | Yes | Unique reference ID for the transaction |
| transactionDateTime | datetime (ISO 8601) | Yes | Transaction timestamp |
| notificationType | string | Yes | Type of webhook notification (e.g. TRANSACTION, REVERSAL) |
| status | string | Yes | Transaction status (SUCCESS, FAILED, PENDING) |
Environments
- Sandbox:
https://apidev.routepay.com - Production:
https://api.routepay.com
Postman collection & developer tools
A Postman collection with the full set of requests (auth, bills, payment) is available to import into Postman.
Use the environment variables baseUrl, ClientId, ClientSecret, and accessToken to run the collection.
You can also use jump to the API Reference to view the full set of requests.
Security & best practices
Do not embed ClientSecret in client-side code. Keep it on your backend.
Use TLS for all traffic (HTTPS required).
Store access tokens securely and refresh when expired.
Validate webhook/callback signatures if RoutePay issues callbacks (contact support to confirm your account's webhook setup).
Support & contact
If you need help or notice unexpected behaviour, capture and share the following when contacting RoutePay support (support@routepay.com):
- merchantReference and transactionReference
- Timestamp of the request (UTC)
- x-correlation-id header (if present)
- Full request/response bodies (redact sensitive card data)
Next steps
- Learn more about BillsPayment API flows.
- Learn how to manage subaccounts and payouts from PayOut API.
