🔗
Base Url
securepay-staging-api.getsecurepay.ai
🔒
TLS Required
HTTPS only · TLS 1.2+
⚡
SLA Uptime
99.95% · Avg 45ms
📦
Pagination
cursor-based
Authentication
Most SecurePay endpoints authenticate requests using a Bearer access token. Some integration endpoints also require the merchant's public key in the Public-Key header. Refer to each endpoint's request example for its authentication requirements.
Public Key
Where specified, include the merchant's public key in the Public-Key header alongside the Bearer access token. The request example for each endpoint shows the headers it requires.
Authorization : Bearer YOUR_ACCESS_TOKEN
Public-Key : YOUR_PUBLIC_KEY
Content-Type : application/json
X-Request-ID : uuid-v4-trace-id
curl -X POST https://securepay-staging-api.getsecurepay.ai/api/v2/payments/initiate \
-H "accept: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
Key Management
Generate and manage merchant public keys for endpoints that explicitly require the Public-Key header.
Parameters
Request
Response
Field Type Required Description
merchantEmail
string
required
The email address of the merchant account for which the public key will be generated. Passed as a query parameter.
https://securepay-staging-api.getsecurepay.ai/api/KeyManager/generateKey?merchantEmail=maxstor%40yopmail.com
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/KeyManager/generateKey?merchantEmail=maxstor%40yopmail.com' \
-H 'accept: application/json'
{
"success" : true ,
"statusCode" : "OK" ,
"message" : "Key generated successfully" ,
"data" : {
"publicKeyEncrypted" : "SP-PK-CU8T20GnkWmlshwSMDbREGOuwXGOcMAvKuRb2th1gsjAGvrT"
}
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: application/json; charset=utf-8
date: Fri, 13 Mar 2026 13:34:27 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
200
Success — Key generated successfully. Returns the encrypted public key for the merchant
400
Bad Request — Missing or invalid merchantEmail query parameter
404
Not Found — No merchant account found for the provided email address
500
Server Error — Internal server error
Sub-accounts
Configure and manage destinations for split-payment settlement. accountType is sent as Nuban for a standard Nigerian bank account or Tsa for a Treasury Single Account. defaultSplit.type is numeric: 0 Percentage (a fraction, so 0.2 means 20%), 1 Flat (fixed NGN), 2 Custom, and 3 Ratio (relative weight).
Field Type Required Description
accountNumber string required 10-digit NUBAN account number.
bankCode string required Destination bank code.
{
"accountNumber": "0123456789",
"bankCode": "058"
}
{
"success": true,
"statusCode": "OK",
"message": "Account resolved.",
"data": { "accountName": "ADA OKAFOR" }
}
Field Type Required Description
businessName string required Sub-account business name.
businessMobile string required Business contact number.
accountType string required Nuban or Tsa.
country string required ISO country code, e.g. NG.
accountNumber string required Required when accountType is Nuban.
bankCode string required Required when accountType is Nuban.
tsa object required Required when accountType is Tsa.
defaultSplit object required Default Percentage, Flat, or Custom rule.
{
"businessName": "Example Partner",
"businessMobile": "+2348012345678",
"accountType": "Nuban",
"country": "NG",
"accountNumber": "0123456789",
"bankCode": "058",
"defaultSplit": { "type": 0, "value": 0.4 }
}
{
"success": true,
"statusCode": "Created",
"message": "Sub-account created and approved.",
"data": {
"subAccountId": "SUB-0001",
"businessName": "Example Partner",
"accountType": "Nuban",
"bankCode": "058",
"bankName": "GTBank",
"accountName": "EXAMPLE PARTNER LTD",
"accountLast4": "6789",
"defaultSplit": { "type": 0, "value": 0.2 },
"defaultSplitRuleVersion": 1,
"kycStatus": "Approved",
"isActive": true,
"eligibleForSplits": true,
"createdAt": "2026-08-05T09:12:00Z"
}
}
Parameters
Request
Response
Field Type Required Description
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/subaccounts' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
{
"success": true,
"statusCode": "OK",
"message": "Sub-accounts retrieved.",
"data": [
{
"subAccountId": "SUB-0001",
"businessName": "Example Partner",
"accountType": "Nuban",
"bankCode": "058",
"bankName": "GTBank",
"accountName": "EXAMPLE PARTNER LTD",
"accountLast4": "6789",
"defaultSplit": { "type": 0, "value": 0.2 },
"defaultSplitRuleVersion": 1,
"kycStatus": "Approved",
"isActive": true,
"eligibleForSplits": true,
"createdAt": "2026-08-05T09:12:00Z"
}
]
}
Not paginated — returns every sub-account for the merchant.
Parameters
Request
Response
Field Type Required Description
subAccountRef path string required SecurePay sub-account reference.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/subaccounts/SA_ABC1234567' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
{
"success": true,
"statusCode": "OK",
"message": "Sub-account retrieved.",
"data": {
"subAccountId": "SUB-0001",
"businessName": "Example Partner",
"accountType": "Nuban",
"bankCode": "058",
"bankName": "GTBank",
"accountName": "EXAMPLE PARTNER LTD",
"accountLast4": "6789",
"defaultSplit": { "type": 0, "value": 0.2 },
"defaultSplitRuleVersion": 1,
"kycStatus": "Approved",
"isActive": true,
"eligibleForSplits": true,
"createdAt": "2026-08-05T09:12:00Z"
}
}
Field Type Required Description
subAccountRef path string required SecurePay sub-account reference.
{
"success": true,
"statusCode": "OK",
"message": "Sub-account deactivated.",
"data": {
"subAccountId": "SUB-0001",
"businessName": "Example Partner",
"accountType": "Nuban",
"bankCode": "058",
"bankName": "GTBank",
"accountName": "EXAMPLE PARTNER LTD",
"accountLast4": "6789",
"defaultSplit": { "type": 0, "value": 0.2 },
"defaultSplitRuleVersion": 1,
"kycStatus": "Approved",
"isActive": false,
"eligibleForSplits": false,
"createdAt": "2026-08-05T09:12:00Z"
}
}
Returns "Sub-account already inactive." with the same shape if the sub-account was already deactivated.
Split Rules
Configure optional overrides and preview split calculations. Override scope values are Global, Campaign, and Order. Override and preview splitType values are Percentage, Flat, Custom, and Ratio; custom override rules are not accepted. Preview basis is gross or settlement.
Field Type Required Description
subAccountId string required SecurePay sub-account reference.
scope string required Global, Campaign, or Order.
splitType string required Percentage, Flat, or Ratio. Custom is rejected for overrides.
value number required Rule value.
validFrom datetime required Rule start date.
validUntil datetime required Rule expiry date.
{
"subAccountId": "SA_ABC1234567",
"scope": 0,
"splitType": 0,
"value": 0.4
}
{
"success": true,
"statusCode": "Created",
"message": "Override rule saved.",
"data": {
"subAccountId": "SA_ABC1234567",
"scope": "Global",
"splitType": "Percentage",
"value": 0.2,
"version": 1
}
}
Saving a new override for the same scope supersedes the previous version — version increments.
Parameters
Request
Response
Field Type Required Description
subAccountRef path string required SecurePay sub-account reference.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/split-rules/overrides/SA_ABC1234567' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
{
"success": true,
"statusCode": "OK",
"message": "Override rules retrieved.",
"data": [
{
"scope": "Global",
"splitType": "Percentage",
"value": 0.2,
"validFrom": null,
"validUntil": null,
"version": 1
}
]
}
Only active overrides are returned — one per scope.
Field Type Required Description
rule.type string required Percentage, Flat, Custom, or Ratio.
rule.value number required Used for Percentage/Flat previews.
rule.flatComponent number required Used for Custom previews.
rule.percentageComponent number required Used for Custom previews; a fraction.
rule.minAmount number required Used for Custom previews.
rule.maxAmount number required Used for Custom previews.
basis string required gross or settlement.
sampleAmounts array required Amounts to preview.
{
"rule": { "type": "Percentage", "value": 0.4 },
"basis": "gross",
"sampleAmounts": [10000, 25000]
}
{
"success": true,
"statusCode": "OK",
"message": "Preview generated.",
"data": {
"rule": { "type": "Percentage", "flatComponent": null, "percentageComponent": null, "minAmount": null, "maxAmount": null, "value": 0.4 },
"basis": "gross",
"previews": [
{ "sampleAmount": 10000, "settlementAmount": 10000, "computedAmount": 4000, "capApplied": "none", "note": "40.00% × 10,000.00 = 4,000.00 (fees applied at charge time — Phase 4)" },
{ "sampleAmount": 25000, "settlementAmount": 25000, "computedAmount": 10000, "capApplied": "none", "note": "40.00% × 25,000.00 = 10,000.00 (fees applied at charge time — Phase 4)" }
]
}
}
Read-only — no rule or override is persisted by this call.
Payment
Initiate and manage V2 split-payment collections. channel accepts Transfer, Card, QR, USSD, or Inflow. Each splits[].type is numeric: 0 Percentage (fraction), 1 Flat (fixed NGN), 2 Custom, or 3 Ratio (relative weight).
Field Type Required Description
amount
number
required
Gross amount paid by the customer. Must be greater than zero.
reference
string
required
Merchant-supplied idempotency reference.
splits
array
required
One or more split instructions for registered sub-accounts.
{
"amount" : 10000 ,
"currency" : "NGN" ,
"reference" : "ORDER-2026-0001" ,
"splits" : [
{
"subAccountId" : "SUB-ACCOUNT-001" ,
"type" : 0 ,
"value" : 0.4
}
]
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/payments/initiate' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"amount": 10000,
"currency": "NGN",
"reference": "ORDER-2026-0001",
"splits": [
{
"subAccountId": "SUB-ACCOUNT-001",
"type": 0,
"value": 0.4
}
]
}'
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
200
Success — V2 split-payment collection initiated successfully
400
Bad Request — Invalid request, unsupported currency, split error, or missing failover configuration
401
Unauthorized — No authenticated user session is available
403
Forbidden — V2 split payments are not enabled
Parameters
Request
Response
Field Type Required Description
collectionReference string required SecurePay collection reference.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/payments/SP_V2_C_20260724123456_abc123' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
{
"success": true,
"statusCode": "OK",
"message": "Collection retrieved.",
"data": {
"collectionReference": "SP_V2_C_20260724123456_abc123",
"merchantReference": "ORDER-2026-0001",
"status": "AwaitingPayment"
}
}
Field Type Required Description
collectionReference string required SecurePay collection reference.
No request body.
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/payments/SP_V2_C_20260724123456_abc123/confirm' \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
{
"success": true,
"statusCode": "OK",
"message": "Collection confirmed.",
"data": {
"collectionReference": "SP_V2_C_20260724123456_abc123",
"status": "Collected"
}
}
Wallets V2
Create and retrieve customer wallets. Use /wallets/create for a single customer or /wallets/bulk-create for up to 50 at once. Wallet statuses are PendingKyc (awaiting verification), Active (usable), Suspended (temporarily restricted), and Closed (permanently closed). All Wallets V2 endpoints require Public-Key. Creation endpoints return 403 if the merchant is not approved for Static Virtual Accounts.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. customerReference string required Unique merchant reference; maximum 100 characters. firstName string required Maximum 100 characters. lastName string required Maximum 100 characters. middleName string required Customer's middle name. alias string required Display alias. city string required Customer's city. address string required Customer's address. emailAddress string required Valid email; maximum 100 characters. dob date string required Exact yyyy-MM-dd format. mobileNumber string required Valid Nigerian number, at least 9 digits.
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/wallets/create' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"customerReference": "CUS-0001",
"firstName": "Ada",
"lastName": "Okafor",
"middleName": "Nneka",
"emailAddress": "ada@example.com",
"dob": "1994-06-12",
"alias": "Ada Store",
"city": "Lagos",
"address": "12 Marina Road",
"mobileNumber": "+2348012345678"
}'
{"success":true,"message":"Virtual account created successfully","data":{"customerId":"7c9e6679-7425-40de-944b-e07fc1f90ae7","customerReference":"CUS-0001","providerCustomerId":"PRV-00019284","accountNumber":"9012345678","accountName":"Ada Okafor","bankName":"Sterling Bank","bankCode":"232"}}
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. customerReference string required Unique merchant reference per item; maximum 100 characters. firstName string required Maximum 100 characters. lastName string required Maximum 100 characters. middleName string required Customer's middle name. alias string required Display alias. city string required Customer's city. address string required Customer's address. emailAddress string required Valid email; maximum 100 characters. dob date string required Exact yyyy-MM-dd format. mobileNumber string required Valid Nigerian number, at least 9 digits.
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/wallets/bulk-create' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '[
{
"customerReference": "CUS-0001",
"firstName": "Ada",
"lastName": "Okafor",
"middleName": "Nneka",
"emailAddress": "ada@example.com",
"dob": "1994-06-12",
"alias": "Ada Store",
"city": "Lagos",
"address": "12 Marina Road",
"mobileNumber": "+2348012345678"
}
]'
{"success":true,"message":"Processed 1 customers: 1 succeeded, 0 failed, 0 skipped","data":{"totalRequested":1,"successCount":1,"failureCount":0,"skippedCount":0,"results":[{"index":0,"status":"Success","stage":null,"customerReference":"CUS-0001","emailAddress":"ada@example.com","customerId":"7c9e6679-7425-40de-944b-e07fc1f90ae7","providerCustomerId":"PRV-00019284","accountNumber":"9012345678","accountName":"Ada Okafor","bankName":"Sterling Bank","bankCode":"232"}]}}
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. search query string required Search customer or wallet details. status query enum required PendingKyc, Active, Suspended, or Closed. fromDate query date-time required Inclusive creation-date range start. toDate query date-time required Inclusive creation-date range end. page query integer optional Zero-based; defaults to 0. pageSize query integer optional Defaults to 20, maximum 200.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/wallets?status=Active&page=0&pageSize=20' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"data":{"total":1,"page":0,"pageSize":20,"items":[]}}
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. id path UUID required Wallet identifier.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/wallets/{{walletId}}' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"data":{"id":"{{walletId}}","customerReference":"CUS-0001","status":"Active"}}
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. id path UUID required Wallet identifier. fromDate query date-time required Inclusive transaction-date range start. toDate query date-time required Inclusive transaction-date range end. page query integer optional Zero-based; defaults to 0. pageSize query integer optional Defaults to 20, maximum 200.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/wallets/{{walletId}}/transactions?page=0&pageSize=20' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"data":{"total":0,"page":0,"pageSize":20,"items":[]}}
Direct Debit V2
Manage mandates and debit collections using Public-Key. Mandate statuses are Pending, Active, Rejected, Cancelled, Failed, and Paused. Debit statuses are Pending, Successful, Failed, and Reversed.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. accountNumber string required Exactly 10 digits. bankCode string required Maximum 10 characters. amount decimal required Must be greater than zero. payerName string required Payer's name. email string required Must be a valid email address. phoneNumber string required Payer's phone number. address string required Payer's address. startDate date-time required Mandate start date. endDate date-time required Must be after startDate. narration string required Mandate description. reference string required Idempotency reference; a repeated value returns the existing mandate.
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/create-mandate' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"accountNumber": "0123456789",
"bankCode": "058",
"amount": 25000,
"payerName": "Ada Okafor",
"email": "ada@example.com",
"phoneNumber": "+2348012345678",
"address": "12 Marina Road",
"startDate": "2026-08-05T00:00:00Z",
"endDate": "2027-08-05T00:00:00Z",
"narration": "Monthly subscription",
"reference": "MANDATE-0001"
}'
{"success":true,"message":"Mandate created successfully","data":{
"status": "PENDING",
"reference": "MN-090POIUJM2PALKIUIO1299M",
"mandateCode": "44b62b80c08d63a6a6324c9bc878b190e86467248bb5508eb37df0cd81b4bf7f",
"amount": 1000,
"narration": "Test V2 Direct Debit",
"mandateConsent": {
"bankName": "Paystack",
"accountName": "NIBSS MANDATE ACTIVATION",
"accountNumber": "9880218357",
"amount": 50.00,
"instructions": "To complete your e-mandate activation, please make a token payment of ₦50.00 to the account number provided below. Kindly ensure that the payment is made strictly via your Mobile Banking App or Internet Banking platform.Please ensure the payment is made from the same account used to create the mandate. This token payment serves as your consent for the mandate to be activated on your account. Thank you; Account Number: 9880218357 Bank: Paystack Account Name: NIBSS MANDATE ACTIVATION OR Account Number: 9020025928 Bank: Fidelity Bank Account Name: NIBSS DIRECT DEBIT"
},
"mandateCreationFee": 0,
"vat": 0.00
}}
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. mandateCode path string required Mandate code.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/mandate-status/{{mandateCode}}' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"message":"Mandate status retrieved","data":{"mandateCode":"MND-0001","accountName":"Ada Okafor","accountNumber":"0123456789","mandateStatus":"Active","workflowStatus":"Completed","rejectionReason":null,"rejectionComment":null,"mandateAdviceStatus":"Sent","mandateAdviceSent":"true"}}
Field Type Description
data.mandateCode string Encrypted mandate code.
data.accountName string Payer account name resolved by NIBSS.
data.accountNumber string Payer account number.
data.mandateStatus string NIBSS mandate status, e.g. Active.
data.workflowStatus string NIBSS workflow stage, e.g. Biller Initiated or Completed.
data.rejectionReason string | null Set when the mandate was rejected.
data.rejectionComment string | null Set when the mandate was rejected.
data.mandateAdviceStatus string Whether the mandate advice was sent, e.g. Sent or Advise Not Sent.
data.mandateAdviceSent string Mandate advice flag as returned by NIBSS ("true"/"0").
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. status query enum required Pending, Active, Rejected, Cancelled, Failed, or Paused. page query integer optional Defaults to 1. pageSize query integer optional Defaults to 20, maximum 100.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/mandates?status=Active&page=1&pageSize=20' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"message":"Mandates retrieved","data":{"data":[{"mandateCode":"MND-0001","reference":"MANDATE-0001","status":"Active","activationState":"Activated","amount":25000,"payerName":"Ada Okafor","payerAccountNumber":"0123456789","payerBankCode":"058","narration":"Monthly subscription","createdAt":"2026-08-05T09:12:00Z","activatedAt":"2026-08-05T09:20:00Z"}],"recordsTotal":1,"recordsFiltered":1,"pageSize":20,"hasNextPage":false,"hasPreviousPage":false,"totalPages":1,"pageIndex":1}}
Field Type Description
data.data[] array Mandate summaries for the page (mandateCode, reference, status, activationState, amount, payerName, payerAccountNumber, payerBankCode, narration, createdAt, activatedAt).
data.recordsTotal integer Total records across all pages, ignoring filters.
data.recordsFiltered integer Total records matching the current filters.
data.pageSize integer Page size used.
data.hasNextPage boolean Whether a next page exists.
data.hasPreviousPage boolean Whether a previous page exists.
data.totalPages integer Total number of pages.
data.pageIndex integer Current page number.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. mandateCode path string required Mandate code. page query integer optional Defaults to 1. pageSize query integer optional Defaults to 20, maximum 100.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/mandate/{{mandateCode}}/debits?page=1&pageSize=20' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"message":"Transactions retrieved","data":{"data":[{"reference":"DDC-0001","merchantReference":"DEBIT-0001","amount":10000,"currency":"NGN","status":"Successful","transactionId":"NIBSS-TXN-0001","narration":"August subscription","failureReason":null,"beneficiaryAccountNumber":"0123456789","settledAt":"2026-08-05T09:31:00Z","createdAt":"2026-08-05T09:30:00Z"}],"recordsTotal":1,"recordsFiltered":1,"pageSize":20,"hasNextPage":false,"hasPreviousPage":false,"totalPages":1,"pageIndex":1}}
Field Type Description
data.data[] array Debit collections for the page (reference, merchantReference, amount, currency, status, transactionId, narration, failureReason, beneficiaryAccountNumber, settledAt, createdAt).
data.recordsTotal integer Total records across all pages, ignoring filters.
data.recordsFiltered integer Total records matching the current filters.
data.pageSize integer Page size used.
data.hasNextPage boolean Whether a next page exists.
data.hasPreviousPage boolean Whether a previous page exists.
data.totalPages integer Total number of pages.
data.pageIndex integer Current page number.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. mandateCode path string required Mandate code. status body enum required ACTIVE resumes, PAUSED pauses, and CANCELLED cancels. Accepted aliases: REINSTATE/RESUME, PAUSE/SUSPENDED, CANCEL/DELETED.
curl -X 'PUT' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/mandate/{{mandateCode}}/status' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"status": "PAUSED"
}'
{"success":true,"message":"Mandate paused","data":{"mandateCode":"MND-0001","status":"Paused"}}
message is dynamic — Mandate active, Mandate paused, or Mandate cancelled depending on the target status.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. mandateCode path string required Mandate code. amount query decimal required Proposed debit amount to validate.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/mandate/{{mandateCode}}/balance?amount=10000' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"message":"Balance enquiry successful","data":{"mandateCode":"MND-0001","accountBalance":500000,"hasSufficientBalance":true,"accountDetails":{"bankCode":"058","bankName":"GTBank","accountName":"Ada Okafor","accountNumber":"0123456789"}}}
Field Type Description
data.accountBalance decimal The payer account's current balance.
data.hasSufficientBalance boolean Whether the balance covers the queried amount.
data.accountDetails object Payer bank and account details (bankCode, bankName, accountName, accountNumber).
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. mandateCode path string required Mandate code. amount decimal required From 1 to 10,000,000 NGN. reference string required Idempotency reference; a repeated value returns the existing debit. narration string required Debit description. beneficiary.nuban string required Exactly 10 digits. beneficiary.nipCode string required Beneficiary bank NIP code. feeBearer body enum required business: merchant pays; customer: customer pays.meta object optional Optional string-to-string metadata.
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/mandate/{{mandateCode}}/debit' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"amount": 10000,
"narration": "August subscription",
"reference": "DEBIT-0001",
"beneficiary": {
"nuban": "0123456789",
"nipCode": "058"
},
"feeBearer": "business",
"meta": {
"invoiceId": "INV-0001"
}
}'
{"success":true,"message":"Account debited successfully","data":{"reference":"DDC-0001","merchantReference":"DEBIT-0001","mandateCode":"MND-0001","amount":10000,"transactionId":"NIBSS-TXN-0001","status":"Successful","beneficiary":{"nuban":"0123456789","nipCode":"058"},"transferFee":25,"vat":1.875}}
Field Type Description
data.reference string SecurePay-generated collection reference.
data.merchantReference string The reference you supplied on the request.
data.transactionId string NIBSS transaction id.
data.status string Pending, Successful, Failed, or Reversed.
data.beneficiary object | null Echoed back when supplied; null for direct-to-payout debits.
data.transferFee decimal Fee charged for the transfer.
data.vat decimal VAT on the transfer fee.
A debit not yet confirmed by NIBSS returns 202 with message Debit pending; awaiting NIBSS confirmation and only reference, mandateCode, amount, and status (no merchantReference, transactionId, beneficiary, transferFee, or vat).
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key. reference path string required The reference you supplied on the request.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/debit/{{reference}}/status' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"statusCode":"200","message":"Transaction status retrieved","data":{"reference":"DDC-0001","merchantReference":"DEBIT-0001","mandateCode":"MND-0001","amount":10000,"status":"Pending","transactionId":"NIBSS-TXN-0001","failureReason":null,"settledAt":null,"createdAt":"2026-08-13T07:26:27.665Z"}}
Field Type Description
data.reference string SecurePay-generated collection reference.
data.merchantReference string The reference you supplied on the Debit Mandate request.
data.status string Pending, Successful, Failed, or Reversed.
data.transactionId string | null NIBSS transaction id, once assigned.
data.failureReason string | null Set when status is Failed.
data.settledAt string | null Set when status is Successful.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/payer-banks' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"statusCode":"200","message":"Payer banks retrieved successfully","data":[{"nipCode":"000001","institutionName":"STERLING BANK"},{"nipCode":"000002","institutionName":"KEYSTONE BANK"},{"nipCode":"000003","institutionName":"FCMB"}]}
Field Type Description
data[].nipCode string Institution NIP code.
data[].institutionName string Institution name.
Parameters
Request
Response
Field Type Required Description Public-Key header required Merchant public key.
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/v2/direct-debit/beneficiary-banks' \
-H 'accept: application/json' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{"success":true,"statusCode":"200","message":"Beneficiary banks retrieved successfully","data":[{"nipCode":"000001","institutionName":"STERLING BANK"},{"nipCode":"000002","institutionName":"KEYSTONE BANK"},{"nipCode":"000003","institutionName":"FCMB"}]}
Field Type Description
data[].nipCode string Institution NIP code.
data[].institutionName string Institution name.
Direct Debit
Endpoints for managing Direct Debit billers and mandates on the SecurePay platform.
Field Type Required Description
rcNumber
string
required
RC (Registration Certificate) number of the biller's business
name
string
required
Legal business name of the biller
address
string
required
Registered address of the biller
email
string
required
Contact email address of the biller
phoneNumber
string
required
Contact phone number of the biller
accountNumber
string
required
Settlement bank account number for the biller
accountName
string
required
Name on the settlement bank account
bankCode
string
required
CBN bank code for the biller's settlement bank
mandateStatusNotificationUrl
string
required
Webhook URL to receive mandate status change notifications
merchantId
uuid
required
Unique identifier (UUID) of the SecurePay merchant account
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/createBiller
{
"rcNumber" : "string" ,
"name" : "string" ,
"address" : "string" ,
"email" : "string" ,
"phoneNumber" : "string" ,
"accountNumber" : "string" ,
"accountName" : "string" ,
"bankCode" : "string" ,
"mandateStatusNotificationUrl" : "string" ,
"merchantId" : "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/createBiller' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"rcNumber": "string",
"name": "string",
"address": "string",
"email": "string",
"phoneNumber": "string",
"accountNumber": "string",
"accountName": "string",
"bankCode": "string",
"mandateStatusNotificationUrl": "string",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
access-control-allow-origin: *
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 14:33:51 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
{
"success" : false ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
200
Success — Biller created successfully. Returns status and biller details
400
Bad Request — Public key is missing or invalid. Ensure your API public key is included in the request headers
500
Server Error — Internal server error
Field Type Required Description
billerId
string
required
Unique identifier of the biller to associate this product with
productName
string
required
Name of the direct debit product being created
merchantId
uuid
required
Unique identifier (UUID) of the SecurePay merchant account
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/createProduct
{
"billerId" : "string" ,
"productName" : "string" ,
"merchantId" : "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/createProduct' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"billerId": "string",
"productName": "string",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
access-control-allow-origin: *
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 15:13:05 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
{
"success" : false ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
200
Success — Product created successfully. Returns status and product details
400
Bad Request — Public key is missing or invalid. Ensure your API public key is included in the request headers
500
Server Error — Internal server error
Parameters
Request
Response
This endpoint takes no parameters. Include the merchant's public key in the Public-Key header.
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/nipBanks
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/nipBanks' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
[
{
"bankCode" : "044" ,
"bankName" : "Access-Diamond Bank" ,
"nipCode" : "000014" ,
"id" : "4b678d0c-fcef-4e44-9adb-7036b07da1b5" ,
"dateCreated" : "2026-02-06T09:55:07.072086" ,
"dateModified" : "2026-02-06T09:55:07.072079"
},
{
"bankCode" : "023" ,
"bankName" : "Citi Bank" ,
"nipCode" : "000009" ,
"id" : "745e29ad-69df-4fa0-8b39-e4e535f9697f" ,
"dateCreated" : "2026-02-06T09:55:07.0721" ,
"dateModified" : "2026-02-06T09:55:07.072095"
},
{
"bankCode" : "058" ,
"bankName" : "Guaranty Trust Bank" ,
"nipCode" : "000013" ,
"id" : "31f47480-a1c7-4c45-a56d-4d2105cf1df2" ,
"dateCreated" : "2026-02-06T09:55:07.072152" ,
"dateModified" : "2026-02-06T09:55:07.072148"
},
// ... 33 more banks
]
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 15:16:55 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
{
"success" : false ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
All 36 Banks Returned
Bank Name Bank Code NIP Code
Access-Diamond Bank 044 000014
Citi Bank 023 000009
Coronation Merchant Bank 559 060001
EcoBank 050 000010
FBN Merchant Bank 911 060002
FBNQuest Merchant Bank 560 060002
Fidelity Bank 070 000007
First Bank of Nigeria 011 000016
First City Monument Bank 214 000003
FSDH 501 400001
Globus Bank 103 000027
Greenwich Bank 562 060004
Guaranty Trust Bank 058 000013
Heritage Bank 030 000020
Jaiz Bank 301 000006
Keystone Bank 082 000002
Lotus Bank 303 000029
Nova Merchant Bank 561 060003
Optimus Bank 107 000036
Parallex Bank 104 000030
Polaris Bank 076 000008
Premium Trust Bank 105 000031
Providus Bank 101 000023
Rand Merchant Bank 502 000024
Signature Bank 106 000034
Stanbic IBTC 221 000012
Standard Chartered Bank 068 000021
Sterling Bank 232 000001
Suntrust Bank 100 000022
TAJ Bank 302 000026
Titan Trust Bank 102 000025
Union Bank 032 000018
United Bank of Africa 033 000004
Unity Bank 215 000011
Wema Bank 035 000017
Zenith Bank 057 000015
200
Success — Returns an array of all supported NIP banks with bank codes and NIP codes
400
Bad Request — Public key is missing or invalid. Ensure your API public key is included in the request headers
500
Server Error — Internal server error
Field Type Required Description
productId
integer
required
Numeric ID of the direct debit product to attach the mandate to
billerId
string
required
Unique identifier of the registered NIBSS biller
accountNumber
string
required
Payer's bank account number to be debited
bankCode
string
required
CBN bank code for the payer's bank (see Get NIP Banks )
payerName
string
required
Full name of the account holder authorising the mandate
payerAddress
string
required
Residential or business address of the payer
accountName
string
required
Name on the bank account to be debited
amount
number
required
Amount to be debited per mandate cycle (in Naira)
narration
string
required
Brief description or reference for the mandate debit
phoneNumber
string
required
Payer's contact phone number
subscriberCode
string
required
Unique code identifying the subscriber within the biller's system
startDate
string (ISO 8601)
required
Mandate activation date and time in ISO 8601 format
endDate
string (ISO 8601)
required
Mandate expiry date and time in ISO 8601 format
payerEmail
string
required
Payer's email address for mandate notifications
merchantId
uuid
required
Unique identifier (UUID) of the SecurePay merchant account
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/create-e-mandate
{
"productId" : 0 ,
"billerId" : "string" ,
"accountNumber" : "string" ,
"bankCode" : "string" ,
"payerName" : "string" ,
"payerAddress" : "string" ,
"accountName" : "string" ,
"amount" : 0 ,
"narration" : "string" ,
"phoneNumber" : "string" ,
"subscriberCode" : "string" ,
"startDate" : "2026-03-12T14:31:59.523Z" ,
"endDate" : "2026-03-12T14:31:59.523Z" ,
"payerEmail" : "string" ,
"merchantId" : "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/create-e-mandate' \
-H 'accept: */*' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"productId": 0,
"billerId": "string",
"accountNumber": "string",
"bankCode": "string",
"payerName": "string",
"payerAddress": "string",
"accountName": "string",
"amount": 0,
"narration": "string",
"phoneNumber": "string",
"subscriberCode": "string",
"startDate": "2026-03-12T14:31:59.523Z",
"endDate": "2026-03-12T14:31:59.523Z",
"payerEmail": "string",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
access-control-allow-origin: *
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 14:32:05 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — E-mandate created successfully. Returns mandate status and details
400
Bad Request — Public key is missing or invalid. Ensure your API public key is included in the request headers
500
Server Error — Internal server error
Parameters
Request
Response
Field Type Required Description
mandateCode
string
required
Mandate code identifier encoded in the URL path
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/mandate-status/4561639%2F20379%2F2169113565
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/mandate-status/4561639%2F20379%2F2169113565' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{
"success" : true ,
"statusCode" : "200" ,
"message" : "Success" ,
"data" : {
"mandateCode" : "4561639/20379/2169113565" ,
"accountName" : "ADENIYI CHINEDU MUSA" ,
"accountNumber" : "3001248102" ,
"mandateStatus" : "Active" ,
"workflowStatus" : "Biller Initiated" ,
"rejectionReason" : null ,
"rejectionComment" : null ,
"mandateAdviceStatus" : "Advise not sent" ,
"mandateAdviceSent" : 0
}
}
200
Success — Returns the current mandate status and workflow details
400
Bad Request — Invalid or missing mandate code in the request URL
500
Server Error — Internal server error
Field Type Required Description
productId
integer
required
Numeric ID of the direct debit product to attach the mandate to
billerId
string
required
Unique identifier of the registered NIBSS biller
accountNumber
string
required
Payer's bank account number to be debited
bankCode
string
required
CBN bank code for the payer's bank (see Get NIP Banks )
payerName
string
required
Full name of the account holder authorising the mandate
payerAddress
string
required
Residential or business address of the payer
accountName
string
required
Name on the bank account to be debited
amount
number
required
Amount to be debited per mandate cycle (in Naira)
narration
string
required
Brief description or reference for the mandate debit
phoneNumber
string
required
Payer's contact phone number
subscriberCode
string
required
Unique code identifying the subscriber within the biller's system
startDate
string (ISO 8601)
required
Mandate activation date and time in ISO 8601 format
endDate
string (ISO 8601)
required
Mandate expiry date and time in ISO 8601 format
payerEmail
string
required
Payer's email address for mandate notifications
merchantId
uuid
required
Unique identifier (UUID) of the SecurePay merchant account
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/create-e-mandate/v2
{
"productId" : 0 ,
"billerId" : "string" ,
"accountNumber" : "string" ,
"bankCode" : "string" ,
"payerName" : "string" ,
"payerAddress" : "string" ,
"accountName" : "string" ,
"amount" : 0 ,
"narration" : "string" ,
"phoneNumber" : "string" ,
"subscriberCode" : "string" ,
"startDate" : "2026-03-12T14:31:59.523Z" ,
"endDate" : "2026-03-12T14:31:59.523Z" ,
"payerEmail" : "string" ,
"merchantId" : "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/create-e-mandate/v2' \
-H 'accept: */*' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"productId": 0,
"billerId": "string",
"accountNumber": "string",
"bankCode": "string",
"payerName": "string",
"payerAddress": "string",
"accountName": "string",
"amount": 0,
"narration": "string",
"phoneNumber": "string",
"subscriberCode": "string",
"startDate": "2026-03-12T14:31:59.523Z",
"endDate": "2026-03-12T14:31:59.523Z",
"payerEmail": "string",
"merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
}'
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
access-control-allow-origin: *
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 14:32:05 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — E-mandate created successfully. Returns mandate status and details
400
Bad Request — Public key is missing or invalid. Ensure your API public key is included in the request headers
500
Server Error — Internal server error
Field Type Required Description
accountNumber
string
required
The account number to look up
channelCode
integer
required
Numeric code identifying the channel through which the inquiry is initiated
destinationInstitutionCode
string
required
NIP or bank code of the destination institution (see Get NIP Banks )
transactionId
string
required
Unique transaction reference ID for tracking the inquiry request
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/name-inquiry
{
"accountNumber" : "string" ,
"channelCode" : 0 ,
"destinationInstitutionCode" : "string" ,
"transactionId" : "string"
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/name-inquiry' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"accountNumber": "string",
"channelCode": 0,
"destinationInstitutionCode": "string",
"transactionId": "string"
}'
{
"success" : true ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
access-control-allow-origin: *
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 16:19:04 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
{
"success" : false ,
"statusCode" : "string" ,
"message" : "string" ,
"data" : "string"
}
200
Success — Account name resolved successfully. Returns account holder details
400
Bad Request — Public key is missing or invalid. Ensure your API public key is included in the request headers
500
Server Error — Internal server error
Parameters
Request
Response
This endpoint takes no parameters. Authentication via public key is required.
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/get-financial-institution
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/get-financial-institution' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY'
{
"success" : true ,
"statusCode" : "OK" ,
"message" : "Financial institutions retrieved successfully" ,
"data" : [
{
"id" : "string" ,
"name" : "string" ,
"code" : "string"
}
]
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: application/json; charset=utf-8
date: Thu, 12 Mar 2026 16:19:04 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — Returns a list of financial institutions
400
Bad Request — Public key is missing or invalid
500
Server Error — Internal server error
Field Type Required Description
sourceInstitutionCode
string
required
The code of the source financial institution
amount
number
required
The amount to transfer
beneficiaryAccountName
string
required
The name of the beneficiary account holder
beneficiaryAccountNumber
string
required
The beneficiary account number
beneficiaryBankVerificationNumber
string
required
The beneficiary's bank verification number
beneficiaryKYCLevel
integer
required
The KYC level of the beneficiary
channelCode
integer
required
The channel code for the transfer
originatorAccountName
string
required
The name of the originator account holder
originatorAccountNumber
string
required
The originator account number
originatorBankVerificationNumber
string
required
The originator's bank verification number
originatorKYCLevel
integer
required
The KYC level of the originator
destinationInstitutionCode
string
required
The code of the destination financial institution
mandateReferenceNumber
string
required
The reference number of the mandate
nameEnquiryRef
string
required
The reference from the name enquiry
originatorNarration
string
required
Narration for the originator
paymentReference
string
required
The payment reference
transactionId
string
required
Unique transaction ID
transactionLocation
string
required
The location of the transaction
beneficiaryNarration
string
required
Narration for the beneficiary
billerId
string
required
The ID of the biller
initiatorAccountNumber
string
required
The account number of the initiator
initiatorAccountName
string
required
The name of the initiator account holder
https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/fund-transfer
{
"sourceInstitutionCode" : "string" ,
"amount" : 0 ,
"beneficiaryAccountName" : "string" ,
"beneficiaryAccountNumber" : "string" ,
"beneficiaryBankVerificationNumber" : "string" ,
"beneficiaryKYCLevel" : 0 ,
"channelCode" : 0 ,
"originatorAccountName" : "string" ,
"originatorAccountNumber" : "string" ,
"originatorBankVerificationNumber" : "string" ,
"originatorKYCLevel" : 0 ,
"destinationInstitutionCode" : "string" ,
"mandateReferenceNumber" : "string" ,
"nameEnquiryRef" : "string" ,
"originatorNarration" : "string" ,
"paymentReference" : "string" ,
"transactionId" : "string" ,
"transactionLocation" : "string" ,
"beneficiaryNarration" : "string" ,
"billerId" : "string" ,
"initiatorAccountNumber" : "string" ,
"initiatorAccountName" : "string"
}
curl -X 'POST' \
'https://securepay-staging-api.getsecurepay.ai/api/DirectDebit/fund-transfer' \
-H 'accept: text/plain' \
-H 'Public-Key: YOUR_PUBLIC_KEY' \
-H 'Content-Type: application/json' \
-d '{
"sourceInstitutionCode": "string",
"amount": 0,
"beneficiaryAccountName": "string",
"beneficiaryAccountNumber": "string",
"beneficiaryBankVerificationNumber": "string",
"beneficiaryKYCLevel": 0,
"channelCode": 0,
"originatorAccountName": "string",
"originatorAccountNumber": "string",
"originatorBankVerificationNumber": "string",
"originatorKYCLevel": 0,
"destinationInstitutionCode": "string",
"mandateReferenceNumber": "string",
"nameEnquiryRef": "string",
"originatorNarration": "string",
"paymentReference": "string",
"transactionId": "string",
"transactionLocation": "string",
"beneficiaryNarration": "string",
"billerId": "string",
"initiatorAccountNumber": "string",
"initiatorAccountName": "string"
}'
{
"success" : true ,
"statusCode" : "OK" ,
"message" : "Fund transfer initiated successfully" ,
"data" : "string"
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: text/plain; charset=utf-8
date: Thu, 12 Mar 2026 16:19:04 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — Fund transfer initiated successfully
400
Bad Request — Public key is missing or invalid, or invalid request body
500
Server Error — Internal server error
Checkout
Endpoints for managing checkout sessions and retrieving available payment channels for a given invoice.
Parameters
Request
Response
Field Type Required Description
invoiceId
string (uuid)
required
The unique invoice ID (UUID) of the checkout session. Passed as a path parameter.
https://securepay-staging-api.getsecurepay.ai/api/checkout/db5a8d4a-d7ce-4543-8921-7edc3bd48213/available-channels
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/checkout/db5a8d4a-d7ce-4543-8921-7edc3bd48213/available-channels' \
-H 'accept: */*'
{
"success" : true ,
"statusCode" : "OK" ,
"message" : "Available payment channels retrieved successfully" ,
"data" : {
"defaultChannel" : 0 ,
"channels" : [
{
"channel" : 0 ,
"isDisabled" : false ,
"reason" : null ,
"maxLimit" : 9000000
}
]
}
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: application/json; charset=utf-8
date: Fri, 13 Mar 2026 13:43:00 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — Returns the default channel and a list of available payment channels with limits and status
404
Not Found — No checkout session found for the provided invoiceId
500
Server Error — Internal server error
Parameters
Request
Response
Field Type Required Description
invoiceId
string (uuid)
required
The unique invoice ID (UUID) of the checkout session. Passed as a path parameter.
channel
integer
required
The channel code for which to retrieve the fee breakdown. Passed as a path parameter (e.g. 0).
https://securepay-staging-api.getsecurepay.ai/api/checkout/db5a8d4a-d7ce-4543-8921-7edc3bd48213/channel/0/breakdown
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/checkout/db5a8d4a-d7ce-4543-8921-7edc3bd48213/channel/0/breakdown' \
-H 'accept: */*'
{
"channel" : 0 ,
"showFeeBreakdown" : false ,
"basePrice" : 0 ,
"channelFee" : 0 ,
"channelFeeExpression" : null ,
"vatOnFee" : 0 ,
"vatAmount" : 0 ,
"vatExpression" : null ,
"vatApplicable" : false ,
"subtotal" : 0 ,
"totalPayable" : 0
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: application/json; charset=utf-8
date: Fri, 13 Mar 2026 13:45:12 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — Returns a full fee and price breakdown for the specified channel including base price, channel fee, VAT, and total payable
404
Not Found — No checkout session found for the provided invoiceId, or the specified channel does not exist
500
Server Error — Internal server error
Parameters
Request
Response
Field Type Required Description
invoiceId
string (uuid)
required
The unique invoice ID (UUID) of the checkout session. Passed as a path parameter.
https://securepay-staging-api.getsecurepay.ai/api/checkout/db5a8d4a-d7ce-4543-8921-7edc3bd48213/preview
curl -X 'GET' \
'https://securepay-staging-api.getsecurepay.ai/api/checkout/db5a8d4a-d7ce-4543-8921-7edc3bd48213/preview' \
-H 'accept: */*'
{
"success" : true ,
"statusCode" : "OK" ,
"message" : "Checkout preview generated successfully" ,
"data" : {
"invoiceNo" : "SP_IVC_134157_f856fd" ,
"subtotal" : 200 ,
"discount" : 0 ,
"discountedAmount" : 200 ,
"vatAmount" : 13.95 ,
"processingFee" : 11 ,
"totalPayable" : 200 ,
"customerBearsFee" : false ,
"isVatInclusive" : true ,
"vatLabel" : "VAT (Inclusive)"
}
}
api-supported-versions: 1.0
cache-control: no-store
content-security-policy: unsafe-inline 'self'
content-type: application/json; charset=utf-8
date: Fri, 13 Mar 2026 13:46:54 GMT
feature-policy: accelerometer 'none'; camera 'none'; geolocation 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'
pragma: no-cache
referrer-policy: no-referrer-when-downgrade
strict-transport-security: max-age=31536000; includeSubDomains
x-content-type-options: nosniff
x-frame-options: DENY
x-permitted-cross-domain-policies: none
200
Success — Returns a full pricing preview including subtotal, discount, VAT amount, processing fee, and total payable for the checkout session
404
Not Found — No checkout session found for the provided invoiceId
500
Server Error — Internal server error
Webhooks
SecurePay notifies your application of events by sending an HTTPS POST with a JSON body to your configured merchant webhook URL. Every request is signed with HMAC-SHA256 using your merchant webhook secret. Respond with any 2xx to acknowledge; any other status, timeout or connection error is retried. If no webhook URL is configured, no webhook is sent.
Direct Debit
Events
Event When it fires directdebit.mandate.approved A customer has authorised a mandate and it is now active. directdebit.debit.successful A debit against a mandate has settled successfully. Terminal — never later changed to failed or reversed. directdebit.debit.failed A debit against a mandate has failed or could not be resolved.
Debits resolve either synchronously (definite NIBSS result on the debit call) or asynchronously (a pending debit reconciled later); the same event is sent once the outcome is definite. There is no separate reversal/chargeback event.
Payload
All events share the envelope eventId, eventType, timestamp (WAT, UTC+1) and data. Bodies are camelCase JSON and null fields are omitted, so fields that don't apply to an event won't appear.
mandate.approved
debit.successful
debit.failed
{
"eventId": "c1a2...",
"eventType": "directdebit.mandate.approved",
"timestamp": "2026-10-14T09:12:03.482",
"data": {
"status": "APPROVED",
"mandateCode": "57fb53c8907a408a22348d67c295ce1ae0341fcaee3453c284ef6edf8d51d7b4",
"reference": "merchant-ref-001",
"amount": 50000.00,
"currency": "NGN",
"narration": "Monthly subscription",
"customerEmail": "payer@example.com",
"paidAt": "2026-10-14T09:12:03.000"
}
}
{
"eventId": "d2b3...",
"eventType": "directdebit.debit.successful",
"timestamp": "2026-10-14T13:45:10.123",
"data": {
"status": "SUCCESSFUL",
"mandateCode": "57fb53c8907a408a22348d67c295ce1ae0341fcaee3453c284ef6edf8d51d7b4",
"transactionRef": "DDC-6F2A1B9C4E8D0A3F",
"reference": "merchant-tx-ref-9981",
"nibssTransactionId": "119206261014134500326352852226",
"amount": 15000.00,
"fee": 26.88,
"currency": "NGN",
"narration": "Order 9981",
"customerEmail": "payer@example.com",
"paidAt": "2026-10-14T13:45:10.000"
}
}
{
"eventId": "e3c4...",
"eventType": "directdebit.debit.failed",
"timestamp": "2026-10-14T13:47:22.900",
"data": {
"status": "FAILED",
"mandateCode": "57fb53c8907a408a22348d67c295ce1ae0341fcaee3453c284ef6edf8d51d7b4",
"transactionRef": "DDC-6F2A1B9C4E8D0A3F",
"reference": "merchant-tx-ref-9982",
"amount": 15000.00,
"currency": "NGN",
"narration": "Order 9982",
"customerEmail": "payer@example.com"
}
}
Field Type Description data.status string APPROVED, SUCCESSFUL, or FAILED. Source of truth for the outcome.data.mandateCode string Encrypted, URL-safe mandate code — the same value returned by the API, never the raw NIBSS code. data.reference string Your reference — the mandate reference (approved) or the debit's merchant reference. data.transactionRef string SecurePay's reference for the debit (debit events). data.nibssTransactionId string NIBSS transaction id (successful debits). data.amount decimal Amount in Naira (₦). data.fee decimal Transfer fee in Naira (successful debits). data.currency string Always NGN. data.narration string Transaction narration. data.customerEmail string Payer's email, if provided on the mandate. data.paidAt string Activation/settlement time (approved and successful events).
Verifying the signature
Header Type Description X-Securepay-Delivery-Id header Unique id for the delivery; identical across retries. Idempotency-Key header Same value as X-Securepay-Delivery-Id. Use it to de-duplicate. X-Securepay-Timestamp header Unix epoch seconds (UTC) when the request was signed. X-Securepay-Signature header scheme=v1,signature=<hex>
Compute HMAC-SHA256 over {timestamp}.{rawBody} using your webhook secret as the key, where rawBody is the body exactly as received (do not re-serialise). Lowercase-hex the result and compare it, in constant time, to the signature= value. Recommended: also reject requests whose timestamp is more than a few minutes old.
bool IsValid(string rawBody, string timestampHeader, string signatureHeader, string secret)
{
// signatureHeader looks like: "scheme=v1,signature=abc123..."
var provided = signatureHeader.Split("signature=").Last().Trim();
var baseString = $"{timestampHeader}.{rawBody}";
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(baseString));
var expected = Convert.ToHexString(hash).ToLowerInvariant();
return CryptographicOperations.FixedTimeEquals(
Encoding.UTF8.GetBytes(expected),
Encoding.UTF8.GetBytes(provided));
}
const crypto = require("crypto");
function isValid(rawBody, timestamp, signatureHeader, secret) {
const provided = signatureHeader.split("signature=").pop().trim();
const base = `${timestamp}.${rawBody}`;
const expected = crypto.createHmac("sha256", secret).update(base).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(provided));
}
Delivery & retries
If a 2xx isn't received, delivery is retried up to 6 times (7 attempts total) with 10–30% jitter. Retries reuse the same Idempotency-Key, and an event may arrive more than once if your response is lost — process each key exactly once.
Retry Delay after previous attempt 1 ~1 minute 2 ~5 minutes 3 ~15 minutes 4 ~1 hour 5 ~6 hours 6 ~24 hours
Best practices
Verify the signature on every request · De-duplicate using Idempotency-Key · Don't rely on event order; correlate by reference · Store the event and return 2xx fast, then process asynchronously.
Error Handling
All errors follow a consistent schema with a machine-readable code and a human-readable message.
{
"success" : false ,
"statusCode" : "BadRequest" ,
"message" : "The request body is invalid." ,
"data" : null
}
400
Bad Request — Invalid input parameters or malformed request
401
Unauthorized — Token missing, expired, or revoked
403
Forbidden — Your role doesn't have permission for this action
404
Not Found — The requested resource does not exist
429
Too Many Requests — Rate limit exceeded. Retry after Retry-After seconds
500
Internal Server Error — Something went wrong on our end. Include request_id when contacting support
SDKs & Libraries
Accelerate your integration with official client packages designed with type safety, robust networking, and built-in error handling.
Flutter
Android
iOS
macOS
Windows
Linux
Web
A Flutter package that wraps the SecurePay payment platform API, giving Flutter developers a clean, typed, and idiomatic Dart interface — no need to read the raw docs or wire up HTTP calls yourself.
Package Features
✓
Full Dart type safety — every request/response is a named model class
✓
Dio-powered HTTP — automatically injects authentication headers
✓
X-Request-ID tracing — UUID tracing headers on every request
✓
Automatic retry — exponential back-off recovery on transient errors
✓
Colour-coded logging — local logs of requests/responses (staging only)
✓
Multi-Environment — separate configurations for Staging & Production
✓
SecurePayException — structured error handling for API failures
Getting Started
Add the package dependency to your project's pubspec.yaml file:
dependencies :
securepay_api : ^0.0.1
Then, pull the package dependencies from the terminal:
Usage
Initialize the Client
Initialize the main SDK client with your environment credentials.
import 'package:securepay_api/securepay_api.dart' ;
final securePay = SecurePayApi (
publicKey: 'YOUR_PUBLIC_KEY' ,
config: SecurePayConfig .staging(enableLogging: true ),
);
final securePay = SecurePayApi (
publicKey: 'YOUR_PUBLIC_KEY' ,
config: SecurePayConfig .production(),
);
Key Management — Generate a Key
Generate public keys for merchant transactions using the key management sub-service.
try {
final response = await securePay.keyManagement.generateKey(
merchantEmail: 'jondoe@gmail.com' ,
);
if (response.success) {
final newKey = response.data["publicKey" ];
print ('Generated key: $newKey' );
}
} on SecurePayException catch (e) {
print ('SecurePay error: ${e.message} (HTTP ${e.statusCode})' );
}
Error Handling
All SDK operations throw strongly-typed exceptions on network or API failures.
try {
await securePay.keyManagement.generateKey(...);
} on SecurePayException catch (e) {
switch (e.errorCode) {
case 'UNAUTHORIZED' :
break ;
case 'BAD_REQUEST' :
break ;
case 'SERVER_ERROR' :
break ;
case 'NETWORK_ERROR' :
break ;
}
}
Configuration Options
Customize network behaviors and timeouts on client initialization:
Option
Type
Default
Description
baseUrl
String
Staging URL
API base URL override
connectTimeout
Duration
30s
Connection timeout duration
receiveTimeout
Duration
30s
Server response timeout duration
enableLogging
bool
false
Enable console logs of outgoing requests and responses (staging only)
enableRetry
bool
true
Automatically retry on transient network failures
maxRetryAttempts
int
3
Maximum number of times to retry failed requests
API Coverage
The Flutter package supports the following SecurePay platform capabilities:
Section
Status
Key Management
Active
Transfers
Active
Direct Debits
Active
Checkouts
Active
Python 3.9+
Linux
macOS
Windows
A Python library for seamlessly integrating the SecurePay payment platform API. Gives Python developers a clean, typed, fully documented interface - no need to read raw API docs or wire up HTTP calls manually.
Package Features
✓
Pydantic v2 validation — full IDE autocomplete and runtime validation
✓
HTTPX HTTP client — async-ready with automatic auth header injection
✓
X-Request-ID tracing — unique UUID header tracking per request
✓
Tenacity auto-retry — robust retry with exponential back-off
✓
Context manager support — clean client resource management
✓
Structured logging — detailed staging logs (auto-disabled in prod)
✓
Environment configs — presets for staging/production environments
✓
Exception hierarchy — clean domain errors (Unauthorized, NotFound, etc.)
Installation
Install the library from PyPI using pip:
pip install securepay-api
Usage
Initialize the Client
Instantiate the `SecurePayApi` client inside your application.
from securepay import SecurePayApi , SecurePayConfig
client = SecurePayApi (
api_key="SP-PK-xxxx" ,
config=SecurePayConfig .staging(enable_logging=True ),
)
Direct Debit — Full Example
Use the direct debit service methods to create, list, patch, and execute collections.
from datetime import date
from securepay import (
SecurePayApi , SecurePayConfig ,
BankAccount , CreateMandateRequest , DebitFrequency ,
InitiateDebitRequest , MandateStatus , UpdateMandateRequest ,
)
client = SecurePayApi (api_key="SP-PK-xxxx" , config=SecurePayConfig .staging())
mandate = client.direct_debit.create_mandate(
CreateMandateRequest (
customer_name="Ada Obi" ,
customer_email="ada@example.com" ,
customer_phone="+2348012345678" ,
bank_account=BankAccount (
account_number="0123456789" ,
bank_code="058" ,
account_name="Ada Obi" ,
),
amount=5000.00 ,
frequency=DebitFrequency .MONTHLY,
start_date=date(2025 , 8 , 1 ),
)
)
print (mandate.mandate_id)
fetched = client.direct_debit.get_mandate(mandate.mandate_id)
mandates = client.direct_debit.list_mandates(page=1 , page_size=20 )
updated = client.direct_debit.update_mandate(
mandate.mandate_id,
UpdateMandateRequest (amount=7500.00 ),
)
client.direct_debit.patch_mandate_status(
mandate.mandate_id,
status=MandateStatus .SUSPENDED,
reason="Customer requested pause." ,
)
collection = client.direct_debit.initiate_collection(
mandate.mandate_id,
InitiateDebitRequest (amount=5000.00 , narration="August subscription" ),
)
client.direct_debit.cancel_mandate(mandate.mandate_id)
Error Handling
Wrap library calls in a try-except block to catch custom exception classes.
from securepay import (
SecurePayException ,
SecurePayUnauthorizedError ,
SecurePayValidationError ,
SecurePayNotFoundError ,
SecurePayNetworkError ,
)
try :
mandate = client.direct_debit.get_mandate("mnd_xyz" )
except SecurePayUnauthorizedError :
print ("Invalid public key" )
except SecurePayNotFoundError :
print ("Mandate not found" )
except SecurePayValidationError as e:
print (f"Bad request: {e.message}" )
except SecurePayNetworkError :
print ("No internet connection" )
except SecurePayException as e:
print (f"Unexpected error: {e}" )
Configuration Options
Customize network behaviors and timeouts on client initialization:
Option
Type
Default
Description
base_url
str
Staging URL
API base URL override
timeout
float
30.0
Request timeout in seconds
max_retries
int
3
Max retry attempts
enable_logging
bool
False
Log requests and responses color-coded
enable_retry
bool
True
Automatically retry on transient network errors
API Coverage
The Python package supports the following SecurePay platform capabilities:
Section
Status
Direct Debit
Active
Transfers
Active
Checkout
Active
Key Management
Active
Local Development
Set up a development environment to run tests or extend the library:
git clone https://github.com/seniorman-dev/SecurePay-Python-Library.git
cd securepay_python
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check .