中国道商户接入中心

唯一正式标准:后台能力、SDK嵌入代码、OpenAPI接口、会员身份、订单与售后说明统一以本页为准;旧SDK/旧指南仅历史兼容。

把 SDK 接入、OpenAPI 文档、订单流程、资金安全和回调说明合并到一个入口。普通商户优先用 SDK;技术型商户/系统服务端可使用 OpenAPI;两者底层共用同一套价格、授权、资金与订单中转体系。

1. 接口定位

推荐

SDK 接入

适合大部分商户。商户嵌入 SDK 页面/组件,SDK 负责商品展示、下单参数收集和部分体验封装。测试联调请登录商户后台操作。

面向:商户前端 + 商户后台配置

高级

OpenAPI 接入

适合有自研后端能力的商户或系统级合作方。使用 AppId/AppSecret/HMAC 签名调用商品、余额、下单、查单接口。

面向:商户服务端/合作方系统

结论:这些接口是“对授权商户开放的外部能力”,但不是给普通 C 端用户裸调。C 端用户在商户页面付款,商户确认收款后再通过 SDK/OpenAPI 通知平台履约。联调测试统一放在商户后台,避免公开文档暴露测试工具。

2. 完整业务流程

渠道商成本价我方同步商品/价格平台基准结算价授权商户商户零售价用户支付给商户商户调用 SDK/OpenAPI平台校验授权/价格/余额冻结预存款上游下单/充值成功确认扣款/失败解冻回调商户用户端展示结果

资金安全 当前测试环境已经采用冻结/确认/解冻机制,不再直接扣款后再履约。

价格体系与调价规则

平台采用三层价格治理,商户端展示和下单金额必须以平台后端快照为准,不能相信前端裸传金额。

三层价格

  1. 上游成本价:平台向权益供应商采购/结算的底价,仅平台内部可见。
  2. 平台基准结算价:平台给商户的默认结算价,必须大于等于上游成本价,是平台毛利底线。
  3. 商户零售价:商户展示给用户并向用户收款的价格,必须大于等于商户结算价。

价格安全底线

  • 平台基准结算价 >= 上游成本价。
  • 商户结算价 >= 平台基准结算价。
  • 用户支付价/商户零售价 >= 商户结算价。
  • 发现倒挂、空价格、过期报价时,平台会拒单或回退到安全建议价。

价格模式

模式适用场景下单要求
固定价 fixed话费、会员、洗车、洁牙、标准权益券等按后台授权价格下单,前端金额仅展示,后端重算。
动态锁价 quote餐饮、商超、酒店、景区、电影、票务等价格波动或SKU组合类先由平台后端查询真实商品并生成 quoteId,再用 quoteId 创建订单;quoteId短期有效。
实时/H5价 h5打车、外跳H5、展码付、第三方收银等实时场景用户在实时页面完成选品/支付,平台按回调和订单快照核验。

商户调价边界

  • 商户可在平台授权范围内设置零售价、建议价、最低价、最高价。
  • 低于结算价的零售价不允许保存;已存在历史倒挂数据会被治理脚本拉回安全价。
  • 动态价产品不允许商户自行填写最终履约价,必须使用 quoteId 或平台实时价格快照。
  • 建议零售价默认按平台基准结算价加合理毛利生成,后续可按商户等级、行业、城市、活动配置差异化规则。

3. SDK v2 接入路径

商户最短接入

  1. 平台开通商户、产品授权、SDK 域名白名单、商户收银台地址与支付回调地址。
  2. 商户页面引入 /sdk/commercial-v2/commercial-v2.css/sdk/commercial-v2/commercial-v2-sdk.js
  3. 调用 ChinaDaoCommercialV2.init 渲染商户权益商城。
  4. 用户选择权益,SDK 自动完成城市/资源/规格选择,并请求后端 quoteId 锁价。
  5. 平台创建待支付订单并返回 cashierUrl,地址仅包含一次性短期 token=cst_xxx,不暴露订单号、金额、签名等敏感参数。
  6. 商户前端只负责跳转 cashierUrl,不要解析或自行拼接 merchantId/orderNo/quoteId/amount/timestamp/nonce/sign
  7. 用户在商户收银台付款,商户服务端通过 /sdk/payment/notify/sdk/order-pay-notify 签名回调平台确认收款,平台履约并回调商户。

正式接入代码

<div id="merchant-benefit-sdk"></div>
<link rel="stylesheet" href="/sdk/commercial-v2/commercial-v2.css">
<script src="/sdk/commercial-v2/commercial-v2-sdk.js"></script>
<script>
ChinaDaoCommercialV2.init({
  merchantId: '你的商户ID',
  container: '#merchant-benefit-sdk',
  merchantName: '商户权益商城',
  apiBase: '/prod-api/openapi/v1',
  liveMode: true,
  merchantMemberId: '商户侧会员ID',
  memberOpenId: '微信openId/unionId,可选',
  memberMobile: '会员手机号,可选',
  memberName: '会员昵称,可选',
  memberSource: 'h5'
});
</script>

旧版 /sdk/sdk.js 仅作为历史兼容文件保留,新商户统一接入 SDK v2。

关键入口

SDK v2 商户演示页
当前正式推荐的商户权益商城组件
推荐
SDK v2 接入说明
品牌、域名、收银台、回调、产品准入
文档

产品准入口径

用户端产品展示以 product-admission.json 为准,分为可购买、可查/联调、即将开放、暂不可接入。只有已验证 query/quote/order-create 链路的产品才允许进入购买。

4. 收银台 cashierUrl 安全说明

token 化跳转

/sdk/order-create 返回的 cashierUrl 是平台生成的短期跳转地址,格式类似 /sdk/commercial-v2/merchant-cashier.html?token=cst_xxx。浏览器 URL 不再携带 merchantId/orderNo/quoteId/amount/timestamp/nonce/sign

商户前端只需要跳转该地址;不要解析、保存、转发或自行拼接 token。token 过期后需要重新创建订单或重新发起支付流程。

支付确认边界

token 仅用于收银台展示订单信息,不代表支付成功凭证。

正式支付成功后,必须由商户服务端调用 /sdk/payment/notify/sdk/order-pay-notify,携带 merchantId/orderNo/quoteId/amount/timestamp/nonce/sign 完成验签确认。浏览器前端不能直接确认支付成功。

5. 客户常用入口

以下仅保留商户接入必须使用的正式入口。

商户后台

商品授权、域名白名单、密钥配置和订单查询请在商户工作台完成。

6. 回调与订单状态

订单状态

WAIT_PAY 待商户确认收款 → PAID 已确认 → PROCESSING 上游处理中 → SUCCESS 成功 / CLOSED 失败关闭 / REFUNDED 已退款。

回调要求

商户按 orderNo 做幂等。平台可能因网络失败重试通知,同一订单重复通知不得重复发货/重复退款。

{
  "orderNo":"SDK202605201812405703",
  "status":"SUCCESS",
  "merchantId":1,
  "payAmount":"105.00",
  "event":"ORDER_SUCCESS"
}

7. 会员身份透传与我的订单

SDK v2 已支持商户自有会员身份透传,解决同一浏览器/多商户场景下“我的订单”归属不清的问题。会员身份始终按商户维度隔离,不建立平台全局用户ID。

SDK 初始化字段

字段说明建议
merchantMemberId商户会员ID/用户ID优先传,作为订单归属第一优先级
memberOpenId公众号/小程序 openId 或 unionId微信生态推荐传
memberMobile会员手机号可作为兜底归属,不建议单独依赖
memberName会员昵称/姓名可选,仅用于展示或辅助排查
memberSource会员来源h5/wechat/miniapp/app

订单归属优先级

  1. merchantId + merchantMemberId
  2. merchantId + memberOpenId
  3. merchantId + memberMobile
  4. 浏览器本地订单缓存仅作为老版本兜底,不作为正式归属依据。

后端订单表已新增 merchant_member_idmember_mobilemember_open_idmember_source 字段,均按商户维度索引查询。

推荐接入代码

<div id="merchant-benefit-sdk"></div>
<link rel="stylesheet" href="/sdk/commercial-v2/commercial-v2.css">
<script src="/sdk/commercial-v2/commercial-v2-sdk.js"></script>
<script>
ChinaDaoCommercialV2.init({
  merchantId: '11',
  container: '#merchant-benefit-sdk',
  merchantName: '商户权益商城',
  apiBase: '/prod-api/openapi/v1',
  liveMode: true,
  merchantMemberId: window.CURRENT_USER_ID || '',
  memberOpenId: window.WECHAT_OPEN_ID || '',
  memberMobile: window.CURRENT_USER_MOBILE || '',
  memberName: window.CURRENT_USER_NAME || '',
  memberSource: 'h5'
});
</script>

我的订单接口

GET /prod-api/openapi/v1/sdk/order-list?merchantId=11&merchantMemberId=U10001
GET /prod-api/openapi/v1/sdk/order-list?merchantId=11&memberOpenId=oXxxx
GET /prod-api/openapi/v1/sdk/order-list?merchantId=11&memberMobile=13800138000

跨域接入时请求必须来自已授权域名;接口会校验 Origin/Referer 与商户白名单。

8. 售后/退款能力

SDK端表现

  • 订单详情显示售后状态。
  • 符合条件的订单展示“申请退款/售后”按钮。
  • 提交前有二次确认,提交后自动刷新订单状态。
  • 订单列表新增售后筛选,便于会员查看处理中/已退款订单。

接口边界

退款申请仅创建售后请求,不代表资金立即原路退回。实际退款需平台/商户按支付渠道、履约状态和风控规则审核处理。

生产环境禁止用真实订单做退款演示,除非商户明确授权。

餐饮/券类 quoteId 报价锁价

餐饮、咖啡、兑换券等 SKU 价格不能由前端裸传金额。商户端应先让平台后端重查真实菜单并生成短期 quoteId,再用 quoteId 创建订单。

正式流程

  1. 查询真实门店和菜单 SKU。
  2. 调用 POST /openapi/v1/sdk/food/quote?merchantId=3 生成报价快照。
  3. 订单创建只提交 quoteId,不要提交前端计算金额。
  4. 后端按 Redis 价格快照写入订单金额,保障 quote/order/DB 一致。

星巴克正式服验收样例

商品:双杯美式咖啡

productId:sbk_135533136191685166

价格:43.20

测试订单:TEST202605202018285095

验收:quote = order = DB = 43.20

报价接口

POST /prod-api/openapi/v1/sdk/food/quote?merchantId=3
Content-Type: application/json

{
  "merchantId": 3,
  "shopType": "XBK",
  "shopId": "ff6f2064-8bf7-4f4a-9c83-4bf201714971",
  "productId": "sbk_135533136191685166",
  "quantity": 1
}

下单接口

POST /prod-api/openapi/v1/sdk/order-create?merchantId=3
Content-Type: application/json

{
  "merchantId": 3,
  "typeCode": "Food",
  "testMode": true,
  "quoteId": "foodq_xxx",
  "phoneNumber": "18100348861"
}

安全要求:正式餐饮/券类下单必须使用 quoteId;quoteId 5分钟有效,后续应增加一次性消费、防重放和 SKU 级成本校验。

7. 安全与正式上线

  • SDK:必须配置商户域名白名单,避免任意站点盗用 merchantId。
  • OpenAPI:必须使用 AppId/AppSecret/HMAC 签名,建议配置 IP 白名单。
  • 价格:动态价格/券类/餐饮类必须使用平台后端价格快照 quoteId,不能相信前端裸传金额。
  • 资金:正式环境只允许冻结/确认/解冻闭环,不允许回到直接扣款模式。
  • 上线:正式环境同步前必须备份代码、JAR、关键表,并重新跑价格/商户/补偿检查。