Webhook 集成指南¶
触发事件¶
当交易进入以下状态时,系统将发送 Webhook 通知。每个通知会在未收到有效成功响应前,进行多次重试,直至达到最大重试次数。
Webhook 事件 | tradeType 字段值 |
requestStatus 字段值 |
描述 |
---|---|---|---|
DepositTransactionInProgress | Deposit |
InProgress |
客户已标记存款订单为已支付,当前正在进行支付确认。 |
DepositTransactionFinished | Deposit |
Finished |
存款订单已成功完成。 |
DepositTransactionFailed | Deposit |
Failed |
存款订单支付失败。失败原因可通过 message 字段获取。 |
DepositTransactionCancelled | Deposit |
Cancelled |
存款订单已取消。取消原因可通过 message 字段获取。 |
WithdrawTransactionInProgress | Withdraw |
InProgress |
提现订单正在进行中,系统正在处理客户的出款。 |
WithdrawTransactionFinished | Withdraw |
Finished |
提现订单已成功完成。 |
WithdrawTransactionFailed | Withdraw |
Failed |
提现订单支付失败。失败原因可通过 message 字段获取。 |
WithdrawTransactionCancelled | Withdraw |
Cancelled |
提现订单已取消。取消原因可通过 message 字段获取。 |
重要安全注意事项¶
收到 webhook 请求后,务必对“签名”和“时间戳”字段进行验证,以确保请求的真实性并防止外部攻击。
验证步骤:¶
- 签名验证:确保请求中的“签名”与使用密钥和有效负载生成的预期签名相匹配。
- 时间戳检查:验证“时间戳”是否在可接受的范围内,以避免重放攻击(例如,确保时间戳在当前服务器时间的几分钟内)。
这一额外的安全层可确保 webhook 请求来自可信来源,并防止未经授权或欺诈性访问。
Webhook 请求体结构¶
Webhook 请求使用如下 JSON 结构,通过 HTTP POST 方式发送,Content-Type
设为 application/json
。
请求体字段说明¶
参数名称 | 类型 | 描述 |
---|---|---|
tradeType | TradeType | 交易类型:Deposit (存款)或 Withdraw (提现) |
requestCode | String | 系统生成的唯一请求编号 |
merchantOrderNo | String | 商户自定义的唯一订单编号 |
internalOrderNo | String | 系统生成的内部订单编号 |
source | SourceFrom | 请求来源:MerchantBackend 、API_V1 、API_V2 |
clientName | String | 客户姓名 |
requestAmount | BigDecimal | 请求的交易金额 |
requestCurrency | String | 交易币种(如 MTC、CNY、HKD) |
message | String | 状态信息或其他附加说明 |
paymentMethod | PaymentOption? | 支付方式(如适用):BankCard 、WeChatPay 等 |
requestStatus | RequestStatus | 当前交易状态 |
unitPrice | BigDecimal | 所用汇率(法币/MTC) |
transactionAmount | BigDecimal | 实际交易金额(MTC) |
receivedAmount | BigDecimal | 客户实际收到或商户被扣除的金额 |
transactionFee | BigDecimal | 扣除的交易手续费 |
paymentAmount | BigDecimal | 客户实际支付的最终金额(法币) |
fiatCurrency | CurrencyCode | 法币币种代码:CNY、HKD |
Webhook 请求示例¶
存款进行中¶
POST https://{MERCHANT_CALLBACK_HOST}/{MERCHANT_CALLBACK_ROUTE}
Host: {MERCHANT_CALLBACK_HOST}
Content-Type: application/json; charset=utf-8
{
"signature": "101EECC76667EBE8A6A252FCE493CFA97CAEBE1935666CF0B2C7ADE424B64D09",
"timestamp": 1742147003264,
"data": {
"tradeType": "Deposit", <-- Current trade type is [Deposit]
"requestCode": "7a4170465c994e8fa313efada0b0e4b6",
"merchantOrderNo": "ORDER_ID_HERE",
"internalOrderNo": "AT-D-3UNT8SRUN",
"source": "API_V2",
"clientName": "USER_REAL_NAME",
"requestAmount": 3213.44,
"requestCurrency": "CNY",
"message": "",
"paymentMethod": "BankCard",
"requestStatus": "InProgress", <-- Current status is [InProgress]
"unitPrice": 7.47,
"transactionAmount": 430.18,
"receivedAmount": 417.27,
"transactionFee": 12.91,
"paymentAmount": 3213.44,
"fiatCurrency": "CNY"
}
}
存款完成¶
POST https://{MERCHANT_CALLBACK_HOST}/{MERCHANT_CALLBACK_ROUTE}
Host: {MERCHANT_CALLBACK_HOST}
Content-Type: application/json; charset=utf-8
{
"signature": "86C70FA0D62BAA24EA35D6116BFF93A66336C856495DD4E0FA22F82E1556C5AE",
"timestamp": 1742147325570,
"data": {
"tradeType": "Deposit", <-- Current trade type is [Deposit]
"requestCode": "7a4170465c994e8fa313efada0b0e4b6",
"merchantOrderNo": "ORDER_ID_HERE",
"internalOrderNo": "AT-D-3UNT8SRUN",
"source": "API_V2",
"clientName": "USER_REAL_NAME",
"requestAmount": 3213.44,
"requestCurrency": "CNY",
"message": "",
"paymentMethod": "BankCard",
"requestStatus": "Finished", <-- Current status is [Finished]
"unitPrice": 7.47,
"transactionAmount": 430.18,
"receivedAmount": 417.27,
"transactionFee": 12.91,
"paymentAmount": 3213.44,
"fiatCurrency": "CNY"
}
}
响应处理¶
服务器将根据您的系统返回值验证 webhook 的响应。
响应验证逻辑¶
- 响应必须返回以下两种之一:
- 返回的纯文本字符串等于
success
,或 - 返回的 JSON 对象中包含一个字段名为
success
且其值为true
。
- 返回的纯文本字符串等于
- 如果响应不符合上述任一条件,系统将重试发送 webhook,直至达到最大重试次数。
示例响应(纯文本)¶
示例响应(JSON)¶
Webhook 重试逻辑¶
为了确保可靠的传递,webhook 通知在回调失败时支持自动重试。以下是重试机制及其配置的说明。
为了确保最终的数据一致性,请确保您的回调接口实现了 幂等性。
回调执行流程¶
当触发 webhook 时,系统会尝试将请求发送到配置的 webhookUrl
。根据响应,系统将确定回调是否成功,或是否需要重试。
重试状态逻辑¶
- 成功:如果回调响应有效(见 回调响应验证),状态将标记为
success
,并且不会进行进一步的重试。 - 需要重试:如果响应无效且仍有重试机会,状态将标记为
NeedRetry
,并计算下次重试的时间。 - 失败:如果所有重试机会都已耗尽,状态将标记为
Failed
。
重试计划¶
重试系统采用基于失败次数的渐进延迟策略。以下是重试时间表:
尝试次数 | 重试前延迟(分钟) |
---|---|
1 | 1 |
2 | 1 |
3 | 1 |
4 | 5 |
5 | 30 |
6 | 30 |
7-16 | 60 |
- 系统允许每个 webhook 事件最多进行 16 次重试。
- 如果所有重试都失败,将不再尝试进一步的回调。