# 创建变更请求
商户业务系统通过创建变更请求接口,发起对用户订阅计划的升级(UPGRADE)或降级(DOWNGRADE)。变更采用两阶段确认模型:本接口仅创建变更预约并生成收银台确认链接,实际变更须由用户在收银台确认后执行。
# 接口说明
接口
请求API: /api/subscription/change/create
请求方式: POST
请求类型:application/json 或 application/x-www-form-urlencoded
# 请求参数
| 字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|---|
| 商户号 | mchNo | 是 | String(30) | M1621873433953 | 商户号 |
| 应用ID | appId | 是 | String(24) | 60cc09bce4b0f1c0b83761c9 | 应用ID |
| 订阅ID | subscriptionId | 是 | String(32) | SUB_20210618164232 | 待变更的订阅ID |
| 目标计划ID | newPlanId | 否 | String(32) | PLAN_002 | 升级/降级目标订阅计划ID,与newPlanCode二选一 |
| 目标计划编码 | newPlanCode | 否 | String(64) | PRO_MONTH | 升级/降级目标订阅计划编码,与newPlanId二选一 |
| 变更类型 | changeType | 是 | String(20) | UPGRADE | 变更类型:UPGRADE-升级 / DOWNGRADE-降级 |
| 生效方式 | effectiveType | 否 | String(20) | IMMEDIATE | 生效方式:IMMEDIATE-立即生效 / NEXT_PERIOD-下期生效。 降级可不传,默认 NEXT_PERIOD;升级必填 |
| 变更返回地址 | returnUrl | 否 | String(256) | https://merchant.com/changeReturn | 变更维度返回地址,收银台取消/补付完成后跳转商户界面。
通知地址沿用订阅级 notifyUrl |
| 请求时间 | reqTime | 是 | long | 1622016572190 | 请求接口时间,13位时间戳 |
| 接口版本 | version | 是 | String(3) | 1.0 | 接口版本号,固定:1.0 |
| 签名 | sign | 是 | String(32) | C380BEC2BFD727A4B6845133519F3AD6 | 签名值,详见签名算法 |
| 签名类型 | signType | 是 | String(32) | MD5 | 签名类型,目前只支持MD5方式 |
# 请求示例数据
{
"mchNo": "M1623984572",
"appId": "60cc09bce4b0f1c0b83761c9",
"subscriptionId": "SUB_20210618164232",
"newPlanId": "PLAN_002",
"changeType": "UPGRADE",
"effectiveType": "IMMEDIATE",
"returnUrl": "https://merchant.com/changeReturn",
"reqTime": "1622016572190",
"version": "1.0",
"signType": "MD5",
"sign": "84F606FA25A6EC4783BECC08D4FDC681"
}
目标计划传参
newPlanId 与 newPlanCode 二选一即可。示例以 newPlanId 演示,商户也可改用 newPlanCode(如 "newPlanCode": "PRO_MONTH")定位目标计划,系统将自动按当前订阅的 mchNo/appId/currency 解析为对应的 planId。
# 返回参数
| 字段名 | 变量名 | 必填 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|---|
| 返回状态 | code | 是 | int | 0 | 0-处理成功,其他-处理有误,详见错误码 |
| 返回信息 | msg | 否 | String(128) | 签名失败 | 具体错误原因 |
| 签名信息 | sign | 否 | String(32) | CCD9083A6DAD9A2DA9F668C3D4517A84 | 对data内数据签名 |
| 返回数据 | data | 否 | Object | {} | 返回变更数据 |
# data数据格式 (SubscriptionChangeRS)
| 字段名 | 变量名 | 类型 | 示例值 | 描述 |
|---|---|---|---|---|
| 变更记录ID | changeId | String | CHG_20210618164201 | 变更记录唯一ID,用于后续确认/查询/对账 |
| 差额 | diffAmount | Long | 1500 | 差额,单位分,新计划与原计划折算后的差额;立即生效升级时正数表示确认时需补付 |
| 币种 | currency | String | USD | 订阅币种,配合 diffAmount 展示金额 |
| 收银台确认链接 | confirmUrl | String | https://cashier.enjoypayment.com/change/CHG_xxx/TOKEN | 引导用户确认变更的收银台链接,1小时后过期 |
| 变更状态 | changeState | Integer | 0 | 0-待生效(PENDING), 1-已生效(EFFECTIVE), 2-已取消(CANCELED), 3-失败(FAILED) |
| 被替换旧变更ID | replacedChangeId | String | CHG_20210618160001 | 创建时存在未确认旧变更被自动替换时返回,供商户对账 |
# 返回示例数据
{
"code": 0,
"msg": "SUCCESS",
"data": {
"changeId": "CHG_20210618164201",
"diffAmount": 1500,
"currency": "USD",
"confirmUrl": "https://cashier.enjoypayment.com/change/CHG_20210618164201/a1b2c3d4-e5f6",
"changeState": 0
},
"sign": "F4DA202C516D1F33A12F1E547C5004FD"
}
# 业务规则
注意
- 订阅状态:仅
活跃(ACTIVE)或逾期(OVERDUE)状态的订阅可发起变更。 - 目标计划:必须为已发布(PUBLISHED)状态,且与当前订阅属于同一应用(appId)、同一商户(mchNo)、同一币种(currency)。不允许变更为当前相同的计划。
- 升级(UPGRADE):
effectiveType必填。- 立即生效(IMMEDIATE):距当前周期结束不足 24 小时禁止立即变更;差额必须大于 0;订阅须已绑定支付方式(paymentMethodToken),确认后将创建补付订单扣款,扣款成功后切换计划。
- 下期生效(NEXT_PERIOD):确认后写入待生效计划,在下次续费扣款成功时切换。
- 升级目标计划金额须高于当前计划(含首期与落点档双重校验)。
- 降级(DOWNGRADE):仅支持下期生效(NEXT_PERIOD),传 IMMEDIATE 将被拒绝;降级目标计划金额须低于当前计划。
- 跨订阅计划占用:系统会校验目标计划是否已被同一用户的其他订阅占用(含已激活订阅、未确认变更、已确认下期生效),存在占用时拒绝变更。
- 并发替换:若该订阅存在未确认的待生效变更,新变更将自动取消并替换旧变更(返回
replacedChangeId,旧变更收到SUBSCRIPTION_CHANGE_CANCELED通知);若存在已确认的立即生效变更(资金在途),则拒绝创建。
# 变更流程
1. 商户调用 [创建变更请求] → 获得 changeId + confirmUrl
2. 引导用户打开 confirmUrl(收银台确认页)
├─ 用户确认 → 调用 [确认变更] 执行实际变更
└─ 用户取消 → 调用 [收银台取消变更] 取消预约
3. 变更结果通过 [订阅通知] 异步回调商户
提示
确认链接有效期为 1 小时,过期后需重新发起变更请求。未确认的变更将在过期后由系统自动清理。