7.1 创建订阅订单【未授权拦截通过,待登录态联调】

POST /tieup/api/v1/subscriptions

请求头:

Idempotency-Key: subscription_10001_20260602143000_x7f9k2

请求体:

{
  "artist_id": 1,
  "subscription_plan_code": "month_30",
  "sub_type": "month",
  "subscription_action": "initial",
  "payment_method": "wechat",
  "is_auto_renew": 2
}

请求参数:

参数 类型 必填 说明
artist_id integer 目标艺人 ID
subscription_plan_code string 必须等于目标艺人在定价设置中当前选择的档位代码,且该代码在当前渠道、平台和市场可用
sub_type string 订阅周期类型:month=月订阅,year=年订阅
subscription_action string 订阅动作:initial=首订,renewal=续订;不传、传 null 或空字符串时默认 initial
payment_method string wechat=微信,alipay=支付宝,apple_iap=苹果内购
is_auto_renew integer 1=自动续订,2=单次订阅;Apple 必须显式传 1,微信/支付宝未传时默认 2
return_url string 仅微信 H5、支付宝 WAP 支持的支付完成回跳地址;完整 HTTP(S) 地址,最长 2048 字符。非空值优先于后台配置,未传、null、空字符串或纯空白时使用后台配置;APP、Apple IAP 传入会返回 422

首次创建或相同购买意图恢复成功响应:

{
  "code": 200,
  "message": "成功",
  "data": {
    "recharge_no": "RC202606060001",
    "order_no": "TO202606060001",
    "transaction_no": "TP202606060001",
    "artist_id": 1,
    "subscription_plan_code": "month_30",
    "payment_amount": "30.00",
    "paid_amount": "0.00",
    "currency": "CNY",
    "subscription_days": 30,
    "subscription_action": "initial",
    "is_auto_renew": 2,
    "status": 1,
    "payment": {
      "order_no": "TO202606060001",
      "transaction_no": "TP202606060001",
      "order_status": 1,
      "payment_status": 1,
      "payment_method": "wechat",
      "provider_code": "wechat_app",
      "payment_account_id": 1,
      "payment_amount": "30.00",
      "currency": "CNY",
      "pay_params": {
        "trade_type": "APP",
        "appid": "wx1234567890",
        "partnerid": "1900000001",
        "prepayid": "wx_prepay_id",
        "package": "Sign=WXPay",
        "noncestr": "a1b2c3d4",
        "timestamp": "1785128400",
        "sign": "base64-signature",
        "sign_type": "RSA"
      }
    },
    "reused_order": true,
    "payment_expires_at": "2026-07-27 15:30:00",
    "remaining_seconds": 1020
  }
}

年订阅请求示例:

{
  "artist_id": 1,
  "subscription_plan_code": "month_30",
  "sub_type": "year",
  "subscription_action": "initial",
  "payment_method": "apple_iap",
  "is_auto_renew": 1
}

Apple 年订阅响应示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "recharge_no": "RC202606060002",
    "order_no": "TO202606060002",
    "transaction_no": "TP202606060002",
    "artist_id": 1,
    "subscription_plan_code": "month_30",
    "payment_amount": "288.00",
    "paid_amount": "0.00",
    "currency": "CNY",
    "subscription_days": 365,
    "subscription_action": "initial",
    "is_auto_renew": 1,
    "status": 1,
    "payment": {
      "order_no": "TO202606060002",
      "transaction_no": "TP202606060002",
      "order_status": 1,
      "payment_status": 1,
      "payment_method": "apple_iap",
      "provider_code": "apple_iap",
      "payment_account_id": 1,
      "payment_amount": "288.00",
      "currency": "CNY",
      "pay_params": {
        "bundle_id": "com.tieup.app",
        "product_id": "com.tieup.sub.year288",
        "application_username": "550e8400-e29b-41d4-a716-446655440000",
        "sandbox": false,
        "requires_client_receipt_confirm": true,
        "storekit": "storekit1"
      }
    },
    "reused_order": false,
    "payment_expires_at": "2026-07-27 15:30:00",
    "remaining_seconds": 1800
  }
}

响应字段:

字段 类型 说明
recharge_no string 订阅充值业务单号
order_no string 平台订单号
transaction_no string 支付流水号
artist_id integer 订阅艺人 ID
subscription_plan_code string 订阅档位代码
payment_amount string 订单金额,单位元,固定两位小数
paid_amount string 已支付金额,单位元,固定两位小数
currency string 币种,当前为 CNY
subscription_days integer 本次订阅天数
subscription_action string 归一化后的订阅动作:initial=首订,renewal=续订
is_auto_renew integer 1=自动续订,2=不自动续订
status integer 订阅充值业务单状态
payment object 本次支付信息
payment.order_no string 平台订单号
payment.transaction_no string 支付流水号
payment.order_status integer 订单状态
payment.payment_status integer 支付流水状态:0=创建,1=预支付成功,2=支付成功,3=支付失败,4=已关闭,5=已退款
payment.payment_method string wechat=微信,alipay=支付宝,apple_iap=苹果内购
payment.provider_code string 接入产品:wechat_app、wechat_h5、alipay_app、alipay_wap、apple_iap
payment.payment_account_id integer 实际命中的支付账号 ID
payment.payment_amount string 支付金额,单位元,固定两位小数
payment.currency string 币种
payment.pay_params object 客户端拉起支付所需参数
payment.pay_params.trade_type string APP、MWEB 或 WAP
payment.pay_params.pay_url string H5 支付跳转地址,仅 MWEB/WAP 返回
payment.pay_params.h5_url string 微信返回的原始 H5 地址,仅 MWEB 返回
payment.pay_params.return_url string 本次支付最终使用的完成回跳地址,仅微信 H5、支付宝 WAP 返回;客户端非空值优先,否则为后台配置
reused_order boolean 是否复用了当前 Tieup 账号的相同购买意图待支付订单
payment_expires_at string 支付参数失效时间
remaining_seconds integer 支付窗口剩余秒数,最小为 0

H5 微信订阅请求完整示例:

POST /tieup/api/v1/subscriptions
Authorization: Bearer <access_token>
X-App-Platform: h5
Idempotency-Key: subscription_h5_10001_20260731143000_x7f9k2
Content-Type: application/json
{
  "artist_id": 1,
  "subscription_plan_code": "month_30",
  "sub_type": "month",
  "subscription_action": "initial",
  "payment_method": "wechat",
  "is_auto_renew": 2,
  "return_url": "https://h5.example.com/payment/result?source=subscription"
}

H5 微信订阅响应完整示例:

{
  "code": 200,
  "message": "成功",
  "data": {
    "recharge_no": "RC202607150001",
    "order_no": "TO202607150001",
    "transaction_no": "TP202607150001",
    "artist_id": 1,
    "subscription_plan_code": "month_30",
    "payment_amount": "30.00",
    "paid_amount": "0.00",
    "currency": "CNY",
    "subscription_days": 30,
    "subscription_action": "initial",
    "is_auto_renew": 2,
    "status": 1,
    "payment": {
      "order_no": "TO202607150001",
      "transaction_no": "TP202607150001",
      "order_status": 1,
      "payment_status": 1,
      "payment_method": "wechat",
      "provider_code": "wechat_h5",
      "payment_account_id": 3,
      "payment_amount": "30.00",
      "currency": "CNY",
      "pay_params": {
        "trade_type": "MWEB",
        "pay_url": "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx_example&package=123&redirect_url=https%3A%2F%2Fh5.example.com%2Fpayment%2Fresult%3Fsource%3Dsubscription",
        "h5_url": "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx_example&package=123",
        "return_url": "https://h5.example.com/payment/result?source=subscription"
      }
    },
    "reused_order": false,
    "payment_expires_at": "2026-07-27 15:30:00",
    "remaining_seconds": 1800
  }
}

H5 回跳地址幂等规则:

  • 支付参数已生成后,同一订单重试未传 return_url 时沿用首次地址;显式传入与首次地址完全相同(去除首尾空白后比较)时复用首次支付参数。
  • 显式传入不同地址,或历史支付流水没有 pay_params.return_url 快照但本次传入地址时,返回 422data.error_code = payment_return_url_conflict;服务端不会创建新流水或重新请求微信、支付宝。
  • 客户端地址允许任意完整 HTTP(S) 域名,客户端必须只提交可信业务页面,不能使用用户输入直接拼接不可信跳转目标。

回跳地址冲突完整响应示例:

{
  "code": 422,
  "message": "return_url与首次支付请求不一致",
  "data": {
    "error_code": "payment_return_url_conflict"
  }
}

原订单正在关闭完整响应示例:

{
  "code": 422,
  "message": "原待支付订单正在关闭,请稍后重试",
  "data": {
    "error_code": "pending_order_closing",
    "pending_order": {
      "order_no": "TO202607270001",
      "artist_id": 1,
      "subscription_plan_code": "month_30",
      "sub_type": "month",
      "subscription_action": "initial",
      "payment_method": "wechat",
      "payment_amount": "30.00",
      "payment_expires_at": "2026-07-27 15:30:00",
      "remaining_seconds": 0
    },
    "retry_after_seconds": 2
  }
}

业务规则:

  • 创建时写入 tieup_ordertieup_user_rechargerecharge_type = 2 或自动订阅时为 3
  • 新订单必须使用 tieup_artist_pricing.status = 1subscription_plan_code 与请求完全一致的艺人当前档位;服务端在订单事务内锁定定价行,防止艺人并发切换档位。未选择、定价禁用或请求其他档位返回 422
  • 普通单次订阅不要求艺人在 tieup_artist_subscription_config 配置该档位;单次订单的配置 ID、配置版本和第三方订阅资源快照为 null,但仍固化业务档位、价格、结算基数和权益天数。
  • 自动续订必须存在匹配且启用的“艺人 + 档位”配置,并固化配置 ID、版本、第三方资源、价格、结算基数和权益天数;后续配置修改不改变历史订单和协议。
  • APP 判断支付入口时,以艺人详情 subscription_plan.auto_renew_methods 为准:数组为空仍可展示微信、支付宝单次订阅;只有请求 is_auto_renew=1 时才要求对应自动续订渠道存在。
  • subscription_action 非必填,不传、传 null 或空字符串时按 initial 处理;其他值返回 422。同一 Idempotency-Key 重试必须保持订阅动作一致。
  • 从未订阅当前艺人时只允许 initial;历史订阅已经断续时允许 initialrenewal;当前存在有效非自动订阅时只允许 renewal;当前存在有效自动订阅时禁止客户端重复首订或续订,Apple 已扣款的服务端自动续订通知仍正常处理。
  • 支付窗口统一为 30 分钟并在订单创建时固化。相同 Tieup 账号换设备或更换 Idempotency-Key 后,只要用户、艺人、套餐、周期、订阅动作、支付方式、金额、自动续订属性及支付路由兼容,接口返回原订单和仍有效的支付参数,reused_order=true
  • 精确命中既有 Idempotency-Key 的重放先按原购买意图复用订单,不因艺人后续切换档位破坏原请求的幂等结果;非精确重放和新订单必须重新校验当前艺人档位。
  • 同一用户、同一艺人允许同时存在多笔待支付订阅订单;不同 Idempotency-Key 的请求每次创建独立订单,客户端可按订单号分别继续支付或取消。
  • 同一 Idempotency-Key 仍只对应一笔订阅订单;同键重试复用原订单及其支付参数,不会创建第二笔订单。
  • 到达 30 分钟边界、订单已申请取消或第三方关单未确认时返回 422data.error_code=pending_order_closing;客户端按 retry_after_seconds 短暂等待并轮询订单详情,不得立即创建新单。
  • 原订单已支付但权益尚未发放时返回 422data.error_code=payment_delivery_pending,服务端同时投递支付发放补偿。
  • sub_type 必须传入 monthyear,服务端会把该值固化到 tieup_user_recharge.extra.sub_type,支付成功后写入 tieup_subscription.sub_type
  • sub_type=month 的普通结算价使用订阅档位 price_cent,订阅天数使用 duration_daysplatform=1 的 iOS 订单实付金额使用 config.ios_month_price_cent,其他平台实付金额等于普通月费。
  • sub_type=year 的普通结算价使用 config.annual_price_cent,订阅天数固定为 365 天;platform=1 的 iOS 订单实付金额使用 config.ios_year_price_cent。缺少对应普通年费或 iOS 年费时返回 422,不得静默回退其他价格。
  • iOS 月费不得低于普通月费,iOS 年费不得低于普通年费。订阅下单时同时把实付金额和普通结算价固化到业务单,后续档位改价不影响已创建订单的艺人结算。
  • 支付成功后生成或续期 tieup_subscription,订阅记录使用 subscription_plan_codeplan_name_snapshotamount_centsettlement_base_amount_centduration_dayssub_type 快照;amount_cent 是本周期实付金额,settlement_base_amount_cent 是艺人分成使用的购买时普通价格,sub_type 是月卡/年卡唯一可信来源。
  • 新订阅 started_at 取支付平台可信支付时间与当前连续订阅最终结束时间中的较晚者;提前续订从原连续结束时间开始,断续后从实际支付时间开始。客户端不能提交续订时间。
  • 每生成一条新的 tieup_subscription 记录,服务端都会登记并异步发送一条 Tieup:Subscribe 超级群定向消息,包括首次订阅、连续续费、手动续费和 Apple 自动续订;重复支付回调按 subscription_no 幂等,不重复创建消息。
  • tieup_user_recharge.uk_idempotency_key (user_id, idempotency_key) 保留原请求幂等约束;tieup_subscription_order_request.uk_user_idempotency 记录换设备产生的多个幂等键到同一订单的映射。
  • 同一 Idempotency-Key 重复请求:已生成可支付参数时返回原支付参数;上一请求仍在创建支付流水时返回 422,提示“支付流水已创建或正在创建中,请稍后查询订单支付状态”,避免重复拉起第三方支付。同一个幂等键不能在 monthyear 之间复用。
  • iOS/Android 微信和支付宝继续返回 APP SDK 参数;H5 必须传 X-App-Platform: h5,微信 MWEB 和支付宝 WAP 返回 payment.pay_params.pay_url,浏览器跳转后仍需查询订单状态,不能把回跳页面当作支付成功依据。
  • Apple IAP 使用 StoreKit 1 / SwiftyStoreKit。创建订单时必须传 payment_method=apple_iapis_auto_renew=1X-App-Platform: ios。服务端按“艺人 + 档位 + 周期”从艺人订阅配置读取 Product ID 并固化 Subscription Group;客户端不提交这些标识。响应返回 payment.pay_params.product_idapplication_username,购买成功后只提交完整小票到 POST /tieup/api/v1/payment-orders/apple-iap-receipts
  • Apple is_auto_renew=2 返回 422。微信、支付宝 is_auto_renew=2 保持现有 APP/H5 单次支付;当前代码库尚无真实签约代扣网关,传 is_auto_renew=1 返回 422“当前支付渠道自动续订签约能力尚未接入”,不会创建假协议或普通支付订单。
  • Apple 订阅链按 Bundle ID、环境和 original_transaction_id 唯一绑定 Tieup 用户、艺人和 agreement_id;续费只按协议快照创建原艺人订单。Product ID 切换必须命中协议中同一 Subscription Group 的月/年商品快照。