# 订阅支付

> 托管订阅与自主管理订阅的选择、合约凭证与生命周期通知、续费与升降级，以及三种接入方式的参数差异。

订阅在首次支付时建立合约，之后按计费周期重复扣款。初始订阅可以在收银台、Web SDK 或 API 直连任一接入方式完成；自主管理订阅的续费与托管订阅的升降级由商户服务端通过 API 直连发起。

## 概念与选择

计费方式由 `subscription.selfExecute` 决定，在初始订阅时选定：

- **托管订阅**（`selfExecute=1`）：Onerway 按订阅的计费设置自动发起每期扣款，每期均推送 Webhook；配置 `notificationEmail` 后，Onerway 向客户发送订阅确认与扣款邮件，客户可通过响应中的 `subscriptionManageUrl` 自助管理订阅。
- **自主管理订阅**（`selfExecute=2`）：商户自行维护计费周期，使用初始订阅返回的 `contractId` 和 `tokenId`，通过[创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction)（`subscription.requestType=1`）发起每期扣款；计费频率仅支持 `frequencyType=D`，但这不表示只能按天扣款：[字段 `subscription.frequencyPoint`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-subscription-frequencyPoint) 按天表示计费周期，例如，月度订阅可传 `30`，年度订阅可传 `365`。该值仅用于记录，实际续费扣款时间由商户自行确定。首期扣款是否由商户发起取决于 `subscription.mode`，默认 `2` 时由 Onerway 在客户授权后完成。

卡与钱包都可用于订阅，两种计费方式对 Apple Pay 与 Google Pay 同样适用；钱包订阅的发起方式与差异见 [Apple Pay](/zh/payments/online-payments/payment-methods/apple-pay#%E9%92%B1%E5%8C%85%E8%AE%A2%E9%98%85) 与 [Google Pay](/zh/payments/online-payments/payment-methods/google-pay#%E9%92%B1%E5%8C%85%E8%AE%A2%E9%98%85)。部分本地支付方式也可用于订阅，但只支持自主管理订阅，且订阅授权会单独产生一条通知，见[本地支付方式](/zh/payments/online-payments/payment-methods/local-payment-methods#%E6%9C%AC%E5%9C%B0%E6%94%AF%E4%BB%98%E6%96%B9%E5%BC%8F%E8%AE%A2%E9%98%85)。

计费周期、期数或截止日期、试用期等均在[字段 `subscription`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-subscription) 中定义，字段含义见 API Reference。客户标识通过外层 `merchantCustId` 传入（`subscription.merchantCustId` 选填，传则须一致），取值要求与[保存支付方式](/zh/payments/online-payments/scenarios/saved-payment-methods#%E6%A6%82%E5%BF%B5%E4%B8%8E%E9%80%89%E6%8B%A9)一致。

## 生命周期与通知

- **合约凭证**：初始订阅成功后，保存[订阅扣款通知](/zh/payments/api-reference/webhooks/subscription-payment)中的 `contractId` 与 `tokenId`，它们是后续扣款、查询与取消的凭证。这里的 `tokenId` 是订阅 token，与卡 token 不可混用，见[场景概览](/zh/payments/online-payments/scenarios#%E4%B8%89%E7%B1%BB-token)。
- **生命周期事件**：首购、续费、换卡、变更、取消、到期与合约状态以订阅扣款通知的[字段 `scenarios`](/zh/payments/api-reference/webhooks/subscription-payment#webhook-scenarios) 与[字段 `subscriptionStatus`](/zh/payments/api-reference/webhooks/subscription-payment#webhook-subscriptionStatus) 为准。
- **自主管理订阅续费**：服务端传入 `contractId`、`tokenId`、`merchantCustId` 与本期金额发起扣款，不传卡信息，因此续费环节没有 PCI DSS 要求。每期扣款金额由商户指定，不受首次订阅金额约束。扣款成功后收到 `scenarios=SUBSCRIPTION_RENEWAL` 的通知；对账由商户负责。
- **托管订阅续费**：Onerway 按生效中的计划金额自动扣款，未变更计划前即首次订阅时的金额。单期自动扣款的金额不能单独修改，需要调整后续金额时按下述升降级更新计划。
- **托管订阅升降级**：使用已存储的 `contractId` 与 `tokenId` 发起（`requestType=2`），生效方式由 `subscription.changeMode` 决定。更新成功后收到 `scenarios=SUBSCRIPTION_CHANGED` 的通知，变更生效后 Onerway 按新计划金额继续自动扣款。

  - `changeMode=1` 立即生效：Onerway 按当前计费周期剩余天数计算差价（`prorationMode=1`，默认），或由商户通过 `proration` 提交差价（`prorationMode=0`）。升级立即扣取差价；降级如需向客户退还差额，由商户调用[申请或取消退款](/zh/payments/api-reference/endpoints/create-or-cancel-refund)完成。
  - `changeMode=2` 下个计费周期生效：不立即扣款，适合需要提前告知客户的涨价。
- **订阅并绑卡**：托管卡订阅同时传入 `subscription.bindCard=true` 时，系统创建两笔交易并发送两条独立通知：[保存支付方式结果通知](/zh/payments/api-reference/webhooks/payment-method-result)（`txnType=BIND_CARD`）返回可用于后续 token 支付的卡 token，订阅扣款通知（`txnType=SALE`）返回订阅侧的 `contractId` 与 `tokenId`。两条通知的 `transactionId` 不同，应各自幂等处理。
- **查询与取消**：合约详情见[查询订阅详情](/zh/payments/api-reference/endpoints/query-subscription-details)，取消见[取消订阅合约](/zh/payments/api-reference/endpoints/cancel-subscription-contract)。

## 扣款失败与重试

自主管理订阅（`selfExecute=2`）由商户自行决定是否重试、重试次数与间隔，每次重试以续费扣款（`requestType=1`）通过 API 直连发起。

托管订阅（`selfExecute=1`）由 Onerway 自动重试：每期最多尝试 **3 次（含首次扣款）**，即最多重试 2 次。重试间隔取决于计费周期：

| 计费周期 | 重试间隔 |
| --- | --- |
| 每天 | 1 小时 |
| 每 2–3 天 | 12 小时 |
| 超过 3 天 | 24 小时 |

重试期间 `subscriptionStatus` 为 `pastdue`；3 次全部失败后变为 `paused`，合约仍处于启用状态（`dataStatus=1`）。两个字段可从订阅扣款通知和[查询订阅详情](/zh/payments/api-reference/endpoints/query-subscription-details)获取。

扣款重试与 Webhook 重发是两回事，后者见 [Webhook 通知](/zh/payments/get-started/webhooks#%E5%BA%94%E7%AD%94%E4%B8%8E%E9%87%8D%E8%AF%95)。

## 更换订阅用卡

仅托管订阅（`selfExecute=1`）支持换卡，且只能由客户在 `subscriptionManageUrl` 指向的订阅管理页面完成，没有对应 API。换卡结果通过 `scenarios=SUBSCRIPTION_CARD_REPLACEMENT` 的订阅扣款通知推送。

## 各接入方式的参数差异

| 接入方式 | 接口 | 关键参数 | 差异说明 | 接入指南 |
| --- | --- | --- | --- | --- |
| 收银台 | [创建收银台支付](/zh/payments/api-reference/endpoints/create-checkout-payment) | `subProductType=SUBSCRIBE`、`subscription`（`requestType=0`） | 只做初始订阅；外层 `merchantCustId` 如同时传入须与 `subscription.merchantCustId` 一致 | [收银台接入](/zh/payments/online-payments/checkout#%E8%AE%A2%E9%98%85%E6%94%AF%E4%BB%98) |
| Web SDK | [创建 SDK 交易](/zh/payments/api-reference/endpoints/sdk-create-transaction) | `subProductType=SUBSCRIBE`、`subscription`（`requestType=0`） | 只做初始订阅；服务端维护允许购买的计划映射 | [Web SDK 接入](/zh/payments/online-payments/sdk#%E4%BF%9D%E5%AD%98%E5%8D%A1%E4%B8%8E%E8%AE%A2%E9%98%85) |
| API 直连 | [创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction) | `subProductType=SUBSCRIBE`、`subscription.requestType` | 初始订阅、续费与升降级都在此接口，以 `requestType` 取 `0` / `1` / `2` 区分 | [API 直连接入](/zh/payments/online-payments/api#%E8%AE%A2%E9%98%85) |
