PAYMENTS / OVERVIEW

支付订单概览

不想自己管理充值地址和到账判定?用支付订单:商户下一笔单,派付分配专属收款地址、托管付款页、判定足额 / 少付 / 多付 / 过期,并通过回调告诉你结果。

收款流程

第 1 步

商户下单

服务端调 POST /api/v1/payment/orders,拿到 checkoutUrl、收款地址与应付金额。

第 2 步

跳转托管付款页

把付款人重定向到 checkoutUrl。付款页展示金额、地址、二维码与倒计时,商户无需自建收银台。

第 3 步

付款人链上转账

付款人向订单专属收款地址转账。系统扫块确认后按金额累计到订单上。

第 4 步

回调通知商户

订单进入「已支付 / 部分支付 / 已过期 / 已取消」时,派付向商户回调地址推送 payment_order.* 事件;商户也可随时按单号主动查询。

商户服务端 ──POST /api/v1/payment/orders──▶ 派付
     │                                         │ 返回 checkoutUrl / payAddress / payAmount
     ├──重定向付款人──▶ 托管付款页 /checkout/{checkoutToken}
     │                       │ 付款人链上转账到 payAddress
     │                       ▼
     │              派付扫块确认 → 累计 paidAmount → 状态流转
     ◀──POST 回调 payment_order.paid / partial_paid / expired / cancelled──┘
     └──(可选)GET /api/v1/payment/orders/by-app-order-no 主动查询

下单方式

开放 API 下单时,币种由商户指定,金额有两种给法:

  • 直接给币数:传 payAmount(可配 payCurrency / chainCode / chainTokenId),系统不报价,付款人按这个币数付。
  • 给法币金额:不传 payAmount,传 fiatCurrency + fiatAmount,系统按汇率换算出 payAmount 并锁价,响应里带汇率快照(rate / rateSource / rateExpireTime 等)。

币种不指定时,按应用已启用的支付代币(可用 chainCode / chainId 缩小范围、payCurrency 按符号匹配)取第一个匹配项。

第三种:法币金额 + 付款人自选币种——传 payerSelectsCurrency=true 与 fiatCurrency + fiatAmount(可用 allowedChainTokenIds 限定可选币种),订单先处于 AWAITING_CURRENCY,付款人在付款页选币后才锁价、分配地址。

自选币种的开放 API 参数随后端新版本上线

payerSelectsCurrency / allowedChainTokenIds 是新增参数。在此之前,自选币种订单可由商户后台创建: 开具发票时不指定币种,或通过收款链接由付款人建单。

锁价与过期

  • 订单有效期:expireTime 优先;不传则 expireMinutes;都不传默认 30 分钟。
  • 按法币下单时,有效期跟随锁价时效缩短:报价的 rateExpireTime = 锁价时间 + 报价有效秒数 (汇率配置的 quoteTtlSeconds,未配置默认 300 秒)。 若它早于订单有效期,接口下单的订单 expireTime 会被截短到 rateExpireTime。后台发票不受此限制。
  • 换算:payAmount = fiatAmount ÷ rate,有滑点配置时再乘以 (1 + slippageBps/10000),最后按代币小数位向上取整。
  • 汇率来源(rateSource):THIRD_PARTY(第三方实时报价)/ LOCAL_TABLE(本地配置表)/ MOCK。实时报价失败时回落本地配置,并如实标为 LOCAL_TABLE。

付款窗口与重新报价(仅付款人自选币种的订单)

  • 付款人选币后按实时汇率锁价、分配独立收款地址,订单转 PENDING,并开启付款窗口:默认 30 分钟(服务端配置 payment-window-minutes),且不超过订单 expireTime。
  • 窗口结束、未收到任何款项、订单仍未过期时可以重新报价:收款地址不变,按新汇率更新应付金额,窗口重新计时。
  • 商户 API 下单的订单没有付款窗口(paymentWindowExpireTimeMillis 为空),也不能重新报价。

订单状态

status(PaymentOrderStatusEnum)

AWAITING_CURRENCY
待选择币种 optional
只有法币金额、还没有币种和地址。仅出现在付款人自选币种的订单(后台发票未指定币种、收款链接建的单)。付款人在付款页选币后转 PENDING;到 expireTime 仍未选币转 EXPIRED。
PENDING
待支付 optional
已锁定币种、应付金额与收款地址,等待付款。
PARTIAL_PAID
部分支付 optional
已到账但累计金额小于应付金额。首次进入时开始补款计时(应用支付设置「最长补款分钟」,默认 60 分钟);补足转 PAID,补款超时转 EXPIRED(exceptionReason=UNDERPAID_TIMEOUT,待人工处理)。
PAID
已支付 optional
累计到账 ≥ 应付金额。多付时仍为 PAID,同时 exceptionReason=OVERPAID、overpaidAmount 为多付部分。终态。
LATE_PAID
过期后到账 optional
订单过期后才收到款项,且应用未开启「过期到账自动完成」。exceptionReason=LATE_PAYMENT,handlingStatus=PENDING,同时推送 payment_order.late_paid 回调(新增事件,随后端新版本上线;此前版本不推送),需商户在后台人工处理。
EXCEPTION
异常待处理 optional
到账命中 KYT 高风险(exceptionReason=RISK_HIGH)。不推送回调,需人工处理。
EXPIRED
已过期 optional
待支付 / 待选币订单到 expireTime 未付款,或部分支付补款超时。过期后仍可能收到迟到款,见下文「异常单」。
CANCELLED
已取消 optional
商户在后台取消。只有「待支付 / 待选择币种」且未收到任何款项的订单可以取消;开放 API 目前没有取消接口。终态。
AWAITING_CURRENCY ──选币──▶ PENDING ──足额──▶ PAID
        │                      │ ──不足──▶ PARTIAL_PAID ──补足──▶ PAID
        │                      │                 └──补款超时──▶ EXPIRED (UNDERPAID_TIMEOUT)
        │                      │ ──KYT 高风险──▶ EXCEPTION
        ├──到期──▶ EXPIRED ◀───┘ 到期
        │                 └──迟到款──▶ LATE_PAID(或开启自动完成时 → PAID)
        └──后台取消──▶ CANCELLED ◀── PENDING(未收到款时)
LATE_PAID / EXCEPTION ──后台人工「标记已支付」──▶ PAID

异常单

exceptionReason 记录异常原因,handlingStatus 记录人工处理进度。异常单在商户后台处理,开放 API 只读。

exceptionReason(PaymentOrderExceptionReasonEnum)

OVERPAID
多付 optional
订单仍为 PAID。handlingStatus 取决于应用支付设置的多付处理方式:人工审核 → PENDING,否则 → RESOLVED(默认)。
UNDERPAID_TIMEOUT
少付补款超时 optional
部分支付后补款超时,订单转 EXPIRED,handlingStatus=PENDING。
LATE_PAYMENT
过期后到账 optional
见 LATE_PAID。若应用开启「过期到账自动完成」,迟到款直接按正常付款累计,可直接变为 PAID 并推送 payment_order.paid。
RISK_HIGH
KYT 高风险 optional
订单转 EXCEPTION,同时回填 riskLevel / riskReason / riskSnapshot。
WRONG_CHAIN
错链 optional
同一收款地址在订单以外的链上收到转账。只记异常、标 exceptionReason 与 handlingStatus=PENDING,不改变订单状态,也不累计金额。
WRONG_TOKEN
错币 optional
订单地址收到了非订单币种。同上,只记异常。
WRONG_MEMO
错 Memo/Tag optional
Memo 链上金额打到了收款地址但 memo 不一致。同上,只记异常。
UNKNOWN_PAYMENT
未知支付 optional
枚举中存在,当前代码未见写入路径。

handlingStatus(PaymentOrderHandlingStatusEnum)

NONE
无需处理 optional
正常订单。
PENDING
待人工处理 optional
需要商户在后台处理(标记已支付 / 忽略等)。
PROCESSING
处理中 optional
RESOLVED
已处理 optional
后台处理完成;人工「标记已支付」会把订单置为 PAID 并补推 payment_order.paid(该订单尚未推过已支付回调时)。
IGNORED
已忽略 optional

以回调或查询结果为准,不要信付款页

给业务发货 / 入账只认服务端拿到的结果:验签通过的 payment_order.paid 回调,或 按单号查询 返回的 status=PAID。

订单来源

订单的 source:API(商户 API 下单)/ INVOICE(商户后台发票)/ PAYMENT_LINK(收款链接)。 三种来源共用同一套状态机与回调。

发票

发票是商户后台功能,无需开发:在后台填写金额(可只填法币金额、不指定币种)、标题和说明即可生成付款链接发给付款人。 付款人打开的就是同一个托管付款页,订单的 source=INVOICE,到账同样推送回调。

下一步