订阅快速开始
本页用于跑通“创建计划、跳转托管 Checkout、确认订阅、查询账单、取消订阅”的最小闭环。
浏览器返回 returnUrl 不代表订阅成功。返回页只展示“处理中”;商户必须通过已验签的 Subscription Event 或订阅查询接口确认状态后,才能开通权益。
接入前准备
Subscription 能力
DEEPayment 已为当前商户和当前环境开通订阅能力。
API 密钥
使用 https://panama.deepayment.com/api/v1、生产环境的 Access Key、商户 Ed25519 私钥和平台 body 公钥,见 鉴权机制。
回跳白名单
计划使用的所有 returnUrl 已按商户、环境加入白名单。
订阅通知
平台运营已为当前商户配置并启用商户级 HTTPS Webhook URL;使用同一环境的 Access Key 和 Secret Key 验证事件。
查询兜底
商户服务端可以查询 Subscription、Invoice 和 Payment Order。
测试和生产环境的密钥必须隔离。订阅事件复用当前环境的商户 API Access Key 和 Secret Key,不存在独立的订阅事件 Secret。
接入流程
- 创建 Plan
定义金额、币种和计费周期。保存返回的
planNo。 - 创建 Checkout Session
传入稳定的商户客户号、会话号和订阅号;跳转前保存平台返回的编号。
- 跳转用户
让浏览器打开
checkoutUrl,不要由商户服务端模拟托管 Checkout。 - 处理浏览器返回
浏览器到达
returnUrl时只展示处理中;用户直接关闭页面时可能没有回跳。 - 确认 Subscription
只有已验签事件或查询确认
ACTIVE后,才开通正式权益。 - 跟踪账单
Invoice 是账单事实,Payment Order 用于确认扣款结果。
- 取消订阅
提交取消请求后,只有 Subscription 确认为
CANCELED才停止权益。
以下路径都相对于:
https://panama.deepayment.com/api/v1
所有 API 请求使用公共的鉴权机制。
1. 创建 Plan
merchantPlanNo 是商户侧幂等键。MXN 的 amount 使用大于 0、最多 2 位小数的十进制字符串;currency 使用商户账户已开通的 3~4 位字母币种代码。intervalCount 必须是 1 到 12 的整数,它与 intervalUnit 共同定义扣款周期。
POST /subscription/plans
Content-Type: application/json
{
"merchantPlanNo": "merchant_plan_monthly_001",
"name": "月度会员",
"description": "月度使用权益",
"amount": "199.00",
"currency": "MXN",
"intervalUnit": "MONTH",
"intervalCount": 1,
"metadataJson": "{\"campaign\":\"summer\"}"
}
metadataJson 的 HTTP 类型是 string,字符串内容必须是 JSON Object,不能直接传嵌套 JSON Object。
只有响应中 operation.status=3(SUCCEEDED),且 Plan 状态为 2(ACTIVE)时,才能继续创建 Checkout Session。Operation 成功只代表 Plan 创建成功,不代表已有用户完成订阅。
2. 创建 Checkout Session
使用稳定业务号:
merchantSessionNo:Checkout Session 幂等键。merchantSubscriptionNo:商户订阅号。merchantCustomerNo:稳定的商户客户号。planNo或merchantPlanNo:只能选择一个传入。paymentMethod:必填支付方式,当前仅支持CARD。
POST /subscription/checkout-sessions
Content-Type: application/json
{
"merchantSubscriptionNo": "membership_user_1001",
"merchantSessionNo": "checkout_user_1001_001",
"planNo": "plan_example_001",
"merchantCustomerNo": "user_1001",
"paymentMethod": "CARD",
"email": "[email protected]",
"phone": "+525500000001",
"returnUrl": "https://merchant.example/subscription/result",
"metadataJson": "{\"source\":\"account_page\"}"
}
email 和 phone 是可选的客户联系方式快照,不控制 Checkout 处理。Session 有效期由 DEEPayment 分配并在响应中返回 expiresAt;超过该时间后不要再跳转客户。
跳转前至少保存:
merchantSessionNo <-> sessionNo <-> subscriptionNo
merchantSubscriptionNo <-> 商户自己的客户或账户
只有 operation.status=3 且存在 session.checkoutUrl 时才可跳转。这只表示托管会话创建成功,不表示用户已完成 Checkout,也不表示 Subscription 已生效。
3. 跳转用户
把 checkoutUrl 返回给浏览器并跳转。商户 Ed25519 私钥不能暴露到前端。
用户可能完成、放弃、关闭页面、断网或稍后返回。不能根据浏览器参数、页面文案、用户截图直接开通权益。
4. 处理 returnUrl
托管 Checkout 发起回跳时,浏览器经 DEEPayment 返回已登记的 returnUrl;用户直接关闭页面时不会保证回跳。
推荐结果页流程:
- 从服务端读取跳转前保存的 Subscription 关联。
- 展示“订阅确认中”。
- 由商户服务端查询 Subscription。
- 只根据服务端确认的状态更新页面。
returnUrl 不携带可信订阅结果。
5. 确认 Subscription
使用平台订阅号查询:
GET /subscription/contracts/sub_example_001
| 状态 | 商户动作 |
|---|---|
ACTIVE(3) | 开通正式订阅权益。 |
TRIALING(8) | 保留状态。商户当前不能主动创建,也不能据此开通权益。 |
PENDING_CHECKOUT / ACTIVATING | 继续展示处理中。 |
PAST_DUE | 按宽限策略处理,并查询当前账单。 |
UNPAID / CANCELED / FAILED | 不提供正式订阅权益。 |
UNKNOWN(0) | 不新开通权益,继续查询。 |
Subscription Event 是实时线索,查询接口是当前状态确认面。保留状态 TRIALING 和处理中状态没有独立事件,必须具备查询兜底。同一 subscriptionNo 只接受大于本地已处理版本的 Subscription 事件,使用 statusVersion 拒绝迟到事件。
6. 查询账单
Invoice 表达一个订阅周期的账单事实,Payment Attempt 表达一次扣款尝试,Payment Order 表达进入 DEEPayment 资金链路的订单。
GET /subscription/invoices?subscriptionNo=sub_example_001&page=1&pageSize=20
GET /subscription/invoices/inv_example_001
GET /subscription/payment-orders?subscriptionNo=sub_example_001&page=1&pageSize=20
GET /subscription/payment-orders/FP_example_001
invoice.status=PAID 表示账单已支付,Payment Order 的 status 表示扣款结果。当前 Subscription API 不公开结算状态,不能把 Invoice 或 Payment Order 支付成功当作结算完成。
Payment Order 列表当前可能出现稀疏页,因为系统先分页候选 Invoice,再过滤没有 Payment Order 的 Invoice。应按 paging 继续翻页,不能用 orders.length 判断是否遍历完成。
7. 取消订阅
POST /subscription/contracts/sub_example_001/cancel
Content-Type: application/json
{
"reason": "用户申请取消"
}
当前接口只支持渠道确认 CANCELED 后取消,不支持周期结束后取消。reason 可选;不需要填写原因时发送空 JSON Object。
如果 Subscription 已经是 CANCELED,并且此前没有记录取消 Operation,成功的幂等响应可能不包含 operation。商户必须以 subscription.status 确认取消结果。
提交请求本身不等于订阅已终止。只有取消响应、已验签事件或查询确认 CANCELED 后,商户才停止订阅权益。取消不会自动退款,也不会撤销已经确认的历史 Invoice、Payment Attempt 和 Payment Order。
HTTP 与 Operation
部分创建或变更接口以 HTTP 200 返回 operation,必须同时判断两层结果:
| 结果 | 含义 |
|---|---|
| HTTP 非 2xx | 没有返回正常业务响应。超时或 5xx 不能证明渠道侧没有发生副作用。 |
HTTP 200 + SUCCEEDED | Operation 已确认成功;仍需读取业务对象状态。 |
HTTP 200 + FAILED | Operation 已确认失败,不能按成功处理。 |
HTTP 200 + CHANNEL_UNKNOWN | 渠道结果未知,不能换新商户业务号重建。 |
HTTP 200 + PENDING / RUNNING | Operation 仍在处理。 |
幂等和恢复
- 创建 Plan:使用相同
merchantPlanNo和完全相同的请求体重试;已取得planNo时查询 Plan,只有ACTIVE才可使用。 - 创建 Checkout Session:使用相同
merchantSessionNo、merchantSubscriptionNo和完全相同的请求体重试。当前没有公开 Session 查询接口;结果长期未知或缺少checkoutUrl时,携带operationNo、traceId联系技术支持。 - 更新或归档 Plan:查询 Plan;不能确认目标变更时联系技术支持。
- 取消订阅:使用完全相同的请求重试并查询 Subscription,只有确认
CANCELED才停止权益。 - 不能因为请求超时就更换商户业务号。