霸王餐渠道接口
    • 业务流程
    • 订单通知
    • 接口安全
    • 霸王餐渠道活动接口
      • 霸王餐类目列表
        GET
      • 霸王餐活动详情
        GET
      • 霸王餐活动分页列表
        GET
    • 霸王餐渠道订单接口
      • 渠道报名下单
        POST
      • 渠道取消报名
        POST
      • 渠道订单详情
        GET
      • 渠道报名单分页搜索
        GET
      • 回填外卖单号
        POST
      • 上传凭证
        POST
    • 霸王餐连通性接口
      • 连通性验证
        GET
    • 数据模型
      • ApiResponse«List«霸王餐类目»»
      • ApiResponse«Map«string,object»»
      • ApiResponse«PageResponse«霸王餐渠道订单»»
      • ApiResponse«PageResponse«霸王餐门店»»
      • ApiResponse«Void»
      • ApiResponse«霸王餐活动详情»
      • ApiResponse«霸王餐渠道订单»
      • BwcUserOrderInfo
      • PageResponse«霸王餐渠道订单»
      • PageResponse«霸王餐门店»
      • 上传凭证请求
      • 回填外卖单号请求
      • 渠道取消报名请求
      • 渠道报名下单请求
      • 霸王餐活动条目
      • 霸王餐活动详情
      • 霸王餐渠道订单
      • 霸王餐类目
      • 霸王餐门店

    接口安全

    霸王餐渠道开放接口安全规范#

    本文约定开放接口的接入凭证、签名算法、防重放机制与响应码口径。所有接口(含连通性自测)都必须签名,未通过签名的请求不进入业务逻辑。

    一、接入准备#

    项说明
    接口地址https://{域名}/openapi/bwc/...(测试/生产地址由我方在开通时提供)
    传输协议生产环境必须使用 HTTPS
    凭证appId(渠道应用 ID)+ secret(签名密钥),同时用于接口签名与 Webhook 验签
    获取方式由我方在渠道管理后台开通并线下下发,禁止通过接口回传
    密钥、回调地址、接口有效期以我方渠道配置为准。修改后最长 60 秒生效,联调期更换密钥后立即请求可能仍按旧密钥校验,等待 1 分钟后重试即可。
    渠道被禁用、接口未开通或已过期时,全部接口返回 code=3,message 说明具体原因。

    二、公共参数#

    所有接口都必须在 URL query 中携带以下 4 个参数(GET 与 POST 一致):
    参数必填类型说明
    appId是string渠道应用 ID
    timestamp是string请求时间戳,秒或毫秒均可(大于 10 位的按毫秒处理),与服务端时间偏差不得超过 ±300 秒
    nonce是string随机串,300 秒内同一 appId 下不可重复(建议 UUID 去横线)
    sign是string签名,见第三节
    校验项失败返回
    appId 缺失或查不到渠道code=3,参数(appId)错误:未查询到渠道,请稍后再试
    timestamp 缺失 / 非数字code=3,参数(timestamp)错误:时间戳不能为空 / 时间戳格式错误
    timestamp 超出 ±300 秒code=3,参数(timestamp)错误:请求已过期
    nonce 缺失code=3,参数(nonce)错误:随机串不能为空
    nonce 重复code=3,参数(nonce)错误:重复请求
    签名不匹配code=101,签名不匹配

    三、签名算法#

    3.1 计算步骤#

    1.
    取 URL query 参数 与 POST body 的 JSON 顶层字段,合并为一个参数集合;同一 key 同时出现时,以 URL 参数为准。
    2.
    剔除 sign 字段(appId / timestamp / nonce 参与签名)。
    3.
    对嵌套结构做扁平化(见 3.2)。
    4.
    按 key 的字典序升序(字符串自然序、区分大小写)排序。
    5.
    依次拼接 k1=v1&k2=v2&...;值为 null 或空字符串的键整条跳过。
    6.
    在拼接串末尾直接追加 secret(不加 &、不加分隔符)。
    7.
    对整串做 MD5,取 32 位小写十六进制(UTF-8 编码)。
    sign = lowerHex( MD5( "k1=v1&k2=v2&...&kn=vn" + secret ) )

    3.2 扁平化规则#

    结构规则示例
    普通字段原样orderNo=BW17612345670001234
    嵌套对象父键 + . + 子键{"coordinate":{"longitude":117.28}} → coordinate.longitude=117.28
    数组父键 + [下标]{"imgs":["a","b"]} → imgs[0]=a、imgs[1]=b
    null / 空串跳过不拼{"reason":""} → 不出现
    数字 / 布尔按原字面量转字符串true、500、117.285735
    本开放接口的请求字段均为扁平结构(经度 longitude、纬度 latitude 直接放在顶层,不要求包成 coordinate 对象)。若渠道方自行嵌套,签名必须按上表的点号路径计算,否则校验失败。

    3.3 注意事项#

    1.
    不做 URL 编码:参与签名的值使用原文,不要先 encodeURIComponent;中文按 UTF-8 原样参与。
    2.
    不做 trim:前后空格会参与签名,请勿在传参前后自行去空格。
    3.
    无值字段直接不传:值为 null 或空串的字段不参与签名,同时建议不要放进请求,避免两端拼接口径不一致。
    4.
    body 必须是合法 JSON:解析失败返回 code=3「参数(body)错误:请求体缺失或 JSON 格式错误」。
    5.
    GET 只签 query 参数:GET 无 body,签名串即全部 query 参数(含公共参数)按字典序拼接。

    四、签名示例#

    4.1 GET 示例(连通性自测)#

    请求(示例 secret 为 MY_APP_SECRET):
    GET /openapi/bwc/ping?appId=200009&timestamp=1761234567&nonce=6f1a2b3c4d5e6f70&sign=1ddb3ec7a8af3322c76945576d8d5f48
    签名原文(字典序:appId < nonce < timestamp,末尾拼 secret):
    appId=200009&nonce=6f1a2b3c4d5e6f70&timestamp=1761234567MY_APP_SECRET
    MD5 32 位小写:
    1ddb3ec7a8af3322c76945576d8d5f48

    4.2 POST 示例(报名下单)#

    URL query:appId=200009&timestamp=1761234567&nonce=a1b2c3d4e5f60718
    Body:
    {
      "channelOrderNo": "CH20261023001",
      "channelUserId": "user_10001",
      "mobile": "13800138000",
      "activityId": "12345",
      "storeId": "store_123",
      "longitude": 117.285735,
      "latitude": 31.863916
    }
    签名原文(query 与 body 合并后按字典序,sign 不参与):
    activityId=12345&appId=200009&channelOrderNo=CH20261023001&channelUserId=user_10001&latitude=31.863916&longitude=117.285735&mobile=13800138000&nonce=a1b2c3d4e5f60718&storeId=store_123&timestamp=1761234567MY_APP_SECRET
    签名结果:
    068735da2dbf5c9c9f9d938bd33e8bf2

    4.3 Java 参考实现#

    4.4 Python 参考实现#

    两份示例均按“空值跳过、URL 覆盖 body”实现;请勿在拼接前后对值做 URL 编码或 trim。

    五、响应约定#

    5.1 统一结构#

    所有接口一律返回 HTTP 200,业务结果通过 body 的 code 判断:
    {
      "code": 0,
      "message": "success",
      "data": {}
    }
    字段类型说明
    codeint业务码,0 表示成功
    messagestring结果描述
    dataobject业务数据,失败时可能为空或携带 field 定位信息
    分页接口的 data 结构:
    {
      "total": 128,
      "page": 0,
      "size": 20,
      "data": []
    }

    5.2 错误码#

    code含义典型场景处理建议
    0成功—正常解析 data
    3参数错误(含防重放失败)缺公共参数、参数格式越界、时间戳过期、nonce 重复、请求体缺失、请求方法不支持、渠道禁用/接口过期修正参数后重试;时间窗与 nonce 类错误需重新生成 timestamp 与 nonce
    101签名不匹配密钥错误、参与签名的参数集合不一致、空值/编码处理不一致用 ping 复现;核对签名原文(常见原因:query 未参与签名、对值做了 URL 编码)
    300业务参数错误当前状态不允许该操作、外卖单号非纯数字、参数组合非法先用 order/detail 刷新状态再决定是否重试
    301业务校验失败未开通渠道服务费、订单不存在、订单不属于当前渠道、活动不存在/已结束/不在活动时间窗、报名被拒按 message 提示修正;归属类错误确认 orderNo 是否属于当前 appId
    500服务端异常内部错误或依赖超时可间隔重试(报名类建议先按 channelOrderNo 查单避免重复报名);持续失败请联系我方
    参数校验失败时,data.field 会给出具体字段名:
    {"code": 3, "message": "参数(rebateMode)错误:返利模式不能为空", "data": {"field": "rebateMode"}}
    301 的 message 为面向渠道的简短原因,可直接展示给渠道运营。
    渠道方不要依赖 HTTP 状态码判断成败,务必读 code。

    5.3 字段约定#

    约定说明
    金额一律为分(mealPrice / commissionAmount / channelAmount 等),整数字段
    比例万分比(commissionRate=500 表示 5%)
    接口时间字段yyyy-MM-dd HH:mm:ss 字符串(GMT+8);ping 返回的 timestamp 为毫秒数字
    Webhook 时间字段毫秒时间戳(epoch millis),与接口响应不同,注意区分
    status接口响应为枚举名字符串(Registered / Submitted / PendingReview / Completed / Rebated / Cancelled);Webhook 为整数
    分页page 从 0 起,size 1~100(默认 20,超过 100 按 100 处理)

    六、接入自检#

    1.
    签名自测:调 GET /openapi/bwc/ping,code=0 且 data.appId 与自己的一致,说明签名链路可用。
    {"code": 0, "message": "success", "data": {"appId": "200009", "timestamp": 1761234567123}}
    2.
    错误分支自测:故意改签名最后一位应返回 code=101;用 1000 秒前的时间戳应返回 code=3 请求已过期;同 nonce 连发两次,第二次应返回 code=3 重复请求。三条都符合,即可判定签名与防重放链路正常。
    3.
    只读接口自测:activity/categories → activity/search → activity/detail,最后再测 order/apply(写接口),避免产生无效报名数据。
    4.
    时钟同步:服务器开启 NTP。本地时钟偏差超过 300 秒会导致全部请求返回 请求已过期。

    七、安全建议#

    1.
    secret 仅保存在服务端,禁止下发到客户端(App/H5)或写入前端配置。
    2.
    生产环境只走 HTTPS,禁止在 URL 中携带敏感信息(手机号等用 body 传)。
    3.
    nonce 使用真随机(UUID v4 或 SecureRandom),不要用固定值或自增数。
    4.
    接收 Webhook 时同样要验签并做幂等,详见 订单通知。
    5.
    发现密钥泄露立即联系我方轮换,轮换后最长 60 秒旧密钥失效。
    6.
    我方所有拒绝都返回 HTTP 200 + code,请勿以 HTTP 状态码做告警,应以 code != 0 做业务告警。
    修改于 2026-10-30 14:28:37
    上一页
    订单通知
    下一页
    霸王餐类目列表
    Built with