> ## Documentation Index
> Fetch the complete documentation index at: https://paystack-sdk.efobi.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Transfer

> Complete API reference for the Transfer module in the Paystack TypeScript SDK

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

```typescript theme={null}
async initiate(input: TransferInitiateInput): Promise<TransferInitiateSuccess | TransferError>
```

<ParamField path="input" type="TransferInitiateInput" required>
  The transfer details.

  <Expandable title="properties">
    <ParamField path="source" type="'balance'">
      Source of funds (defaults to 'balance')
    </ParamField>

    <ParamField path="amount" type="number" required>
      Amount to transfer in kobo/cents (minimum: 1000)
    </ParamField>

    <ParamField path="recipient" type="string" required>
      Recipient code (must start with RCP\_)
    </ParamField>

    <ParamField path="reason" type="string">
      Reason for the transfer
    </ParamField>

    <ParamField path="currency" type="'NGN' | 'USD' | 'GHS' | 'ZAR' | 'KES' | 'XOF'">
      Currency code (defaults to NGN)
    </ParamField>

    <ParamField path="reference" type="string" required>
      Unique transfer reference
    </ParamField>

    <ParamField path="account_reference" type="string">
      Optional account reference
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="domain" type="string">
      Domain type
    </ResponseField>

    <ResponseField name="amount" type="number">
      Transfer amount
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code
    </ResponseField>

    <ResponseField name="reference" type="string">
      Transfer reference
    </ResponseField>

    <ResponseField name="source" type="string">
      Source of funds
    </ResponseField>

    <ResponseField name="reason" type="string">
      Transfer reason
    </ResponseField>

    <ResponseField name="status" type="string">
      Transfer status (pending, success, failed, etc.)
    </ResponseField>

    <ResponseField name="transfer_code" type="string">
      Unique transfer code (starts with TRF\_)
    </ResponseField>

    <ResponseField name="id" type="number">
      Transfer ID
    </ResponseField>

    <ResponseField name="integration" type="number">
      Integration ID
    </ResponseField>

    <ResponseField name="recipient" type="number">
      Recipient ID
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO datetime when transfer was created
    </ResponseField>
  </Expandable>
</ResponseField>

**Example Usage:**

```typescript theme={null}
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.

```typescript theme={null}
async finalize(input: TransferFinalizeInput): Promise<TransferFinalizeSuccess | GenericError>
```

<ParamField path="input" type="TransferFinalizeInput" required>
  The transfer finalization details.

  <Expandable title="properties">
    <ParamField path="transfer_code" type="string" required>
      Transfer code from the initiate response (must start with TRF\_)
    </ParamField>

    <ParamField path="otp" type="string" required>
      One-Time Password sent to your phone
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="domain" type="string">
      Domain type
    </ResponseField>

    <ResponseField name="amount" type="number">
      Transfer amount
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code
    </ResponseField>

    <ResponseField name="reference" type="string">
      Transfer reference
    </ResponseField>

    <ResponseField name="status" type="string">
      Transfer status
    </ResponseField>

    <ResponseField name="transfer_code" type="string">
      Transfer code
    </ResponseField>

    <ResponseField name="id" type="number">
      Transfer ID
    </ResponseField>

    <ResponseField name="source_details" type="unknown">
      Source details
    </ResponseField>
  </Expandable>
</ResponseField>

**Example Usage:**

```typescript theme={null}
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.

```typescript theme={null}
async initiateBulk(input: TransferBulkInitiateInput): Promise<TransferBulkInitiateSuccess | TransferError>
```

<ParamField path="input" type="TransferBulkInitiateInput" required>
  The bulk transfer details.

  <Expandable title="properties">
    <ParamField path="source" type="'balance'">
      Source of funds (defaults to 'balance')
    </ParamField>

    <ParamField path="transfers" type="array" required>
      Array of transfer objects

      <Expandable title="transfer object">
        <ParamField path="amount" type="number" required>
          Amount to transfer
        </ParamField>

        <ParamField path="recipient" type="string" required>
          Recipient code (must start with RCP\_)
        </ParamField>

        <ParamField path="reference" type="string" required>
          Unique reference for this transfer
        </ParamField>

        <ParamField path="reason" type="string">
          Reason for the transfer
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="data" type="array">
  Array of transfer result objects

  <Expandable title="transfer result">
    <ResponseField name="reference" type="string">
      Transfer reference
    </ResponseField>

    <ResponseField name="recipient" type="string">
      Recipient code
    </ResponseField>

    <ResponseField name="amount" type="number">
      Transfer amount
    </ResponseField>

    <ResponseField name="transfer_code" type="string">
      Unique transfer code
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code
    </ResponseField>

    <ResponseField name="status" type="string">
      Transfer status
    </ResponseField>
  </Expandable>
</ResponseField>

**Example Usage:**

```typescript theme={null}
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.

```typescript theme={null}
async list(input: TransferListInput): Promise<TransferListSuccess | GenericError>
```

<ParamField path="input" type="TransferListInput" required>
  Query parameters for listing transfers.

  <Expandable title="properties">
    <ParamField path="perPage" type="number">
      Number of records to fetch per page (defaults to 50)
    </ParamField>

    <ParamField path="page" type="number">
      Page number to retrieve (defaults to 1)
    </ParamField>

    <ParamField path="from" type="string">
      Start date for date range filter (ISO datetime)
    </ParamField>

    <ParamField path="to" type="string">
      End date for date range filter (ISO datetime)
    </ParamField>

    <ParamField path="recipient" type="string">
      Filter by recipient code (must start with RCP\_)
    </ParamField>
  </Expandable>
</ParamField>

<ResponseField name="data" type="array">
  Array of transfer objects

  <Expandable title="transfer object">
    <ResponseField name="amount" type="number">
      Transfer amount
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code
    </ResponseField>

    <ResponseField name="reference" type="string">
      Transfer reference
    </ResponseField>

    <ResponseField name="status" type="string">
      Transfer status
    </ResponseField>

    <ResponseField name="transfer_code" type="string">
      Transfer code
    </ResponseField>

    <ResponseField name="recipient" type="object">
      Recipient details including name, account details, and bank information
    </ResponseField>

    <ResponseField name="created_at" type="string">
      ISO datetime when transfer was created
    </ResponseField>
  </Expandable>
</ResponseField>

**Example Usage:**

```typescript theme={null}
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.

```typescript theme={null}
async getTransferById(id_or_code: string): Promise<TransferSingleSuccess | GenericError>
```

<ParamField path="id_or_code" type="string" required>
  The ID or code of the transfer
</ParamField>

<ResponseField name="data" type="object">
  <Expandable title="properties">
    <ResponseField name="domain" type="string">
      Domain type
    </ResponseField>

    <ResponseField name="amount" type="number">
      Transfer amount
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code
    </ResponseField>

    <ResponseField name="reference" type="string">
      Transfer reference
    </ResponseField>

    <ResponseField name="reason" type="string">
      Transfer reason
    </ResponseField>

    <ResponseField name="status" type="string">
      Transfer status
    </ResponseField>

    <ResponseField name="transfer_code" type="string">
      Transfer code
    </ResponseField>

    <ResponseField name="id" type="number">
      Transfer ID
    </ResponseField>

    <ResponseField name="recipient" type="object">
      Complete recipient details including bank information
    </ResponseField>

    <ResponseField name="session" type="object">
      Session details for the transfer
    </ResponseField>

    <ResponseField name="fees_charged" type="number">
      Fees charged for the transfer
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO datetime when transfer was created
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      ISO datetime when transfer was last updated
    </ResponseField>
  </Expandable>
</ResponseField>

**Example Usage:**

```typescript theme={null}
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.

```typescript theme={null}
async verify(reference: string): Promise<TransferSingleSuccess | GenericError>
```

<ParamField path="reference" type="string" required>
  The reference of the transfer to verify
</ParamField>

<ResponseField name="data" type="object">
  Complete transfer object with all details (same structure as getTransferById response)
</ResponseField>

**Example Usage:**

```typescript theme={null}
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:

```typescript theme={null}
// 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);
}
```

***

## Related Guides

* [Getting Started](/quickstart)
* [Transfer Recipients](/api-reference/recipient)
* [Transfers Guide](/guides/transfers)
