Skip to content

Transfer

Updated: 9/16/26, 11:08:10 AM

Description

Initiate a direct channel transfer (merchant balance to a payee, e.g. marketing rewards, reimbursements, commission settlement).

Transfer is a direct channel capability: channel (wechat/alipay/douyin) and the corresponding channelMchNo (channel merchant number) are required.

Idempotency: the idempotency key is channel + merchant transfer number (bizTransferNo) + merchant number. Duplicate requests with the same combination are rejected (noDuplicate). A failed transfer keeps the failed record — retry by resubmitting with the same bizTransferNo (the original order is reused); no need to change the number.

Request

POST /unipay/transfer

  • Auth: RSA signature (@PaymentVerify)
  • Response: DaxResult<TransferCreateResult>

Parameters

Common params same as Pay - Common Parameters. Business parameters:

ParameterTypeRequiredMaxDescription
channelstringYesTransfer channel (wechat / alipay / douyin)
channelMchNostringYes32Channel merchant number (credential assembly and channel routing)
bizTransferNostringYes100Merchant transfer number (idempotency key, unique per merchant per channel; reuse the same number to retry a failed transfer)
amountlongYesTransfer amount in cents (min 1 cent, max 100 million yuan)
titlestringNo100Transfer title
reasonstringNo200Transfer reason / remark
payeeTypestringYes32Payee account type (see table below)
payeeAccountstringYes100Payee account
payeeNamestringNo100Payee name (WeChat rules below)
attachstringNo500Merchant custom data (returned as-is in callback)
notifyUrlstringNo200Async notification URL
reportInfosobject[]NoTransfer scene report info (required for some WeChat scenes, see below)
transferScenestringNo32Transfer scene identifier (Alipay / Douyin, see below)

payeeType Codes (channel × payee type)

Corresponds to backend enum TransferPayeeTypeEnum. Supported values differ per channel:

payeeTypeDescriptionWeChatAlipayDouyin
openidWeChat / Douyin user openid
user_idAlipay user ID (starts with 2088)
open_idAlipay openid
login_nameAlipay login account (phone / email)
phoneDouyin phone number (passed via payeeAccount)

transferScene and reportInfos (channel differences)

ChanneltransferScenereportInfos
WeChatNot used — the transfer scene bound in channel merchant config appliesRequired for some scenes (e.g. marketing rewards): infoType is a fixed Chinese label in the WeChat protocol (e.g. 活动名称), infoContent is merchant-provided; left empty the channel does fallback validation
AlipayTransfer scene config ID (the scene opened on the channel side, e.g. 1001 general transfer)Not used
DouyinScene enum code (channel master data, selected by the caller, e.g. 1001)Not used

WeChat payeeName Rules

  • Amount less than 0.3 yuan: must be empty
  • Amount >= 2000 yuan: required (must match the payee's real name)
  • Otherwise: optional

Request Example

json
{
  "mchNo": "M200000001",
  "appId": "APP001",
  "reqId": "REQ20241201040",
  "reqTime": "2024-12-01 12:40:00",
  "sign": "Base64Signature",
  "channel": "alipay",
  "channelMchNo": "2088xxxxxxxxxxxx",
  "bizTransferNo": "TRANS20241201001",
  "amount": 10000,
  "title": "Commission settlement",
  "reason": "December promotion commission",
  "payeeType": "user_id",
  "payeeAccount": "2088yyyyyyyyyyyy",
  "transferScene": "1001",
  "notifyUrl": "https://your-domain.com/notify"
}

Response

DaxResult<TransferCreateResult>, the data field:

ParameterTypeDescription
transferNostringPlatform transfer number
bizTransferNostringMerchant transfer number
statusstringTransfer status (see table below; normal returns are processing or success)
confirmUrlstringConfirm-receive URL (returned only for WeChat transfers awaiting payee confirmation; send it to the payee to open in WeChat; empty when the platform gateway URL is not configured)

Transfer Status (PayFundStatusEnum)

statusDescription
initInitialized (transfer order created, not yet sent to channel)
processingProcessing (accepted by channel / WeChat awaiting payee confirmation)
successTransfer succeeded
failTransfer failed (retry by reusing the original bizTransferNo)
closeTransfer closed (only for channels supporting close, via the merchant panel)
cancelCancelled

Response Example

json
{
  "code": 0,
  "msg": "success",
  "data": {
    "transferNo": "TF2024120112345700001",
    "bizTransferNo": "TRANS20241201001",
    "status": "processing"
  },
  "sign": "Base64Signature",
  "resTime": "2024-12-01 12:40:00",
  "reqId": "REQ20241201040"
}

Best Practices

  • Retry on failure: when channel validation fails (e.g. payee info mismatch, insufficient balance), the endpoint returns an error response and the record is marked failed — resubmit with the same bizTransferNo to retry on the original order.
  • WeChat payee confirmation: after a successful initiation returns processing, the payee must open confirmUrl (or the platform transfer confirm page) to accept; unaccepted transfers are returned by the channel after timeout. Poll final status via Sync Transfer.
  • Async notification: the platform pushes the final state to notifyUrl (events transfer.success / transfer.fail / transfer.close); if no notification arrives, call Sync Transfer.
  • Query: use Query Transfer Order for the full record; failed orders include the channel-side errorMsg.

Official Website · Released under the GNU LGPL v3.0