Direct Debit
This API set enables direct debits from an account number up to a pre-set amount over a defined timeframe without requiring further approval from the account owner.
Environment base URL:
Test: https://sandbox-api-d.squadco.com
Production: https://api-d.squadco.com
Authorization keys are to be passed via Headers as a Bearer token.
Example: Authorization: Bearer sandbox_sk_94f2b798466408ef4d19e848ee1a4d1a3e93f104046f.
The transaction reference used to initiate transactions must be unique.
Direct Debit Flow
The direct debit service works by applying Mandates to an account. A mandate is an authorized instruction that permits an account to be debited up to a specific amount within a defined duration.
Flow Summary
Creating a Mandate on an account
Account Holder approving the mandate on the account
Debiting the account using the created mandate
.
Create Mandate
This endpoint allows you to create a mandate for a GTBank account
Parameters
Create Mandate
mandate_type*
String
The type of mandate to be used, always set to emandate (electronic mandate)
debit_type*
String
VARIABLE or FIXED. Where VARIABLE is set merchant can debit mandated account at will up to the maximum amount set. Where FIXED is set account is only debited based on inital fixed settings
amount*
Integer
The total amount in kobo to be debitted throughout the mandate cycle (expressed in the lowest currency value - kobo). 10000 = 100NGN
account_number*
Integer
The account number of customer to be mandated
bank_code*
String
Unique NIP code that identifies a bank. For GTBank, always: 058
description*
String
Merchant description of the transaction
start_date*
date
Start date for the mandate, YYYY-MM-DD
end_date*
date
End date for the mandate, YYYY-MM-DD
customer_email*
String
Email of customer whose account is to be mandated. A notification will be sent to the customer
transaction_reference*
String
Unique reference number for each mandate. Where not provided, the system generates one
customerInformation*
Object
The customerInformation collects relevant customer information for mandate creation. Esure details passed are verified and correct.
identity*
Object
identity is a nested object inside the customerInformation object where value of TYPE is 'bvn' and NUMBER is the customer bvn number
firstName*
String
Customer first name, must match with BVN details
lastName*
String
Customer last name, must match with BVN details
address*
String
Customer address
phone*
Integer
Customer phone number, must match with BVN details
fixedMandateSettings*
Object
fixedMandateSettings is required where 'debit_type' is set as FIXED. It specifies the details for a fixed mandate.
frequency*
String
MONTHLY || WEEKLY || YEARLY. Specifies Frequency of debit to occur on mandated account
interval*
Integer
Count of times to debied on mandated account within the chosen Frequency
initial_debit_amount*
Integer
The first amount to be debited from the customer's mandated account
initial_debit_date*
date
Start date for the first amount to be debited, YYYY-MM-DD
Sample Request
{
"mandate_type": "emandate",
"debit_type": "variable",
"amount": "20000000000",
"account_number": "0188990055",
"bank_code": "058",
"description": "DD test merchant",
"start_date": "2026-07-01",
"end_date": "2027-01-20",
"customer_email": "jamggesd@yahoo.com",
"transaction_reference": "123f4ffghfddfdd",
"customerInformation": {
"identity": { "type": "bvn", "number": "12355666919" },
"firstName": "James",
"lastName": "Bradford",
"address": "Barclays Avenue",
"phone": "080239232912"
},
"fixedMandateSettings": {
"frequency": "monthly",
"interval": 1,
"initial_debit_amount": 500000,
"initial_debit_date": "2026-07-15"
}
}
Responses
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"message": "OTP has been sent to the customer's registered phone number.",
"mandate_id": "sqaudDDc5d887o23brgmzht6jbigf",
"mandate_type": "emandate",
"debit_type": "variable",
"status": "initiated",
"approved": false,
"ready_to_debit": false,
"reference": "123f4ffghfddfdd01q",
"account_number": "0188990055",
"description": "DD test merchant",
"start_date": "2026-08-01",
"end_date": "2028-01-20",
"date": "2026-06-18",
"next_action": "send_otp",
"session_token": "ZE7S-yPO1DBFpjDPRGMECaLoZWh1D0tBZqwxYafUNeyHcdUgNBvFUtTU1XAtuRu7Rx7_qAfw1HWMciduE1OZpiG_yYecjqYU1-3a21lHQil0GAEXByjx5xSMmFQIQ8lPBbPRVxkdhGvm7lQJhXZU_zVuAVw_9c8R070bbm7tqknb4vq5KHpEvmioLIs4GG9frPAVme0o-XmD-4ISwGEOaBrL0GvWo4ltZU3N23zIxIlPBuC_WCT7CzDbdMoyls-a0lKs_CWrU12zhEWeg8hLrZtYtX0pUOUW5ep-Qii0fVQ"
}
}
{
"status": 400,
"success": false,
"message": "Customer already exists with the same email address.",
"data": {}
}
.
Validate Mandate OTP
This endpoint allows you to validate the OTP supplied by the customer
Parameters
Validate Mandate OTP
session_token*
String
Returned session token gotten from the Create Mandate API
otp*
Integer
OTP Sent to customer phone number
Sample Request
{
"session_token":"L4m4KIJXFezyB7S7jz_1oqMaavlNg3_cvodEuJxWqrojn_GWX4zkd6q8hro__Q-jjwrC0flUMrOa0NOfzlXwt-i3bltIymcridtEK-EuZpsphME8_QFIPHDqF6xkZJ0Lr45-BPH0blELmN-sZg",
"otp":"102345"
}
Responses
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"mandate_id": "sqaudDDc5d8drug57unpf5tsimyb",
"mandate_reference_number": "MDT55718501",
"status": "approved",
"ready_to_debit": true
}
}
}
{
"status": 424,
"success": false,
"message": "Invalid or expired session.",
"data": {}
}
.
Debit Mandate
This endpoint allows you to debit an account where a mandate has been created
Parameters
Debit Mandate
amount*
Integer
Amount to be debitted from account
mandate_id*
Integer
mandate_id gotten in response from Creating the Mandate
transaction_reference*
Integer
Merchant created reference
narration*
String
narration of debit
pass_charge*
Boolean
Pass charges to customers by setting to True
customer_email*
customer email address to be notified
Sample Request
{
"amount": 100000,
"mandate_id": "sqaudDDc5d8drug57unpf5tsimyb",
"transaction_reference": "jqwoneu43l67o22",
"narration": "3rd debit on customer",
"pass_charge": false,
"customer_email": "jamesd@yahoo.com"
}
Responses
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"status": "Success",
"aamount": 100000,
"mandate_id": "sqaudDDc5d8drug57unpf5tsimyb",
"transaction_reference": "jqwoneu43l67o22",
"date": "2026-06-18T14:50:20.1123408+00:00",
"account": {
"bank_code": "058",
"account_name": "James Bradford",
"account_number": "0188990055",
"bank_name": "GTB"
}
}
}
{
"status": 400,
"success": false,
"message": "Mandate on account 0179088393 is not ready for debit.",
"data": {}
}
{
{
"status": 400,
"success": false,
"message": "Minimum amount for direct debit is N200.",
"data": {}
}
}
{
{
"status": 400,
"success": false,
"message": "Mandate on account 0188990055 balance is lesser than debit amount.",
"data": {}
}
}
.
Cancel Mandate
This endpoint allows you to cancel a mandate on the account
Parameters
Cancel Mandate
mandateIds*
Object
mandateIdsis a object where a single or multiple mandate Ids can be passed
Sample Request
{
"mandateIds": [
"sqaudDD657al1hrep7m4bc",
"sqaudDD5c9elxp61u3sju",
"sqaudDD5c9elxp61u3sju"
]
}
Responses
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"canceledMandates": [
"sqaudDDf99ae9mtizerna8f"
],
"failedMandates": []
}
}
}
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"canceledMandates": [],
"failedMandates": [
{
"mandateId": "sqaudDDf99ae9mtizerna8f",
"failureReason": "Mandate already cancelled"
}
]
}
}
}
.
Get Mandate Details
This endpoint supports searching for mandate details using any combination of the following query parameters: status (initiated | approved | cancelled | rejected), page_size, mandate_id, merchant_ref, account_number, customer_name, mandate_type, amount, debit_type, is_approved, ready_to_debit, start_date(YYYY-MM-DD), and end_date(YYYY-MM-DD), .
Parameters
Responses
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"records": [
{
"id": "C2t9VA==",
"start_date": "2026-08-02T00:00:00",
"end_date": "2028-01-22T00:00:00",
"account_number": "0188990055",
"account_name": "James Bradford",
"bankName": "GTBank Plc",
"bank": "058",
"ready_to_debit": true,
"is_approved": true,
"status": "approved",
"merchant_reference": "123f4ffghfddfdd01q0",
"mandate_type": "emandate",
"debit_type": "variable",
"merchant_id": "AABBCCDDEEFFGGHHJJKK",
"amount": 20000000000,
"balance": 19999900000,
"total_debited": 100000,
"mandate_id": "sqaudDDc5d8drug57unpf5tsimyb",
"customer_email": "jamggesd@yahoo.com",
"customer_name": "James Bradford",
"description": "DD test merchant",
"mandate_authorization_date": "2026-08-02T00:00:00",
"created_at": "2026-06-18T14:00:17.768603",
"frequency": "monthly",
"initial_debit_amount": 500000
}
],
"next_cursor": "C2t9VA==",
"prev_cursor": "C2t9VA==",
"has_more": false,
"page_size": 20
}
}
{
"status": 400,
"success": false,
"message": "No mandate found for reference workinornot242",
"data": {}
}
{
"success": false,
"message": "API key is empty or invalid. Key must start with sandbox_sk_",
"data": {}
}
{
"success": false,
"message": "",
"data": {}
}
.
Resend Mandate OTP
This endpoint allows you to initate a resend of OTP to a customer
Parameters
Resend OTP
session_token*
String
Session token returned after calling the Create Mandate endpoint
Sample Request
{
"session_token":"AUK1hgmDUqYkoBu_LmGc85xPyFxw6Elj5CZX-4Q_Qe3V5CfOJBjDQED1EGFETqE73Y7ar1AFBlwZ_gLjWcP3R1re-jVsbIt7eeuHg5abA3hLQJMnEfXI3mRV5ALOSwTOv6NFQPHJeGFlCYZx3zbKzt83dTAXPBXs96l6BPo"
}
Responses
{
"status": 200,
"success": true,
"message": "Success",
"data": {}
}
{
"success": false,
"message": "API key is empty or invalid. Key must start with sandbox_sk_",
"data": {}
}
{
"success": false,
"message": "",
"data": {}
}
Go Live
To go live, simply:
- Change the base URL of your endpoints from sandbox-api-d.squadco.com to api-d.squadco.com
- Sign up on our Live Environment
- Complete your KYC
- Use the secret key provided on the dashboard to replace the test keys gotten from the sandbox environment to authenticate your live transactions