# 91卡券接入当前项目接口配置 ## 1. 对接目标 - `91卡券` 作为外部售卖与自动发货通道。 - 当前项目负责: - 接收 `91卡券` 下单请求; - 在系统内生成订单与快手履约任务; - 生成当前项目自己的领取链接; - 由 `91卡券` 通过自动发货,将该领取链接展示给买家。 - 已确认:**允许将链接作为最终卡密内容展示给买家**。 ## 2. 对接结论 本次对接不走 `Agiso/咸鱼` 的站内消息链路,而是走: 1. `91卡券` 调用我方异步下单接口; 2. 我方创建内部订单,并生成领取链接; 3. `91卡券` 调用我方查询订单接口; 4. 我方在查询结果的 `cards` 中返回领取链接; 5. `91卡券` 自动发货给买家。 ## 3. 接口地址建议 基础前缀建议: ```text https://你的域名/api/v1/open/91 ``` 接口列表: - 异步卡密下单:`POST /api/v1/open/91/orders/create` - 查询订单接口:`POST /api/v1/open/91/orders/query` ## 4. 签名配置 签名规则采用当前文档里的示例规则: - 仅使用请求 JSON body 中实际传入的参数参与签名; - 除 `sign` 外,所有 body 参数按字段名 ASCII 升序排序; - 使用 `key=value&key=value` 方式拼接; - 前后拼接商户密钥; - 取 `MD5`,输出 32 位大写字符串。 建议固定配置: - `signType`: `MD5` - `charset`: `UTF-8` - `timestamp`: 10 位秒级 Unix 时间戳 - `version`: `1.0` - 已传入的空值参数是否参与签名:`参与` - 不参与签名:`sign`、未传入的可选字段、`userId`、商户号、内部配置项 ## 5. 业务字段映射 ### 5.1 下单请求 -> 当前项目 | 91字段 | 当前项目用途 | 说明 | | --- | --- | --- | | `orderNo` | 外部订单号 / 幂等键 | 建议映射为内部 `platformOrderId` | | `productNo` | 商品映射 | 映射到内部 SKU 或履约绑定规则 | | `buyNum` | 购买数量 | 生成对应数量的履约任务 | | `maxAmount` | 成本上限校验 | 可选,超限返回失败 | | `callbackUrl` | 备用回调地址 | 先保留,不作为主流程依赖 | | `timestamp` | 防重放 | 校验请求时效 | | `version` | 版本 | 固定 `1.0` | | `sign` | 验签 | 必填 | ### 5.2 当前项目内部建议映射 建议新增一个独立来源: - `provider = '91kaquan'` - `platform = 'kuaishou'` 商品绑定建议: - `productNo` 对应当前项目内部 `skuCode` - 再由现有快手履约配置,匹配到 `kuaishou_ct_assisted` 履约链路 - 若 `productNo` 暂未配置,订单会先进入后台“91卡券待补全订单”队列,不直接丢弃。 ## 6. 异步下单接口配置 ### 6.1 请求方向 - `91卡券 -> 当前项目` ### 6.2 请求地址 ```text POST /api/v1/open/91/orders/create Content-Type: application/json;charset=utf-8 ``` ### 6.3 请求参数 | 参数名 | 必填 | 类型 | 说明 | | --- | --- | --- | --- | | `orderNo` | 是 | string | 91 商家订单号,唯一 | | `productNo` | 是 | string | 我方商品编号 | | `buyNum` | 是 | int | 购买数量 | | `maxAmount` | 否 | string | 可接受最大成本金额 | | `callbackUrl` | 否 | string | 91 提供的回调地址 | | `timestamp` | 是 | long | 10 位秒级时间戳 | | `version` | 是 | string | 固定 `1.0` | | `sign` | 是 | string | 签名 | ### 6.4 请求示例 ```json { "orderNo": "P91KS202605040001", "productNo": "KS-CLOUD-SKU-001", "buyNum": 1, "maxAmount": "0.0000", "callbackUrl": "https://cb.example.com/notify/91/order", "timestamp": 1777867200, "version": "1.0", "sign": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" } ``` ### 6.5 下单处理规则 - 验签失败:直接返回失败。 - `orderNo` 已存在:按幂等处理,返回已有订单状态。 - `productNo` 未配置:保存为待补全订单,返回处理中。 - 成本超限:返回失败,错误码可用 `1220`。 - 下单成功后: - 创建内部订单; - 创建快手履约任务; - 生成领取链接; - 异步商品首次响应返回 `10`,表示处理中。 ### 6.6 响应字段约定 | 参数名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `orderNo` | string | 是 | 原样返回 | | `outTradeNo` | string | 是 | 我方内部订单号 | | `orderStatus` | int | 是 | 异步商品固定返回 `10` 或 `30` | | `orderCost` | decimal | 否 | 成功受理时可返回 | | `cards` | string | 否 | 异步下单阶段建议为空 | ### 6.7 响应示例 ```json { "code": 200, "message": "接口调用成功", "data": { "orderNo": "P91KS202605040001", "outTradeNo": "OS202605040001", "orderStatus": 10, "orderCost": 0.0000, "cards": "" } } ``` ## 7. 查询订单接口配置 ### 7.1 请求方向 - `91卡券 -> 当前项目` ### 7.2 请求地址 ```text POST /api/v1/open/91/orders/query Content-Type: application/json;charset=utf-8 ``` ### 7.3 请求参数 | 参数名 | 必填 | 类型 | 说明 | | --- | --- | --- | --- | | `orderNo` | 是 | string | 91 商家订单号 | | `timestamp` | 是 | long | 10 位秒级时间戳 | | `version` | 是 | string | 固定 `1.0` | | `sign` | 是 | string | 签名 | ### 7.4 查询处理规则 - 找不到订单:返回失败。 - 订单已创建但履约配置尚未补齐:返回 `orderStatus = 10`。 - 订单已创建但领取链接未准备好:返回 `orderStatus = 10`。 - 领取链接已生成,可交付:返回 `orderStatus = 20`。 - 订单无法履约:返回 `orderStatus = 30`,并带失败原因。 ### 7.5 响应字段约定 | 参数名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `orderNo` | string | 是 | 原样返回 | | `outTradeNo` | string | 是 | 我方内部订单号 | | `orderStatus` | int | 是 | `10`处理中,`20`成功,`30`失败 | | `failCode` | int | 否 | 失败时返回 | | `failReason` | string | 否 | 失败时返回 | | `orderCost` | decimal | 否 | 成功时返回 | | `cards` | string | 成功时必须 | 卡密加密串 | ## 8. cards 字段配置 ### 8.1 推荐方案 既然已确认允许将链接作为最终卡密内容展示给买家,建议: - `cardNo` 直接放领取链接; - `cardPwd` 留空; - `expireTime` 可放领取链接过期时间; - `jumpLink` 可与 `cardNo` 保持一致,作为兼容字段。 这样做的好处是: - `91卡券` 自动发货可直接展示链接; - 复杂文案、快手操作说明、核销码校验、角色确认,全部放在我方领取页完成; - 降低 91 展示层格式差异带来的风险。 ### 8.2 单卡结构建议 ```json [ { "cardNo": "https://你的域名/claim/abc123xyz", "cardPwd": "", "expireTime": "2026-05-05 12:00:00", "jumpLink": "https://你的域名/claim/abc123xyz" } ] ``` ### 8.3 多数量建议 如果 `buyNum > 1`: - 每个数量生成一个独立领取链接; - `cards` 中放多个卡项; - 每个 `cardNo` 对应一个独立链接。 ## 9. 查询成功响应示例 ```json { "code": 200, "message": "接口调用成功", "data": { "orderNo": "P91KS202605040001", "outTradeNo": "OS202605040001", "orderStatus": 20, "failCode": 0, "failReason": "", "orderCost": 0.0000, "cards": "加密后的cards字符串" } } ``` `cards` 解密前原始结构建议为: ```json [ { "cardNo": "https://你的域名/claim/abc123xyz", "cardPwd": "", "expireTime": "2026-05-05 12:00:00", "jumpLink": "https://你的域名/claim/abc123xyz" } ] ``` ## 10. 状态流转建议 ### 10.1 91侧状态 - `10`: 已下单,当前项目正在补齐履约配置或生成领取链接 - `20`: 已可交付,91 可自动发货给买家 - `30`: 无法履约 ### 10.2 当前项目侧状态建议 - 创建订单成功:若履约配置已命中则进入待履约;若未命中则进入后台待补全 - 已生成 `claimUrl`:视为可交付 - 查询接口检测到 `claimUrl` 已存在:返回 `20` - 商家后台手动标记无法履约、履约初始化失败:返回 `30` ## 11. 商品配置建议 建议在你方给 91 的商品配置中约定: - `productNo`:对应当前项目内部的快手履约 SKU - 商品名称:明确标注“自动发链接” - 发货类型:异步卡密 - 买家收到内容:领取链接 后台补全路径: 1. 进入“平台配置 -> 91卡券接入”查看待补全订单; 2. 根据订单中的 `productNo` 到“履约配置中心 -> 快手 Cloud 新履约”新增或补齐规则; 3. 规则保存后回到“91卡券接入”,点击“重试生成任务”; 4. 任务生成后,查询接口会在领取链接准备好时返回 `orderStatus = 20`。 ## 12. 对接方需确认的固定项 发给 `91卡券` 客服/对接方时,建议一次性确认以下配置: - 异步卡密下单 URL - 查询订单 URL - 商户密钥 - 签名算法是否按本文档固定 - `cards` 中 `cardNo` 直接展示链接是否按预期显示 - `jumpLink` 是否会同步展示或仅作兼容字段 - 查询频率与超时要求 ## 13. 最终建议 这次对接的最稳方案是: - `91` 负责卖货与自动发货; - 当前项目负责生成 `claimUrl`; - `claimUrl` 作为最终卡密内容,通过 `cards.cardNo` 返回; - 所有快手专属引导和后续交互,都留在当前项目领取页中完成。 这样对当前项目改动最小,也最符合现在快手 Cloud 履约链路的设计。