Skip to content

支付绑卡

本组接口仅服务 CXH_DEDUCT 的"A.1 自绑"子流程(用户在 CXH 端绑卡,CXH 持有协议)。

  • CHANNEL_COLLECT 的渠道:无需本组接口,直接查阅 订阅下单
  • CXH_DEDUCT 的 A.2 协议共享(用户已在渠道侧绑卡,渠道将支付机构协议号共享给 CXH):无需本组接口,在 订阅下单 入参中传 sharedAgreement 子对象

协议(agreement)代表用户与某个支付通道签订的代扣授权。绑卡与订阅下单分离:绑卡仅完成"卡 + 实名 + 代扣授权"的建立,无需指定 SPU;后续 订阅下单 时通过 bindOrderNo 关联,同一份绑卡可被同一渠道下的多个 SPU 订阅复用。

多卡多通道场景

  • 同一用户可在多个支付通道各绑一张卡,每张卡独立 agreement
  • 同一用户在同一支付通道也可绑多张不同银行卡,每张卡独立 agreement
  • 绑卡时通过入参 paymentChannelCode 指定使用哪个通道
  • 可选的 paymentChannelCode 列表由 BD 为每个渠道单独授权,渠道通过 payment-channels/list 获取动态列表(亦可向 BD 索取)
  • 绑卡接口的 bankCode 使用支付通道支持的银行编码;若通道返回 supportedBanks=["*"] 表示不限,否则必须从 supportedBanks 列表中取值

POST /openapi/v1/payment-channels/list

查询当前渠道已授权的支付通道列表。建议渠道前端进入绑卡页时先调用一次,动态展示给用户选择。

请求

无 body(空对象 {})。

响应 data

字段说明
items已授权通道列表
items[].code通道编码,作为 bind-sms 入参 paymentChannelCodesharedAgreement.paymentChannelCode
items[].displayName终端用户可见的名称
items[].isDefault该渠道的默认通道,列表内至多一项true;bind-sms 未传 paymentChannelCode 时由此兜底
items[].shareEnabled是否开通 A.2 协议共享。true 表示渠道可在 订阅下单sharedAgreement 入参跳过 CXH 绑卡,直接传入支付机构的协议号。需双方在该支付机构提前完成协议共享对接
items[].supportedBanks该通道支持的银行编码列表;["*"] 表示不限
json
{
  "items": [
    {
      "code": "CHANNEL_A",
      "displayName": "示例通道 A",
      "isDefault": true,
      "shareEnabled": true,
      "supportedBanks": ["ICBC", "ABC", "CCB", "BOC"]
    },
    {
      "code": "CHANNEL_B",
      "displayName": "示例通道 B",
      "isDefault": false,
      "shareEnabled": false,
      "supportedBanks": ["*"]
    }
  ]
}

POST /openapi/v1/agreements/bind-sms

发送绑卡验证码。5 个敏感字段必须 AES 加密,详见 签名 + 字段加密

请求

字段必填说明
channelUserId渠道侧用户唯一 ID
paymentChannelCode支付通道编码;若该渠道仅授权一个通道或配置了默认通道,可不传(CXH 用默认值兜底)。传值必须在 BD 提供的授权列表内,否则 403003 PAYMENT_CHANNEL_NOT_ALLOWED
bankCode银行编码;通道要求银行编码时必填,取值参考 payment-channels/list 返回的 items[].supportedBanks。例如 CCB(建设银行)、ABC(农业银行)。该字段不是敏感字段,明文传输
mobileEncrypted用户登录手机号(AES 加密;不是银行预留手机号)。首次发码成功后,该手机号与 (channelId, channelUserId) 强绑定;后续同 (channelId, channelUserId) 再次调用 bind-sms / orders/create 入参 mobile 必须一致,否则 410010 CHANNEL_USER_MOBILE_MISMATCH。如需修改请联系 BD 人工处理
bankCardNoEncrypted银行卡号(AES 加密)
certificateNoEncrypted身份证号(AES 加密)
realNameEncrypted真实姓名(AES 加密)
bankMobileEncrypted银行预留手机号(AES 加密)
certType证件类型,默认 ID_CARD
productCodeSPU 编码;若绑卡时已知目标 SPU 可传入,CXH 会校验该渠道是否被授权销售;留空表示通用绑卡,与具体 SPU 解耦
bindOrderNo二次发码时传入(同一绑卡单重新触发短信);二次发码不可修改 paymentChannelCode
json
{
  "channelUserId": "u_001",
  "paymentChannelCode": "CHANNEL_A",
  "bankCode": "CCB",
  "mobileEncrypted": "cxh_aes_v1:...",
  "bankCardNoEncrypted": "cxh_aes_v1:...",
  "certificateNoEncrypted": "cxh_aes_v1:...",
  "realNameEncrypted": "cxh_aes_v1:...",
  "bankMobileEncrypted": "cxh_aes_v1:...",
  "certType": "ID_CARD"
}

响应 data

字段说明
bindOrderNo绑卡单号;后续 bind-confirmorders/create 用此关联
paymentChannelCode实际生效的通道编码(入参未传时返回兜底默认值)
agreementStatusBIND_ING(短信已发送,等待用户输入验证码)
smsStatusSEND_SUCCESS / SEND_FAIL
failReasonsmsStatus=SEND_FAIL 时返回,失败原因描述
json
{
  "bindOrderNo": "BIND...",
  "paymentChannelCode": "CHANNEL_A",
  "agreementStatus": "BIND_ING",
  "smsStatus": "SEND_SUCCESS"
}

POST /openapi/v1/agreements/bind-confirm

提交短信验证码,完成绑卡。smsCodeEncrypted 必须 AES 加密

请求

字段必填说明
bindOrderNobind-sms 返回的绑卡单号
smsCodeEncrypted用户输入的短信验证码(AES 加密)
json
{
  "bindOrderNo": "BIND...",
  "smsCodeEncrypted": "cxh_aes_v1:..."
}

响应 data

字段说明
agreementNo协议号(绑卡成功后由 CXH 生成)
agreementStatusBIND_SUCCESS / BIND_FAIL
bankCardTailNo银行卡号后 4 位,用于回显
failReasonagreementStatus=BIND_FAIL 时返回,失败原因描述
json
{
  "agreementNo": "AGT...",
  "agreementStatus": "BIND_SUCCESS",
  "bankCardTailNo": "0123"
}

成功后 agreementNo 即可在 订阅下单 通过 bindOrderNo 关联使用。订阅下单时无需再传 paymentChannelCode,CXH 从 agreement 自动获取

POST /openapi/v1/agreements/user-data

按查询条件返回该用户在 CXH 已绑卡的 agreement 列表(密文回传,渠道侧自行解密)。至少传一个查询条件;敏感字段必须 AES 加密。

请求

字段必填说明
channelUserId渠道侧用户唯一 ID;与 bankCardNoEncrypted / certificateNoEncrypted 至少传一个
bankCardNoEncrypted银行卡号(AES 加密);用于按卡号反查
certificateNoEncrypted身份证号(AES 加密);用于按证件号反查
json
{
  "channelUserId": "u_001"
}

未传任何查询条件时返回 400001

响应 data

字段说明
bankDataList已绑 agreement 列表,空列表表示该用户在当前渠道无已绑卡
bankDataList[].bindOrderNo绑卡单号
bankDataList[].agreementNo协议号
bankDataList[].bankCardNoEncrypted银行卡号密文(渠道侧用 aesKey 解密)
bankDataList[].certificateNoEncrypted身份证号密文
bankDataList[].realNameEncrypted真实姓名密文
bankDataList[].bankMobileEncrypted银行预留手机号密文
bankDataList[].agreementStatusBIND_SUCCESS / CANCELED / REPLACED
json
{
  "bankDataList": [
    {
      "bindOrderNo": "BIND...",
      "agreementNo": "AGT...",
      "bankCardNoEncrypted": "cxh_aes_v1:...",
      "certificateNoEncrypted": "cxh_aes_v1:...",
      "realNameEncrypted": "cxh_aes_v1:...",
      "bankMobileEncrypted": "cxh_aes_v1:...",
      "agreementStatus": "BIND_SUCCESS"
    }
  ]
}

字段名以 Encrypted 结尾的均为 AES 密文,渠道侧使用 aesKey签名 + 字段加密 § 字段级 AES 描述的格式解密。

对接咨询 · bd@cxh.me / tech@cxh.me