paystack-transfers

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Paystack Transfers

Paystack 转账

The Transfers API lets you send money from your Paystack balance to bank accounts and mobile wallets. Transfers require a pre-created transfer recipient.
Depends on: paystack-setup for the
paystackRequest
helper.
Related: paystack-transfer-recipients for creating recipients before transfers.
Transfers API 允许你将资金从你的Paystack余额转账至银行账户和移动钱包。转账需要预先创建转账收款人。
依赖:paystack-setup 提供的
paystackRequest
工具函数。
相关技能:paystack-transfer-recipients,用于在转账前创建收款人。

Endpoints

端点

MethodEndpointDescription
POST
/transfer
Initiate a transfer
POST
/transfer/finalize_transfer
Finalize transfer (OTP)
POST
/transfer/bulk
Initiate bulk transfer
GET
/transfer
List transfers
GET
/transfer/:id_or_code
Fetch a transfer
GET
/transfer/verify/:reference
Verify a transfer
方法端点描述
POST
/transfer
发起转账
POST
/transfer/finalize_transfer
完成转账(OTP验证)
POST
/transfer/bulk
发起批量转账
GET
/transfer
列出转账记录
GET
/transfer/:id_or_code
获取单笔转账详情
GET
/transfer/verify/:reference
验证转账状态

Initiate Transfer

发起转账

POST /transfer
Returns status
pending
if OTP is disabled on your account, or
otp
if OTP is required.
ParamTypeRequiredDescription
source
stringYes
balance
(only option)
amount
integerYesAmount in subunits (kobo/pesewas)
recipient
stringYesRecipient code (e.g.
RCP_gd9vgag7n5lr5ix
)
reference
stringYesUnique identifier (16-50 chars, lowercase a-z, 0-9,
-
,
_
)
reason
stringNoReason for transfer (shows in customer's credit notification)
currency
stringNoCurrency code (defaults to
NGN
)
account_reference
stringNoRequired in Kenya for MPESA Paybill and Till transfers
typescript
const transfer = await paystackRequest<{
  transfer_code: string;
  status: string;
  reference: string;
  amount: number;
}>("/transfer", {
  method: "POST",
  body: JSON.stringify({
    source: "balance",
    amount: 100000,          // ₦1,000
    recipient: "RCP_gd9vgag7n5lr5ix",
    reference: `txf_${crypto.randomUUID()}`,
    reason: "Vendor payment for January",
  }),
});
// transfer.data.status → "pending" or "otp"
// transfer.data.transfer_code → "TRF_v5tip3zx8nna9o78"
POST /transfer
如果账户禁用OTP,返回状态为
pending
;如果需要OTP验证,返回状态为
otp
参数类型是否必填描述
source
string
balance
(唯一可选值)
amount
integer金额(subunits单位,如科博/比塞瓦)
recipient
string收款人代码(例如
RCP_gd9vgag7n5lr5ix
reference
string唯一标识符(16-50字符,小写a-z、0-9、
-
_
reason
string转账原因(会显示在客户的到账通知中)
currency
string货币代码(默认值为
NGN
account_reference
string肯尼亚地区MPESA Paybill和Till转账时必填
typescript
const transfer = await paystackRequest<{
  transfer_code: string;
  status: string;
  reference: string;
  amount: number;
}>("/transfer", {
  method: "POST",
  body: JSON.stringify({
    source: "balance",
    amount: 100000,          // ₦1,000
    recipient: "RCP_gd9vgag7n5lr5ix",
    reference: `txf_${crypto.randomUUID()}`,
    reason: "Vendor payment for January",
  }),
});
// transfer.data.status → "pending" or "otp"
// transfer.data.transfer_code → "TRF_v5tip3zx8nna9o78"

Finalize Transfer

完成转账(OTP验证)

POST /transfer/finalize_transfer
Required when transfer status is
otp
. Submit the OTP sent to your business phone.
ParamTypeRequiredDescription
transfer_code
stringYesTransfer code from initiate response
otp
stringYesOTP sent to business phone
typescript
await paystackRequest("/transfer/finalize_transfer", {
  method: "POST",
  body: JSON.stringify({
    transfer_code: "TRF_v5tip3zx8nna9o78",
    otp: "928783",
  }),
});
POST /transfer/finalize_transfer
当转账状态为
otp
时需要调用此接口。提交发送至企业手机号的OTP验证码。
参数类型是否必填描述
transfer_code
string发起转账接口返回的transfer_code
otp
string发送至企业手机号的OTP验证码
typescript
await paystackRequest("/transfer/finalize_transfer", {
  method: "POST",
  body: JSON.stringify({
    transfer_code: "TRF_v5tip3zx8nna9o78",
    otp: "928783",
  }),
});

Initiate Bulk Transfer

发起批量转账

POST /transfer/bulk
Batch multiple transfers in a single request. OTP must be disabled on your account to use this endpoint.
ParamTypeRequiredDescription
source
stringYes
balance
transfers
arrayYesArray of transfer objects
Each transfer object:
ParamTypeRequiredDescription
amount
integerYesAmount in subunits
recipient
stringYesRecipient code
reference
stringYesUnique reference (16-50 chars)
reason
stringNoTransfer reason
typescript
const result = await paystackRequest("/transfer/bulk", {
  method: "POST",
  body: JSON.stringify({
    source: "balance",
    currency: "NGN",
    transfers: [
      {
        amount: 20000,
        recipient: "RCP_gd9vgag7n5lr5ix",
        reference: `txf_${crypto.randomUUID()}`,
        reason: "Bonus for the week",
      },
      {
        amount: 35000,
        recipient: "RCP_m7ljkv8leesep7p",
        reference: `txf_${crypto.randomUUID()}`,
        reason: "January salary",
      },
    ],
  }),
});
// result.message → "2 transfers queued."
POST /transfer/bulk
在单个请求中批量处理多笔转账。使用此端点必须先在账户中禁用OTP
参数类型是否必填描述
source
string
balance
transfers
array转账对象数组
每个转账对象的参数:
参数类型是否必填描述
amount
integer金额(subunits单位)
recipient
string收款人代码
reference
string唯一参考号(16-50字符)
reason
string转账原因
typescript
const result = await paystackRequest("/transfer/bulk", {
  method: "POST",
  body: JSON.stringify({
    source: "balance",
    currency: "NGN",
    transfers: [
      {
        amount: 20000,
        recipient: "RCP_gd9vgag7n5lr5ix",
        reference: `txf_${crypto.randomUUID()}`,
        reason: "Bonus for the week",
      },
      {
        amount: 35000,
        recipient: "RCP_m7ljkv8leesep7p",
        reference: `txf_${crypto.randomUUID()}`,
        reason: "January salary",
      },
    ],
  }),
});
// result.message → "2 transfers queued."

List Transfers

列出转账记录

GET /transfer
ParamTypeRequiredDescription
perPage
integerNoRecords per page (default: 50)
page
integerNoPage number (default: 1)
recipient
integerNoFilter by recipient ID
from
datetimeNoStart date
to
datetimeNoEnd date
typescript
const transfers = await paystackRequest("/transfer?perPage=20&page=1");
GET /transfer
参数类型是否必填描述
perPage
integer每页记录数(默认:50)
page
integer页码(默认:1)
recipient
integer按收款人ID筛选
from
datetime起始日期
to
datetime结束日期
typescript
const transfers = await paystackRequest("/transfer?perPage=20&page=1");

Fetch Transfer

获取单笔转账详情

GET /transfer/:id_or_code
typescript
const transfer = await paystackRequest(
  `/transfer/${encodeURIComponent("TRF_v5tip3zx8nna9o78")}`
);
GET /transfer/:id_or_code
typescript
const transfer = await paystackRequest(
  `/transfer/${encodeURIComponent("TRF_v5tip3zx8nna9o78")}`
);

Verify Transfer

验证转账状态

GET /transfer/verify/:reference
Verify the status of a transfer using its reference.
typescript
const result = await paystackRequest(
  `/transfer/verify/${encodeURIComponent(reference)}`
);
// result.data.status → "success" | "failed" | "pending" | "reversed"
GET /transfer/verify/:reference
使用转账参考号验证转账状态。
typescript
const result = await paystackRequest(
  `/transfer/verify/${encodeURIComponent(reference)}`
);
// result.data.status → "success" | "failed" | "pending" | "reversed"

Transfer Flow

转账流程

typescript
// 1. Create recipient (see paystack-transfer-recipients skill)
// 2. Initiate transfer
const transfer = await paystackRequest("/transfer", {
  method: "POST",
  body: JSON.stringify({
    source: "balance",
    amount: 500000,
    recipient: "RCP_gd9vgag7n5lr5ix",
    reference: `txf_${crypto.randomUUID()}`,
  }),
});

// 3. If OTP required, finalize
if (transfer.data.status === "otp") {
  const otp = await getOTPFromUser();
  await paystackRequest("/transfer/finalize_transfer", {
    method: "POST",
    body: JSON.stringify({
      transfer_code: transfer.data.transfer_code,
      otp,
    }),
  });
}

// 4. Listen for webhooks: transfer.success, transfer.failed, transfer.reversed
typescript
// 1. Create recipient (see paystack-transfer-recipients skill)
// 2. Initiate transfer
const transfer = await paystackRequest("/transfer", {
  method: "POST",
  body: JSON.stringify({
    source: "balance",
    amount: 500000,
    recipient: "RCP_gd9vgag7n5lr5ix",
    reference: `txf_${crypto.randomUUID()}`,
  }),
});

// 3. If OTP required, finalize
if (transfer.data.status === "otp") {
  const otp = await getOTPFromUser();
  await paystackRequest("/transfer/finalize_transfer", {
    method: "POST",
    body: JSON.stringify({
      transfer_code: transfer.data.transfer_code,
      otp,
    }),
  });
}

// 4. Listen for webhooks: transfer.success, transfer.failed, transfer.reversed

Important Notes

重要注意事项

  • You can only transfer from
    balance
    — ensure your Paystack balance has sufficient funds
  • Bulk transfers require OTP to be disabled (Dashboard → Settings → Preferences)
  • Transfer references must be unique, 16-50 characters, lowercase with
    -
    and
    _
    only
  • For Kenya MPESA Paybill/Till, include
    account_reference
    in the transfer
  • Always verify transfer status via webhook (
    transfer.success
    ,
    transfer.failed
    ) rather than polling
  • 你只能从
    balance
    转账——请确保你的Paystack余额有足够资金
  • 批量转账需要禁用OTP(控制台 → 设置 → 偏好设置)
  • 转账参考号必须唯一,长度为16-50字符,仅允许小写字母、
    -
    _
  • 肯尼亚地区MPESA Paybill/Till转账需包含
    account_reference
    参数
  • 请始终通过webhook(
    transfer.success
    transfer.failed
    )验证转账状态,而非轮询