开发 服务端 担保支付(自动续费) 签解约能力
# 签解约能力
更新时间:2024-11-08 11:03:10
注意:平台已提供统一的解约入口,请开发者务必在开发者平台配置好解约回调地址!请参考:功能说明 (opens new window)
# 1. 支付并签约
# 1.1 接口说明
- 可通过该接口发起支付并签约,支付并签约后会产生两个回调,分别是支付成功回调和签约成功回调。
a. 支付并签约的支付回调和普通单次支付回调一致,不包含签约相关信息。
b. 签约成功回调,参考"3.签解约回调“ - 支付回调地址会优先使用开发者传入的 pay_notify_url,如果接口没有传入,会填充开发者在开发者平台设置的 支付回调,该回调地址设置与查看步骤如下【小程序开发者平台 (opens new window) -> 交易管理 -> 支付管理 -> 支付设置 -> 默认回调地址】
- 签解约回调地址会优先使用开发者传入的 contract_notify_url,如果接口没有传入,会填充开发者在开发者平台设置的 签/解约回调,该回调地址设置与查看步骤同上
- 代扣回调地址会优先使用开发者传入的 withhold_notify_url,如果接口没有传入,会填充开发者在开发者平台设置的 代扣回调,该回调地址设置与查看步骤同上
# 1.2 基本信息
名称 | 内容 |
HTTP URL | https://open.kuaishou.com/openapi/mp/developer/epay/create_contract_order |
HTTP Method | POST |
Scope | 需要具有小程序担保支付权限(scope.ks.epay) |
# 1.3 请求头
名称 | 字段类型 | 内容 |
Content-Type | String | 固定值: "application/json" |
# 1.4 请求参数
以下字段放在 query param 处:
字段名 | 类型 | 是否必填 | 是否参与签名 | 说明 |
app_id | string | 是 | 是 | 小程序AppId 例如:ks707065143182458884 |
access_token | string | 是 | 否 | 拥有小程序支付权限的access token,获取方式见getAccessToken |
以下字段在 body json 处:
字段名 | 类型 | 是否必填 | 是否参与签名 | 说明 |
out_order_no | string[6,32] | 是 | 是 | 商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯一 示例值:1217752501201407033233368018 |
open_id | string | 是 | 是 | 快手用户在当前小程序的open_id,可通过login操作获取。 |
total_amount | number | 是 | 是 | 用户支付金额,单位为[分]。不允许传非整数的数值。 |
goods_id | string[1, 256] | 否 | 是 | 下单商品id,小说行业请传入内容库的third_id 。长度限制256个英文字符,1个汉字=2个英文字符; |
subject | string[1,128] | 是 | 是 | 商品名称或者商品描述简介,建议长度在10个汉字以内,在收银台页面、支付账单中供用户查看使用。注:不可传入特殊符号、emoji 表情等,否则会影响支付成功,1汉字=2字符。 |
detail | string[1,1024] | 是 | 是 | 商品详情。注:不可传入特殊符号、emoji 表情等,否则会影响支付成功,1汉字=2字符。 |
type | number | 是 | 是 | 商品类型,不同商品类目的编号见担保支付商品类目编号 |
expire_time | number | 是 | 是 | 订单过期时间,单位秒,300s - 3600s |
pay_notify_url | string[1, 256] | 否 | 是 | 签约支付回调 通知URL必须为直接可访问的URL,不允许携带查询串。 |
contract_notify_url | string[1, 256] | 否 | 是 | 签约通知回调 通知URL必须为直接可访问的URL,不允许携带查询串。 |
withhold_notify_url | string[1, 256] | 否 | 是 | 代扣通知回调 通知URL必须为直接可访问的URL,不允许携带查询串。 |
provider | json | 否(无收银台预下单必填) | 是 | 无收银台版本预下单场景,json格式,示例如下: {"provider": "ALIPAY","provider_channel_type":"NORMAL"} 注意: 1、json中字段 枚举值见 provider字段说明(目前只需要按照样例传递即可) 2、json中字段顺序须与示例中保持一致,否则会导致验签失败。 |
contract_info | json | 否(自动续费场景必填) | 是 |
注意: 1. 同样的withhold_product和template_type,同一用户仅允许签约一次; 2. 平台会在指定的代扣日期当天开始执行代扣任务;若当天结束仍然未扣款成功,本月将扣款失败。开发者通过代扣结果回调判断代扣执行情况。\ \ 例如:用户在2023年1月10日签约了自动续费的月卡,对应的首次代扣执行时间传入2023年2月10日; 平台会在2023年2月10日开始尝试代扣,若扣款成功,则本月代扣任务已完成;若当天的代扣均失败,则本月代扣失败,平台将不再针对此单发起代扣任务。
4. template_type 自然月、固定30天、固定31天的区别: b. 固定30天/固定31天模板:不受扣款日的限制,将以固定的时长间隔发起扣款,扣款周期固定。例如:开发者传入的首次代扣时间为10号,则下一次扣款将发生在30天/31天之后。
json中字段顺序须与示例中保持一致,否则会导致验签失败。具体实例如上述json |
attach | string[0,256] | 否 | 是 | 开发者自定义字段,回调原样回传. 注:1汉字=2字符;勿回传敏感信息 |
sign | string | 是 | 否 | 开发者对核心字段签名, 签名方式见附录 |
Q: provider 和 contract_info 如何参与验签?
A: 两个参数按照入参示例中的顺序,转换为字符串,之后按照验签 Demo 进行加签
# 1.5 请求示例
curl --location --request POST 'https://open.kuaishou.com/openapi/mp/developer/epay/create_contract_order?app_id=ks707065143182458884&access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhJQj7WUW3mucBZlklkzQT1nZ3g-u0129JVjCDj-H68v__XCG_u1tKpvETKfwCSVxJotPH_omhiHHbax-XAlebkX1f293Un9KHxWB2k3lBICFocaEngsUCp0IQD00y-GC9Pzapqg_iIgb0ga72EMrnCLrIbzwOewukr0fySa1lMFsjOJhI8VXTgoDzAB' \
--header 'Content-Type: application/json' \
--data '{
"open_id": "5b748c61ef290140c0656638eaa0d69c",
"out_order_no": "1703147868993contractDemo3",
"total_amount": "1",
"subject": "自动续费VIP",
"type": "89999",
"detail": "签约",
"expire_time": "300",
"attach": "",
"pay_notify_url": "https://www.abidu.com/zeus/epay/notify",
"contract_notify_url": "https://www.abidu.com/contract_notify",
"withhold_notify_url": "https://www.abidu.com/withhold_notify",
"goods_detail_url": "1222",
"contract_info": {
"withhold_amount": 1,
"template_type": 2,
"withhold_product": "ks_vip_card",
"first_withhold_time":1704274954000
},
"provider": {
"provider_channel_type": "NORMAL",
"provider": "ALIPAY"
},
"sign": "5a5546dd7b1fbb13ded3b86a901647f9"
}'
# 1.6 响应结果
返回值为 JSON 形式,其中包括如下字段:
字段名 | 类型 | 说明 |
result | number | 状态码 1-业务处理成功 |
error_msg | string | 错误提示信息 |
order_info | json string | 拉起收银台的 orderInfo |
示例如下(仅供参考):
{
"result":1,
"error_msg":"错误信息提示",
"order_info":{
"order_no": "121072611585202788127", // 签约支付单号
"contract_no":"524010201776062339152", // 快手小程序平台签约单号
"order_info_token": "ChJrc01wUGF5Lm9yZGVyVG9rZW4SULxOUORbNX1NAzmbs3vCE8Fo8FN8EW90EM7iReQujs85RbgDNVDPqxJoGly_jX7Zv9kwTiXsrFuSgwrR-ufuZexCYejepc-C0swHGhJtqssdzyq4aMsYYWjhyloiIOZOjlvg2cPW6VJsOmt6c4Tz2qSsZoAhTeKIZAXM13SRKAUwAQ"
}
}
当 result 不为 1 时,说明请求错误,错误信息详见文章末尾 错误码 处。
# 2. 申请解约
# 2.1 接口说明
可通过该接口发起解约,但请注意:
只有签约单状态为 签约成功(CONTRACT_SUCCESS) 才允许调用此接口发起解约
# 2.2 基本信息
名称 | 内容 |
HTTP URL | https://open.kuaishou.com/openapi/mp/developer/epay/apply_uncontract |
HTTP Method | POST |
Scope | 需要具有小程序担保支付权限(scope.ks.epay) |
Content-Type | application/json |
# 2.3 请求头
名称 | 字段类型 | 内容 |
Content-Type | String | 固定值: "application/json" |
# 2.4 请求参数
以下字段放在 query param 处:
字段名 | 类型 | 是否必填 | 是否参与签名 | 说明 |
app_id | string | 是 | 是 | 小程序AppId 例如:ks707065143182458884 |
access_token | string | 是 | 否 | 拥有小程序支付权限的access token,获取方式见getAccessToken |
以下字段放在 body json 处:
字段名 | 类型 | 是否必填 | 是否参与签名 | 说明 |
open_id | string | 是 | 是 | 快手用户在当前小程序的open_id,可通过login操作获取。 |
contract_no | string[21,21] | 是 | 是 | 用户支付并签约时响应结果中的 contract_no(即快手小程序平台签约号),例如:521072611585202788127 |
contract_product | string[1,32] | 是 | 是 | 周期代扣对应的产品信息,产品命名要求: 1. 全英文字符; 2. 命名规范:体现产品信息,例如: xxx_vip_card 目的:保证 同一用户同一时刻只能签约同一个代扣产品 |
uncontract_reason | string[1,64] | 是 | 是 | 解约原因。不可传入特殊符号、emoji 表情等,否则会影响解约,1汉字=2字符。 |
sign | string | 是 | 否 | 开发者对核心字段签名, 签名方式见附录 |
# 2.5 请求示例
curl --location --request POST 'https://open.kuaishou.com/openapi/mp/developer/epay/apply_uncontract?app_id=ks682576822728817112&access_token=ChFvYXV0aC5hY2Nlc3NUb2tlbhJAL52dDoKMVh2w8jPfbT6kWU8YUJOa3RqvKlESG0cXeUPeTlFC2MleLTZhqCUc21PPMSPpFPX5Kz_QmeoSZa9zthoSOI8XNcR9SteZH8dRkJ9UsC77IiDBOPwbNeeoBSus0AVDxBcdWHC_ATprOsTy7szonCPcDigFMAE' \
--header 'Content-Type: application/json' \
--data '{
"open_id": "f198e0af75c12d9914bf57248892441e",
"contract_no": "524010900088702196436",
"contract_product": "Online1_WEEK",
"uncontract_reason": "online测试解约1",
"sign": "9714e90a64f9ed9e265f34f122ee5489"
}'
# 2.6 响应结果
返回值为 JSON 形式,其中包括如下字段:
字段名 | 类型 | 说明 |
result | number | 状态码 1-业务处理成功 |
error_msg | string | 错误提示信息 |
示例如下(仅供参考):
{
"result":1,
"error_msg":"错误信息提示"
}
当 result 不为 1 时,说明请求错误,错误信息详见文章末尾 错误码 处。
# 3. 签解约回调
# 3.1 接口说明
在签约/解约成功后,快手小程序服务端会通过 HTTP POST 请求方式回调开发者提供的 HTTP 签约回调地址。回调的内容使用小程序 secret key 进行签名,具体回调方式和重试策略见附录 (opens new window)。请注意:
- 由于网络波动等原因,可能会产生重复的通知消息,开发者需要做好幂等处理。
- 回调可能存在延时,开发者可以通过主动请求查询签约信息,确认签约结果。
- 在开发者服务端收到回调且处理成功后,需要按以下正常返回示例返回并且 HTTP 响应状态码设为 200,否则会认为通知失败并进行重试。
- 签约回调的地址是 支付并签约接口中的 contract_notify_url 字段,所以请务必保证该字段传输的正确性
# 3.2 基本信息
名称 | 内容 |
HTTP URL | 开发者在支付并签约时传入的 contract_notify_url 字段 |
HTTP Method | POST |
# 3.3 平台回调内容
以下字段放在 body json处:
{
"data": {
"withhold_product": "签约产品",
"contract_status": "CONTRACT_SUCCESS",
"order_no": "121112500031787702250",
"contract_no": "521112500031787702251",
"contract_time":1627293368719,
"uncontract_time":1627293368719,
"contract_type": 1,
"contract_provider": "ALIPAY",
"attach": "小程序demo得"
},
"biz_type": "CONTRACT", // 代表为签解约回调
"message_id": "fa578923-347b-4158-9ae8-06c54d485da3",
"app_id": "ks682576822728417112",
"timestamp": 1627293368719
}
其中和支付相关的主要是:
字段名 | 类型 | 说明 |
attach | string | 预下单时携带的开发者自定义信息 |
withhold_product | string | 周期代扣产品名称 |
contract_status | string | 签约状态 CONTRACT_SUCCESS - 签约成功 UNCONTRACT_SUCCESS - 解约成功 |
order_no | string | 快手小程序平台订单号 |
contract_no | string | 快手小程序平台签约号 |
contract_time | number | 签约时间 |
uncontract_time | number | 解约时间 |
contract_type | number | 签约模版类型 1:周 2:月 3:季度 4:年 5:固定30天 6:固定31天 |
contract_provider | string | 签约的第三方渠道,取值如下 UNKNOWN - 未知|WECHAT-微信|ALIPAY-支付宝 |
# 3.4 开发者返回内容
开发者在接收到回调消息,并正确处理后,需要返回以下内容格式,以通知小程序平台不再持续回调:
{
"result" : 1, //必填。 1-成功,其他-失败。失败小程序平台会尝试重推此消息
"message_id" : "ChFvYXV0aC5hY2Nlc3NUb2tlbhJQvpR51x8In46B1sDB" //当前消息的message_id
}
如果开发者没有返回或者返回的result不等于1,则小程序平台会尝试重复推送此消息,开发者务必做好消息的幂等处理!
# 错误码
错误码 | 描述 | 排查建议 |
10000011 | token 过期 | 调用 getAccessToken 重新生成 token |
10000200 | 参数错误 | 对照错误提示和接口字段定义,检查对应的参数 |
10000302 | 请求频率太快,被限速。 | 请降低访问频率 |
10000500 | 系统故障 | 请联系相关开发人员进行排查 |
10000501 | 稍后重试 | 请等待1-2秒,再重试 |
10000606 | 接口参数签名错误 | 对照接口字段,检查签名字段是否正确 |
10000607 | 不合理的订单金额 | 请检查传入的订单金额是否合理 |
10000632 | 平台内部错误 | 请联系相关开发人员进行排查 |
10001001 | 签约单不存在 | 请检查传递的签约单号/订单号 |
10001003 | 平台解约异常 | 请联系相关人员排查 |
10000605 | 回调地址异常 | 请检查接口传递的回调地址域名是否正确 |
10000631 | 配置错误 | 请检查在小程序平台的支付信息是否完善 |
10000622 | 平台支付异常 | 请联系相关开发人员进行排查 |