跳到主要内容

Payin 收款对接指南

本文档面向商户开发者,说明如何创建 Payin 收款订单、引导用户付款、处理订单 Webhook,并通过查询接口确认最终结果。

Payin 主流程分为三步:

  1. 创建收款订单:商户调用 POST /payment/acquiring/orders 创建订单。
  2. 用户完成付款:商户将用户引导到 checkout_url,用户选择币种和网络并付款。
  3. 确认结果:商户通过 acquiring.order.updated Webhook 接收订单状态变化,也可以调用查询接口做补偿确认和对账。

一页摘要

最小 API 集合:

  1. POST /payment/acquiring/orders
  2. GET /payment/acquiring/orders/{order_id}

补充 API:

  1. GET /payment/acquiring/orders/{order_id}/payments:查询该订单下的支付记录
  2. POST /payment/acquiring/orders/{order_id}/close:提前关闭未完成订单

最小 Webhook:

  1. acquiring.order.updated:订单状态变化

如果商户需要接收 Webhook,创建订单时应传入有效的 notify_webhook_id。该 webhook 必须处于启用状态,并订阅 acquiring.order.updatedacquiring.payment.updatedacquiring.*

接入前准备

正式创建收款订单前,先确认这些信息:

项目为什么需要
API Key 权限创建订单需要 acquiring 创建权限,查询订单需要 acquiring 读取权限,关闭订单需要 acquiring 关闭权限。
收款方式确认当前账号可用的支付 token,例如 TRON_USDTBSC_USDT
商户订单号每笔都必须传 out_trade_no,并在商户系统内保持唯一。
Webhook 配置需要先在商户后台创建并启用 webhook,然后每次创建订单都传 notify_webhook_id
商户侧存储至少保存 out_trade_noorder_idstatuscheckout_urlexpire_time

确认可用支付方式

首次接入或新增收款路线时,商户需要先知道用户可以用哪些币种和网络付款。

支付 token ID 表示“网络 + 币种”的组合,格式通常是:

<NETWORK>_<CURRENCY>

例如:

支付 token ID含义用户实际支付
TRON_USDTTRON 网络上的 USDT用户通过 TRON 转 USDT
ETH_USDTEthereum 网络上的 USDT用户通过 Ethereum 转 USDT
BSC_USDTBNB Smart Chain 网络上的 USDT用户通过 BSC 转 USDT
ETH_USDCEthereum 网络上的 USDC用户通过 Ethereum 转 USDC
BASE_USDCBase 网络上的 USDC用户通过 Base 转 USDC

需要确认:

你需要的值示例用在请求哪里
订单计价币种USDorder_currency
支付 token IDTRON_USDTBSC_USDTallowed_pay_currencies,不传则使用系统默认可用 token
Webhook IDwebhook_xxxnotify_webhook_id

这些值通常由 Beyounger 或商户后台配置确认。商户创建订单时可以把允许用户支付的 token ID 放入 allowed_pay_currencies;如果不传,则使用系统为该账号配置的默认可用 token。

当前常见 token ID:

币种可用 token ID
USDTTRON_USDTETH_USDTBSC_USDTMATIC_USDTARBITRUM_USDTSOL_USDT
USDCETH_USDCBASE_USDCBSC_USDCMATIC_USDCARBITRUM_USDCSOL_USDC

建议:

  1. 只把商户希望开放给用户的 token ID 放进 allowed_pay_currencies
  2. 如果只想让用户用 TRON USDT 支付,就传 ["TRON_USDT"]
  3. 如果允许用户在多个网络支付 USDT,可以传 ["TRON_USDT", "ETH_USDT", "BSC_USDT"]
  4. 不要只传 USDTUSDC,必须传完整 token ID。
  5. 不要把未开通或不准备支持的 token ID 放进订单。

核心流程图

第一步:创建收款订单

接口

POST /payment/acquiring/orders

商户通过该接口创建一笔收款订单。创建成功后,Beyounger 返回 checkout_url,商户前端应将用户跳转到该地址完成支付。

请求头

Authorization: Bearer <api_key_jwt>
Content-Type: application/json
Accept: application/json

核心请求参数

字段是否必填说明
out_trade_no必填商户订单号,必须每笔唯一
order_currency必填订单计价币种,当前支持 USD
order_amount必填订单金额,必须大于 0
allowed_pay_currencies可选限制用户可支付的 token 列表,例如 ["TRON_USDT", "BSC_USDT"];不传则使用系统默认可用 token
expire_seconds必填订单有效期,范围 6010800
underpay_tolerance必填少付容差,必须大于等于 0
notify_webhook_id必填接收订单状态通知的 webhook ID
redirect_url可选用户完成支付后跳转地址,支持 HTTPS 绝对地址或同源相对路径
logo_url可选收银台展示的商户 Logo,必须是 HTTPS 地址
remark可选商户备注

创建订单示例

{
"out_trade_no": "payin_202606190001",
"order_currency": "USD",
"order_amount": "20.00",
"allowed_pay_currencies": ["TRON_USDT", "BSC_USDT"],
"expire_seconds": 1800,
"underpay_tolerance": "0",
"notify_webhook_id": "webhook_xxx",
"redirect_url": "https://merchant.example.com/payment/result",
"remark": "Order payin_202606190001"
}

成功响应

{
"code": 0,
"message": "OK",
"data": {
"order": {
"order_id": "acq_order_xxx",
"platform_order_no": "P202606190001",
"out_trade_no": "payin_202606190001",
"status": "pending",
"checkout_type": "default",
"order_currency": "USD",
"order_amount": "20.00",
"allowed_pay_currencies": ["TRON_USDT", "BSC_USDT"],
"pay_amount": "20.00",
"paid_amount_total": "0",
"remaining_amount": "20.00",
"underpay_tolerance": "0",
"checkout_url": "https://api.example.com/payment/checkout/acq_order_xxx",
"notify_webhook_id": "webhook_xxx",
"expire_time": 1781789497,
"created_at": 1781787697,
"updated_at": 1781787697
}
}
}

必须保存:

  1. out_trade_no
  2. order_id
  3. status
  4. checkout_url
  5. allowed_pay_currencies,如果请求中有传
  6. pay_amount
  7. expire_time

创建成功不代表用户已经付款,只代表收款订单已经创建。

第二步:用户付款和 Webhook 通知

商户前端应跳转到 checkout_url,或在自己的页面展示该地址。用户完成付款后,Beyounger 会根据链上或服务商结果更新订单状态。

如果创建订单时传了有效的 notify_webhook_id,订单达到需要通知的状态时,Beyounger 会发送:

acquiring.order.updated

商户收到后应:

  1. 校验 Webhook 签名
  2. event_idbusiness_id 做幂等
  3. 读取 data.order_iddata.out_trade_nodata.status
  4. 必要时调用 GET /payment/acquiring/orders/{order_id} 确认最新状态
  5. 更新商户订单状态

Webhook Payload 示例

{
"event_id": "acqevt_acq_order_xxx",
"event_type": "acquiring.order.updated",
"business_type": "acquiring",
"business_id": "acq_order_xxx",
"occurred_at": 1781789497,
"version": "v1",
"data": {
"provider_event": "transaction_confirmed",
"anomaly_tag": "",
"order_id": "acq_order_xxx",
"platform_order_no": "P202606190001",
"out_trade_no": "payin_202606190001",
"previous_status": "pending",
"status": "completed",
"status_changed": true,
"amount_changed": true,
"order_currency": "USD",
"pay_amount": "20.00",
"paid_amount_total": "20.00",
"remaining_amount": "0",
"overpaid_amount": "0",
"underpay_tolerance": "0",
"expire_time": 1781789497,
"updated_at": 1781789497
}
}

核心字段:

字段说明
event_idWebhook 事件 ID
event_type固定为 acquiring.order.updated
business_type固定为 acquiring
business_id等于 order_id
data.out_trade_no商户订单号
data.status最新订单状态
data.paid_amount_total已支付总金额
data.remaining_amount剩余应付金额
data.anomaly_tag异常标记,例如过期后到账

数币收单状态说明

数币收单不是简单的“成功/失败”模型。订单状态由该订单下的支付记录聚合而来,核心判断依据是已确认到账金额、订单应付金额、少付容差和订单是否过期。

商户处理 Webhook 时建议按下面规则理解:

Webhook 中的 data.status是否最终状态说明商户建议
partial_paid已有部分金额完成确认,但确认金额还没有达到 pay_amount - underpay_tolerance订单不要标记成功,继续等待后续到账或按商户规则提示用户补款
completed已确认金额加上少付容差后满足订单应付金额标记商户订单支付成功,开始发货、入账或开通服务
underpaid订单过期时已有确认金额,但金额不足且超过少付容差标记异常订单,进入人工处理、补款或退款流程
expired订单过期且没有确认到账金额标记订单过期,不再让用户继续使用该订单付款

同时注意:

  1. pendingconfirmingprocessing 更常见于查询接口或支付记录中,通常表示还在等待用户付款、链上广播或确认数。
  2. paid_amount_total 是已确认到账金额,不是用户可能已经广播但尚未确认的金额。
  3. remaining_amount 是基于已确认到账金额计算的剩余金额。
  4. overpaid_amount 大于 0 表示用户多付,商户需要按业务规则处理多付金额。
  5. anomaly_tag=expired_paid 表示订单过期后又检测到到账,商户不要自动按正常成功处理,应进入异常流程。
  6. 同一个订单可能有多笔支付记录,订单状态以聚合后的 data.status 为准。

第三步:查询订单状态

接口

GET /payment/acquiring/orders/{order_id}

调用场景:

  1. 创建后查看初始状态
  2. 收到 Webhook 后确认最新状态
  3. Webhook 超时或丢失时补偿查询
  4. 财务或运营对账

状态判断

status含义商户处理
pending等待用户付款保持订单待支付
processing已检测到支付,处理中等待后续状态
confirming等待链上确认等待确认完成
partial_paid已部分支付继续等待或按商户规则处理
completed支付完成标记商户订单支付成功
underpaid少付且超过容差标记异常,进入人工或退款流程
expired订单已过期标记订单过期;如果后续到账,关注 anomaly_tag

最终成功以 status=completed 为准。不要只根据前端跳转结果或创建订单响应判断支付成功。

查询支付记录

接口

GET /payment/acquiring/orders/{order_id}/payments

这个接口用于排查和对账,不是最小接入必须接口。常见用途:

  1. 查看用户选择的支付币种和网络
  2. 查看收款地址
  3. 查看 tx_hash
  4. 排查少付、多付、币种或网络不匹配

支付记录常见状态:

payment.status含义
pending等待支付
processing已收到支付,处理中
confirming等待确认
completed该笔支付完成
failed支付失败
late过期后到账
expired支付记录过期

关闭订单

接口

POST /payment/acquiring/orders/{order_id}/close

如果商户订单已取消、已换单,或不希望用户继续付款,可以关闭收款订单。

{
"reason": "merchant_order_cancelled"
}

关闭订单只适用于未完成订单。订单已经支付成功后,不应通过关闭接口处理。

常见问题

创建订单成功是否代表支付成功?

不是。创建成功只代表收款订单已创建。最终支付结果看 acquiring.order.updated Webhook 或查询接口。

Payin 是否支持单笔 notify_url

当前创建订单接口使用 notify_webhook_id 指定回调配置,不使用单笔 notify_url。商户需要先创建 webhook,再在订单中传 notify_webhook_id

allowed_pay_currencies 怎么传?

如果商户想限制用户只能使用指定币种或网络支付,就传 allowed_pay_currencies。如果不传,系统会使用该账号默认可用的支付 token。

传入时使用 Beyounger 或商户后台确认过的支付 token ID。token ID 是“网络 + 币种”,例如 TRON_USDT 表示 TRON 网络上的 USDT。

示例:

{
"allowed_pay_currencies": ["TRON_USDT", "BSC_USDT"]
}

Webhook 和查询接口哪个为准?

Webhook 用于实时通知,查询接口用于确认和补偿。建议两者都接入。

开发资源

  1. API Reference
  2. OpenAPI JSON
  3. Postman Collection
  4. Getting Started
  5. Authentication