Overview
The Transfer class provides methods for interacting with Paystack’s Transfer API. This module allows you to initiate single and bulk transfers, finalize transfers with OTP, list transfers, and verify transfer status.
Methods
initiate
Initiates a transfer to a recipient.
async initiate ( input : TransferInitiateInput ): Promise < TransferInitiateSuccess | TransferError >
input
TransferInitiateInput
required
The transfer details. Source of funds (defaults to ‘balance’)
Amount to transfer in kobo/cents (minimum: 1000)
Recipient code (must start with RCP_)
currency
'NGN' | 'USD' | 'GHS' | 'ZAR' | 'KES' | 'XOF'
Currency code (defaults to NGN)
Unique transfer reference
Optional account reference
Transfer status (pending, success, failed, etc.)
Unique transfer code (starts with TRF_)
ISO datetime when transfer was created
Example Usage:
const { data , error } = await paystack . transfer . initiate ({
source: "balance" ,
amount: 50000 ,
recipient: "RCP_recipient123" ,
reason: "Payment for services" ,
reference: "unique-transfer-ref-123" ,
});
if ( error ) {
// Check if OTP is required
if ( error . meta ?. nextStep === "send_otp" ) {
console . log ( "OTP required. Check your phone for OTP." );
} else {
console . error ( "Transfer failed:" , error );
}
} else {
console . log ( "Transfer initiated:" , data . transfer_code );
}
finalize
Finalizes a transfer with an OTP.
async finalize ( input : TransferFinalizeInput ): Promise < TransferFinalizeSuccess | GenericError >
input
TransferFinalizeInput
required
The transfer finalization details. Transfer code from the initiate response (must start with TRF_)
One-Time Password sent to your phone
Example Usage:
const { data , error } = await paystack . transfer . finalize ({
transfer_code: "TRF_code123" ,
otp: "123456" ,
});
if ( error ) {
console . error ( "Finalization failed:" , error );
} else {
console . log ( "Transfer finalized:" , data . status );
}
initiateBulk
Initiates a bulk transfer to multiple recipients.
async initiateBulk ( input : TransferBulkInitiateInput ): Promise < TransferBulkInitiateSuccess | TransferError >
input
TransferBulkInitiateInput
required
The bulk transfer details. Source of funds (defaults to ‘balance’)
Array of transfer objects Recipient code (must start with RCP_)
Unique reference for this transfer
Array of transfer result objects
Example Usage:
const { data , error } = await paystack . transfer . initiateBulk ({
source: "balance" ,
transfers: [
{
amount: 50000 ,
recipient: "RCP_recipient1" ,
reference: "bulk-transfer-ref-1" ,
reason: "Payment 1" ,
},
{
amount: 75000 ,
recipient: "RCP_recipient2" ,
reference: "bulk-transfer-ref-2" ,
reason: "Payment 2" ,
},
],
});
if ( error ) {
console . error ( "Bulk transfer failed:" , error );
} else {
console . log ( `Initiated ${ data . length } transfers` );
}
list
Lists transfers made on your integration.
async list ( input : TransferListInput ): Promise < TransferListSuccess | GenericError >
input
TransferListInput
required
Query parameters for listing transfers. Number of records to fetch per page (defaults to 50)
Page number to retrieve (defaults to 1)
Start date for date range filter (ISO datetime)
End date for date range filter (ISO datetime)
Filter by recipient code (must start with RCP_)
Array of transfer objects Recipient details including name, account details, and bank information
ISO datetime when transfer was created
Example Usage:
const { data , error } = await paystack . transfer . list ({
perPage: 50 ,
page: 1 ,
});
if ( error ) {
console . error ( "Failed to list transfers:" , error );
} else {
console . log ( `Found ${ data . length } transfers` );
}
getTransferById
Retrieves a single transfer by ID or code.
async getTransferById ( id_or_code : string ): Promise < TransferSingleSuccess | GenericError >
The ID or code of the transfer
Complete recipient details including bank information
Session details for the transfer
Fees charged for the transfer
ISO datetime when transfer was created
ISO datetime when transfer was last updated
Example Usage:
const { data , error } = await paystack . transfer . getTransferById ( "TRF_code123" );
if ( error ) {
console . error ( "Failed to fetch transfer:" , error );
} else {
console . log ( "Transfer details:" , data );
}
verify
Verifies the status of a transfer using its reference.
async verify ( reference : string ): Promise < TransferSingleSuccess | GenericError >
The reference of the transfer to verify
Complete transfer object with all details (same structure as getTransferById response)
Example Usage:
const { data , error } = await paystack . transfer . verify ( "transfer-ref-123" );
if ( error ) {
console . error ( "Verification failed:" , error );
} else if ( data . status === "success" ) {
console . log ( "Transfer completed successfully" );
} else {
console . log ( `Transfer status: ${ data . status } ` );
}
Transfer Flow
Here’s a typical flow for initiating and completing a transfer:
// Step 1: Initiate the transfer
const { data : initData , error : initError } = await paystack . transfer . initiate ({
source: "balance" ,
amount: 50000 ,
recipient: "RCP_recipient123" ,
reason: "Payment for services" ,
reference: `transfer- ${ Date . now () } ` ,
});
if ( initError ) {
// Check if OTP is required
if ( initError . meta ?. nextStep === "send_otp" ) {
console . log ( "OTP has been sent to your phone" );
// Step 2: Get OTP from user (e.g., from input field)
const otp = await getUserOTP (); // Your implementation
// Step 3: Finalize with OTP
const { data : finalData , error : finalError } = await paystack . transfer . finalize ({
transfer_code: initData . transfer_code ,
otp: otp ,
});
if ( finalError ) {
console . error ( "Transfer finalization failed:" , finalError );
} else {
console . log ( "Transfer completed:" , finalData );
}
} else {
console . error ( "Transfer failed:" , initError );
}
} else {
// Transfer completed without OTP requirement
console . log ( "Transfer successful:" , initData );
}