Single Transfers

Before you begin!
To send money on Paystack, you need API keys to authenticate your transfers. You can find your keys on the Paystack Dashboard under Settings → API Keys & Webhooks.

You can transfer money in four easy steps:

  1. Verify the account number
  2. Create a transfer recipient
  3. Initiate transfer
  4. Listen for transfer status
Feature Availability
This feature is only available to businesses in Nigeria and Ghana.

Verify the account number

You need to collect the destination account number and confirm that the account number is valid. You can use our Resolve Account NumberAPI endpoint to ensure the account number is the right one. This step is important to avoid sending money to a wrong or invalid account.

To resolve an account number, send a GET request to the Resolve Account Number API endpoint with the account number and the bank code. Ideally, you should have a form on your site or app where you can collect and resolve the account number.

Show Response
1curl https://api.paystack.co/bank/resolve?account_number=0001234567&bank_code=058
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-X GET
1{
2 "status": true,
3 "message": "Account number resolved",
4 "data": {
5 "account_number": "0001234567",
6 "account_name": "Doe Jane Loren",
7 "bank_id": 9
8 }
9}
Tip
You can get a list of banks and their code using our list bankAPI endpoint.

Create a transfer recipient

Before sending money to the account, you need to create a transfer recipient with the account details. This will return a recipient_code that you can then initiate the transfer to. This way, you can verify an account number once and use the transfer recipient code to represent the bank account number, to prevent mistakes subsequently.

To create the transfer recipient, send the user's account number and bank code to the transfer recipientAPI endpoint.

Show Response
1curl https://api.paystack.co/transferrecipient
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "type": "nuban",
5 "name": "John Doe",
6 "account_number": "0001234567",
7 "bank_code": "058",
8 "currency": "NGN"
9 }'
10-X POST
1{
2 "status": true,
3 "message": "Transfer recipient created successfully",
4 "data": {
5 "active": true,
6 "createdAt": "2020-05-13T13:59:07.741Z",
7 "currency": "NGN",
8 "domain": "test",
9 "id": 6788170,
10 "integration": 428626,
11 "name": "John Doe",
12 "recipient_code": "RCP_t0ya41mp35flk40",
13 "type": "nuban",
14 "updatedAt": "2020-05-13T13:59:07.741Z",
15 "is_deleted": false,
16 "details": {
17 "authorization_code": null,
18 "account_number": "0001234567",
19 "account_name": null,
20 "bank_code": "058",
21 "bank_name": "Guaranty Trust Bank"
22 }
23 }
24}

The recipient_code from the data object is the unique identifier for this user and would be used to make transfers to the specified account. This code should be saved with the user's records in your database.

Initiate a transfer

When you are ready to send money to the account, you call the Initate TransferAPI endpoint to perform the funds transfer.

Disabling OTP
When building a fully automated system, you might need to disable OTP for transfers. You can disable OTP from the Preferences tab on the Paystack Dashoard. You should uncheck the Confirm transfers before sending check box as shown in the image below.
Image of the disabled OTP state of tranfers
Show Response
1curl https://api.paystack.co/transfer
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "source": "balance",
5 "amount": "3794800",
6 "recipient": "RCP_t0ya41mp35flk40",
7 "reason": "Holiday Flexing"
8 }'
9-X POST
1{
2 "status": true,
3 "message": "Transfer has been queued",
4 "data": {
5 "reference": "on5hyz9poe",
6 "integration": 428626,
7 "domain": "test",
8 "amount": 3794800,
9 "currency": "NGN",
10 "source": "balance",
11 "reason": "Holiday Flexing",
12 "recipient": 6788170,
13 "status": "success",
14 "transfer_code": "TRF_fiyxvgkh71e717b",
15 "id": 23070321,
16 "createdAt": "2020-05-13T14:22:49.687Z",
17 "updatedAt": "2020-05-13T14:22:49.687Z"
18 }
19}

When you send this request, if there are no errors, the response comes back with a pending status, while the transfer is being processed.

Retrying a transfer
If there is an error with the transfer request, kindly retry the transaction with the same reference in order to avoid double crediting. If a new reference is used, the transfer would be treated as a new request.

Test transfers always return success, because there is no processing involved. The live transfers processing usually take between a few seconds and a few minutes. When it's done processing, a notification is sent to your webhook.

Authenticating with OTP

As an additional layer of security, a Paystack business owner might want to confirm a transfer by using the One Time Password (OTP) sent to their device.

If you have OTP enabled on your Paystack Dashboard and you intiate a transfer via the API, you get a response with message: Transfer requires OTP to continue and data.status: otp

1{
2 "status": true,
3 "message": "Transfer requires OTP to continue",
4 "data": {
5 "reference": "x8beye1xud",
6 "integration": 463433,
7 "domain": "test",
8 "amount": 20000,
9 "currency": "NGN",
10 "source": "balance",
11 "reason": "E choke",
12 "recipient": 10751086,
13 "status": "otp",
14 "transfer_code": "TRF_1aqrqhoomp0rjro",
15 "id": 56506855,
16 "createdAt": "2021-04-07T12:41:57.763Z",
17 "updatedAt": "2021-04-07T12:41:57.763Z"
18 }
19}

When the business owner supplies the OTP sent to their mobile number (and email if enabled), the transfer can be completed by using our Finalize TransferAPI endpoint:

Show Response
1curl https://api.paystack.co/transfer/finalize_transfer
2-H "Authorization: Bearer YOUR_SECRET_KEY"
3-H "Content-Type: application/json"
4-d '{ "transfer_code": "TRF_vsyqdmlzble3uii", "otp": "928783" }'
5-X POST
1{
2 "status": true,
3 "message": "Transfer has been queued",
4 "data": {
5 "reference": "on5hyz9poe",
6 "integration": 428626,
7 "domain": "test",
8 "amount": 3794800,
9 "currency": "NGN",
10 "source": "balance",
11 "reason": "Holiday Flexing",
12 "recipient": 6788170,
13 "status": "success",
14 "transfer_code": "TRF_vsyqdmlzble3uii",
15 "id": 23070321,
16 "createdAt": "2020-05-13T14:22:49.687Z",
17 "updatedAt": "2020-05-13T14:22:49.687Z"
18 }
19}

Listen for transfer status

When the transfers are initiated, they take a few seconds or minutes to process. When they have been processed, Paystack sends the final status as a POST event to your webhook URL.

If the transfer is successful, you will get a transfer.success notification. If the transfer failed, you will get a transfer.failed event. Learn more about Paystack events and webhook.

The response for a transfer also contains a unique transfer code to identify this transfer. You can use this code to call the Fetch TransferAPI endpoint to fetch status and details of the transfer anytime you want.