创建下发单 Try it ↗
POST /api/payouts
创建一笔下发单。需要携带 X-Request-No 防止重复提交。
所需权限: payouts:write
请求头:
x-api-key: sk-xxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
X-Request-No: <唯一请求编号>
请求正文 (Body):
{
"type": "INTERNATIONAL_TRANSFER",
"payout_details": {
"request": {
"sourceCurrency": "USD",
"destinationCurrency": "CNY",
"notes": "Q1 vendor payment"
}
},
"remits": [
{
"type": "SWIFT",
"line_number": 1,
"details": {
"amount": {
"receive_amount": 10000
},
"recipient": {
"account_type": "COMPANY",
"country_code": "CHN",
"transfer_type": "WIRE",
"bank_name": "China Construction Bank",
"bank_swift_code": "PCBCCNBJ",
"bank_address": "Beijing, China",
"account_number": "6217001234567890",
"beneficiary_name": "Example Corp Ltd"
},
"display_name": "Example Corp",
"save_as_payee": true
}
}
]
}
字段说明
顶层字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 下发单类型 |
payout_details.request | object | 是 | 下发请求信息 |
remits | array | 是 | 汇款明细列表 |
type 可选值
| 值 | 说明 |
|---|---|
INTERNATIONAL_TRANSFER | 国际汇款 |
CHINA_MAINLAND_BANK_TRANSFER | 中国大陆银行转账 |
ALIPAY_MAINLAND_TRANSFER | 中国大陆支付宝转账 |
payout_details.request 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
sourceCurrency | string | 否 | 付款货币,如 USD |
destinationCurrency | string | 否 | 收款货币,如 CNY |
notes | string | 否 | 备注 |
remits[] 字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
type | string | 是 | 汇款类型:SWIFT / CHINA_MAINLAND_BANK / ALIPAY_MAINLAND |
line_number | number | 是 | 明细行号,从 1 开始 |
details.amount.receive_amount | number | 否 | 收款金额 |
details.recipient | object | 否 | 收款方信息(与 recipient_id 二选一) |
details.recipient_id | string | 否 | 已有收款方 ID |
details.payee_id | string | 否 | 已有收款人 ID |
details.display_name | string | 否 | 显示名称 |
details.save_as_payee | boolean | 否 | 是否保存为收款人,默认 false |
收款方信息 (Recipient)
按汇款类型不同,recipient 结构有所区别。
SWIFT
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
account_type | string | 是 | PERSONAL 或 COMPANY |
country_code | string | 是 | ISO 3166-1 Alpha-3 国家代码 |
transfer_type | string | 是 | WIRE 或 WIRE_SAME_NAME |
bank_name | string | 是 | 银行名称 |
bank_swift_code | string | 是 | SWIFT 代码 |
bank_address | string | 是 | 银行地址 |
account_number | string | 是 | 账号 |
beneficiary_name | string | 是 | 收款人姓名 |
beneficiary_id_document | string[] | 否 | 身份证件文件 ID |
beneficiary_statement | string[] | 否 | 声明文件 ID |
beneficiary_business_registration | string[] | 否 | 营业执照文件 ID |
beneficiary_company_registration | string[] | 否 | 公司注册文件 ID |
中国大陆银行
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
account_type | string | 是 | PERSONAL 或 COMPANY |
bank_name | string | 是 | 银行名称 |
branch_name | string | 是 | 支行名称 |
account_number | string | 是 | 账号 |
beneficiary_name | string | 是 | 收款人姓名 |
id_number | string | 否 | 身份证号(个人账户建议提供) |
phone_number | string | 否 | 预留手机号(个人账户建议提供) |
business_license | string[] | 否 | 营业执照文件 ID |
支付宝
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
account_type | string | 是 | PERSONAL(仅支持个人) |
account | string | 是 | 支付宝账号 |
beneficiary_name | string | 是 | 收款人姓名 |
phone_number | string | 是 | 手机号 |
响应正文 (Body)
成功 200:
{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
错误响应
// 400 — 请求内容不正确
{ "success": false, "message": "请求内容不正确" }
// 400 — 业务校验失败
{ "success": false, "message": "不允许使用此收款方式" }
{ "success": false, "message": "recipient 和 recipient_id 不能同时为空" }
// 401
{ "success": false, "message": "未授权" }
// 403
{ "success": false, "message": "权限不足" }
示例代码
- curl
- Java
- Python
- PHP
- Go
- JavaScript
#!/bin/bash
API_ENDPOINT="YOUR_API_ENDPOINT"
API_KEY="YOUR_API_KEY"
REQUEST_NO="req-$(date +%s)-$RANDOM"
BODY='{
"type": "INTERNATIONAL_TRANSFER",
"payout_details": {
"request": {
"sourceCurrency": "USD",
"destinationCurrency": "CNY",
"notes": "Q1 vendor payment"
}
},
"remits": [
{
"type": "SWIFT",
"line_number": 1,
"details": {
"amount": { "receive_amount": 10000 },
"recipient": {
"account_type": "COMPANY",
"country_code": "CHN",
"transfer_type": "WIRE",
"bank_name": "China Construction Bank",
"bank_swift_code": "PCBCCNBJ",
"bank_address": "Beijing, China",
"account_number": "6217001234567890",
"beneficiary_name": "Example Corp Ltd"
},
"display_name": "Example Corp",
"save_as_payee": true
}
}
]
}'
curl -X POST "https://${API_ENDPOINT}/api/payouts" \
-H "x-api-key: ${API_KEY}" \
-H "Content-Type: application/json" \
-H "X-Request-No: ${REQUEST_NO}" \
-d "$BODY"
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.UUID;
public class CreateDisbursement {
public static void main(String[] args) throws Exception {
String apiEndpoint = "YOUR_API_ENDPOINT";
String apiKey = "YOUR_API_KEY";
String requestNo = "req-" + UUID.randomUUID();
String body = """
{
"type": "INTERNATIONAL_TRANSFER",
"payout_details": {
"request": {
"sourceCurrency": "USD",
"destinationCurrency": "CNY",
"notes": "Q1 vendor payment"
}
},
"remits": [
{
"type": "SWIFT",
"line_number": 1,
"details": {
"amount": { "receive_amount": 10000 },
"recipient": {
"account_type": "COMPANY",
"country_code": "CHN",
"transfer_type": "WIRE",
"bank_name": "China Construction Bank",
"bank_swift_code": "PCBCCNBJ",
"bank_address": "Beijing, China",
"account_number": "6217001234567890",
"beneficiary_name": "Example Corp Ltd"
},
"display_name": "Example Corp",
"save_as_payee": true
}
}
]
}
""";
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://" + apiEndpoint + "/api/payouts"))
.header("x-api-key", apiKey)
.header("Content-Type", "application/json")
.header("X-Request-No", requestNo)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}
import json
import uuid
from urllib.request import Request, urlopen
api_endpoint = "YOUR_API_ENDPOINT"
api_key = "YOUR_API_KEY"
request_no = f"req-{uuid.uuid4()}"
body = json.dumps({
"type": "INTERNATIONAL_TRANSFER",
"payout_details": {
"request": {
"sourceCurrency": "USD",
"destinationCurrency": "CNY",
"notes": "Q1 vendor payment",
}
},
"remits": [
{
"type": "SWIFT",
"line_number": 1,
"details": {
"amount": {"receive_amount": 10000},
"recipient": {
"account_type": "COMPANY",
"country_code": "CHN",
"transfer_type": "WIRE",
"bank_name": "China Construction Bank",
"bank_swift_code": "PCBCCNBJ",
"bank_address": "Beijing, China",
"account_number": "6217001234567890",
"beneficiary_name": "Example Corp Ltd",
},
"display_name": "Example Corp",
"save_as_payee": True,
},
}
],
})
req = Request(
f"https://{api_endpoint}/api/payouts",
data=body.encode("utf-8"),
headers={
"x-api-key": api_key,
"Content-Type": "application/json",
"X-Request-No": request_no,
},
method="POST",
)
with urlopen(req) as resp:
print(f"Status: {resp.status}")
print(f"Body: {resp.read().decode('utf-8')}")
<?php
$apiEndpoint = "YOUR_API_ENDPOINT";
$apiKey = "YOUR_API_KEY";
$requestNo = "req-" . uniqid();
$body = json_encode([
"type" => "INTERNATIONAL_TRANSFER",
"payout_details" => [
"request" => [
"sourceCurrency" => "USD",
"destinationCurrency" => "CNY",
"notes" => "Q1 vendor payment",
],
],
"remits" => [
[
"type" => "SWIFT",
"line_number" => 1,
"details" => [
"amount" => ["receive_amount" => 10000],
"recipient" => [
"account_type" => "COMPANY",
"country_code" => "CHN",
"transfer_type" => "WIRE",
"bank_name" => "China Construction Bank",
"bank_swift_code" => "PCBCCNBJ",
"bank_address" => "Beijing, China",
"account_number" => "6217001234567890",
"beneficiary_name"=> "Example Corp Ltd",
],
"display_name" => "Example Corp",
"save_as_payee" => true,
],
],
],
]);
$ch = curl_init("https://{$apiEndpoint}/api/payouts");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"x-api-key: {$apiKey}",
"Content-Type: application/json",
"X-Request-No: {$requestNo}",
],
CURLOPT_POSTFIELDS => $body,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "Status: {$httpCode}\n";
echo "Body: {$response}\n";
package main
import (
"fmt"
"io"
"net/http"
"strings"
"github.com/google/uuid"
)
func main() {
apiEndpoint := "YOUR_API_ENDPOINT"
apiKey := "YOUR_API_KEY"
requestNo := "req-" + uuid.NewString()
body := `{
"type": "INTERNATIONAL_TRANSFER",
"payout_details": {
"request": {
"sourceCurrency": "USD",
"destinationCurrency": "CNY",
"notes": "Q1 vendor payment"
}
},
"remits": [
{
"type": "SWIFT",
"line_number": 1,
"details": {
"amount": { "receive_amount": 10000 },
"recipient": {
"account_type": "COMPANY",
"country_code": "CHN",
"transfer_type": "WIRE",
"bank_name": "China Construction Bank",
"bank_swift_code": "PCBCCNBJ",
"bank_address": "Beijing, China",
"account_number": "6217001234567890",
"beneficiary_name": "Example Corp Ltd"
},
"display_name": "Example Corp",
"save_as_payee": true
}
}
]
}`
req, err := http.NewRequest("POST", "https://"+apiEndpoint+"/api/payouts", strings.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("x-api-key", apiKey)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Request-No", requestNo)
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
fmt.Printf("Status: %d\n", resp.StatusCode)
fmt.Printf("Body: %s\n", respBody)
}
const apiEndpoint = "YOUR_API_ENDPOINT";
const apiKey = "YOUR_API_KEY";
const requestNo = `req-${Date.now()}-${Math.random().toString(36).slice(2)}`;
const body = JSON.stringify({
type: "INTERNATIONAL_TRANSFER",
payout_details: {
request: {
sourceCurrency: "USD",
destinationCurrency: "CNY",
notes: "Q1 vendor payment",
},
},
remits: [
{
type: "SWIFT",
line_number: 1,
details: {
amount: { receive_amount: 10000 },
recipient: {
account_type: "COMPANY",
country_code: "CHN",
transfer_type: "WIRE",
bank_name: "China Construction Bank",
bank_swift_code: "PCBCCNBJ",
bank_address: "Beijing, China",
account_number: "6217001234567890",
beneficiary_name: "Example Corp Ltd",
},
display_name: "Example Corp",
save_as_payee: true,
},
},
],
});
const resp = await fetch(`https://${apiEndpoint}/api/payouts`, {
method: "POST",
headers: {
"x-api-key": apiKey,
"Content-Type": "application/json",
"X-Request-No": requestNo,
},
body,
});
console.log("Status:", resp.status);
console.log("Body:", await resp.json());