订阅续费
无需PCI合规要求
与初始订阅设置不同,订阅续费操作不需要PCI合规,因为:
- 续费操作期间不传输敏感卡数据
- 所有操作都使用安全存储的
tokenId
和contractId
- 卡详细信息在初始订阅过程中已经代币化
介绍
订阅续费API用于处理现有订阅合约的后续扣款。此API专门用于:
自管理订阅续费:对于使用自管理订阅模式的商户,必须调用此API来使用存储的合约和代币信息处理定期付款。
订阅计划更新:对于托管订阅,此API可用于更新订阅计划(升级/降级)。
本文档涵盖所有集成方法的订阅续费,包括API、收银台和SDK订阅实现。
API请求参数
Parameter | Type | Length | Required | Signed | Description |
---|---|---|---|---|---|
billingInformation | String | / | Yes | Yes | Transaction billing information in JSON string format. See TransactionAddressfor complete structure. |
merchantCustId | String | 50 | Conditional | Yes | Unique customer identifier in merchant system. |
merchantNo | String | 20 | Yes | Yes | Merchant number assigned by |
merchantTxnId | String | 64 | Yes | Yes | Unique transaction identifier for each customer payment, generated by the merchant system. |
merchantTxnOriginalId | String | 128 | No | Yes | Master transaction ID generated by merchant for grouping related transactions. |
merchantTxnTime | String | / | No | Yes | Transaction timestamp when the merchant initiated the transaction. |
merchantTxnTimeZone | String | 64 | No | Yes | Transaction timezone offset for the merchant transaction time. |
orderAmount | String | 19 | Yes | Yes | Transaction amount in the specified currency, formatted as a decimal string. |
orderCurrency | String | 8 | Yes | Yes | Three-letter currency code according to ISO 4217 standard for the transaction amount. |
productType | String | 16 | Yes | Yes | Payment method category that determines which payment options are available to customers. See ProductTypeEnumfor all available options. |
sign | String | / | Yes | No | Digital signature string for request verification and security. Please refer to Signature for signature generation method. |
subProductType | String | 16 | Yes | Yes | Specific implementation method within the selected product type, defining how the payment is processed. See SubProductTypeEnumfor all available options. |
subscription | String | / | Conditional | Yes | |
txnOrderMsg | String | / | Yes | Yes | Transaction business information in JSON string format. See TxnOrderMsgfor complete structure. |
txnType | String | 16 | Yes | Yes | Transaction type that defines the payment operation to be performed. See TxnTypeEnumfor all available options and detailed usage scenarios. |
订阅参数
subscription
参数是包含以下字段的JSON字符串:
订阅续费流程
对于后续订阅扣款(非初始付款):
- 托管订阅:Onerway根据您的配置自动处理定期付款
- 自管理订阅:您需要调用此API来启动续费付款
Name | Type | Length | Required | Description |
---|---|---|---|---|
requestType | String | 1 | Yes | Subscription request type. See RequestTypeEnum |
contractId | String | 20 | Yes | Subscription contract ID obtained from initial subscription response. |
tokenId | String | 300 | Yes | Subscription token ID obtained from initial subscription response. |
merchantCustId | String | 40 | No | Unique identifier for the user in the merchant's system, must be consistent with the ID provided during initial subscription. |
响应
Name | Type | Description |
---|---|---|
respCode | String | Response code from |
respMsg | String | Response message from |
data | Object | Response data. Refer to object data |
集成流程
自管理订阅续费流程
订阅计划更新流程
API使用示例
自管理订阅续费示例
{
"merchantNo": "800000",
"merchantTxnId": "renewal-20241201-001",
"orderAmount": "29.99",
"orderCurrency": "USD",
"txnType": "SALE",
"subscription": "{\"contractId\":\"contract-12345\",\"tokenId\":\"token-abcdef\",\"subscriptionType\":\"SELF_MANAGED\",\"billingCycle\":\"MONTHLY\"}"
}
2
3
4
5
6
7
8
{
"respCode": "20000",
"respMsg": "Success",
"data": {
"transactionId": "1234567890123456789",
"merchantTxnId": "renewal-20241201-001",
"status": "S",
"contractId": "contract-12345",
"subscriptionStatus": "ACTIVE",
"nextBillingDate": "2025-01-01 00:00:00"
}
}
2
3
4
5
6
7
8
9
10
11
12
{
"notifyType": "SUBSCRIPTION_RENEWAL",
"transactionId": "1234567890123456789",
"merchantTxnId": "renewal-20241201-001",
"status": "S",
"contractId": "contract-12345",
"subscriptionStatus": "ACTIVE",
"renewalAmount": "29.99",
"nextBillingDate": "2025-01-01 00:00:00"
}
2
3
4
5
6
7
8
9
10
常见错误场景和解决方案
常见错误代码
错误代码 | 描述 | 解决方案 |
---|---|---|
40001 | 参数错误 | 验证请求参数是否完整且正确 |
40301 | 合约不存在 | 检查contractId是否有效 |
40302 | 代币已过期 | 重新获取有效的tokenId |
40303 | 订阅已暂停/取消 | 检查订阅状态 |
50001 | 系统错误 | 联系Onerway技术支持 |
场景1:合约ID无效
{
"respCode": "40301",
"respMsg": "Contract not found",
"data": null
}
2
3
4
5
解决方案
确保使用的contractId是有效的活跃合约ID。可以通过订阅查询API验证合约状态。
场景2:代币过期
{
"respCode": "40302",
"respMsg": "Token expired",
"data": null
}
2
3
4
5
解决方案
代币已过期,需要客户重新进行支付授权以获取新的tokenId。
实施最佳实践
- 自动重试机制:对于失败的续费,实施指数退避重试策略
- 订阅状态管理:维护本地订阅状态与Onerway状态同步
- 失败处理:制定清晰的付款失败处理流程(暂停服务、通知客户等)
- Webhook处理:确保正确处理订阅相关的webhook通知
- 金额验证:在计划更新时验证金额变化的合理性
- 日志记录:详细记录所有订阅操作以便问题排查
- 测试验证:使用测试环境充分验证续费和更新流程
商户集成检查清单
- 实现自动续费逻辑(如适用)
- 配置订阅续费失败的重试机制
- 实现订阅计划更新功能
- 设置webhook接收和处理逻辑
- 建立订阅状态监控和报警
- 验证金额计算逻辑的准确性
- 测试各种续费和更新场景
- 确认客户通知机制正常工作
- 配置适当的日志记录和监控
- 在生产环境中验证端到端流程