Skip to main content

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.
info

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.

info

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

POST
https://sandbox-api-d.squadco.com/transaction/mandate/create

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

200:Success
Mandate Created
{
"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"
}
}
400:Bad Request
Bad Request
{
"status": 400,
"success": false,
"message": "Customer already exists with the same email address.",
"data": {}

}

.

Validate Mandate OTP

POST
https://sandbox-api-d.squadco.com/transaction/mandate/validate-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

200:OK
Successful
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"mandate_id": "sqaudDDc5d8drug57unpf5tsimyb",
"mandate_reference_number": "MDT55718501",
"status": "approved",
"ready_to_debit": true

}
}
}
424:Expired Session
Failed Dependency
{
"status": 424,
"success": false,
"message": "Invalid or expired session.",
"data": {}
}

.

Debit Mandate

POST
https://sandbox-api-d.squadco.com/transaction/mandate/debit

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*

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

200:Success
Debit Successfull
{
"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"
}
}
}
400:Mandate Not Ready
Mandate Not Ready
{
"status": 400,
"success": false,
"message": "Mandate on account 0179088393 is not ready for debit.",
"data": {}


}
400:Minimum Amount
Bad Request
{
{
"status": 400,
"success": false,
"message": "Minimum amount for direct debit is N200.",
"data": {}
}


}
400:Over Debit
Bad Request
{
{
"status": 400,
"success": false,
"message": "Mandate on account 0188990055 balance is lesser than debit amount.",
"data": {}
}


}

.

Cancel Mandate

POST
https://sandbox-api-d.squadco.com/transaction/mandate/cancel

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

Success
Mandate Cancelled
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"canceledMandates": [
"sqaudDDf99ae9mtizerna8f"
],
"failedMandates": []
}
}
}
Failed
Failed
{
"status": 200,
"success": true,
"message": "Success",
"data": {
"canceledMandates": [],
"failedMandates": [
{
"mandateId": "sqaudDDf99ae9mtizerna8f",
"failureReason": "Mandate already cancelled"
}
]
}
}

}

.

Get Mandate Details

GET
https://sandbox-api-d.squadco.com/transaction/mandate/get-mandates

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

Success
Mandate Details
{
"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
}
}
404:Not Found
Reference Not Found
{
"status": 400,
"success": false,
"message": "No mandate found for reference workinornot242",
"data": {}
}
403:Forbidden
Forbidden
{
"success": false,
"message": "API key is empty or invalid. Key must start with sandbox_sk_",
"data": {}
}
401:Unauthorized
Unauthorized
{
"success": false,
"message": "",
"data": {}
}

.

Resend Mandate OTP

POST
https://sandbox-api-d.squadco.com/transaction/mandate/resend-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

Success
OTP Resent
{
"status": 200,
"success": true,
"message": "Success",
"data": {}
}
403:Forbidden
Forbidden
{
"success": false,
"message": "API key is empty or invalid. Key must start with sandbox_sk_",
"data": {}
}
401:Unauthorized
Unauthorized
{
"success": false,
"message": "",
"data": {}
}

Go Live

To go live, simply:

  1. Change the base URL of your endpoints from sandbox-api-d.squadco.com to api-d.squadco.com
  2. Sign up on our Live Environment
  3. Complete your KYC
  4. Use the secret key provided on the dashboard to replace the test keys gotten from the sandbox environment to authenticate your live transactions