小程序C端接口对接文档
小程序 C 端接口对接文档(2026-09 功能批次)
唯一维护处:本笔记。2026-10-13 起仓库
docs/不再保留副本,接口变更直接在此维护,勿再找源文件。
创建:2026-09-29|更新:2026-10-13(mall2.0 已上线现网,以此版为准)
用途:小程序前端(前端小哥)对接本期新增功能的全部接口
覆盖:首页宫格配置 / 滚动系统通知 / 商城轮播图 / 商品分类 / 每日签到 / 积分抽奖(含实物收货信息)/ 客服咨询 / 订单物流轨迹 / 售后退款 / 混合支付
后端仓库:pangge-mall(mall-admin),本文档口径以代码为准2026-10-12 更新记录:
- 新增「首页滚动系统通知」接口(2.3);
- 修正 2.2 首页资讯出参口径:无正文/发布时间,新增跳转配置三字段;
- 抽奖:draw 出参新增
recordId,my-records 扩展收货信息,新增「填写收货信息」接口(4.5);- 订单:新增物流三字段与物流状态(6.2),新增「修改订单收货地址」接口(6.3);
- 第八章联调状态刷新到上线日。
2026-10-13 更新记录:
- 新增「商城轮播图」两个接口,自建商品 / 胖哥商品分开(2.4);
- 新增「商品分类」接口的
image字段(分类图片,2.5)。
一、通用约定
1.1 请求地址与鉴权
| 项目 | 说明 |
|---|---|
| 基础地址 | 生产:https://m.panggeshop.com/mall-api(nginx 去掉 /mall-api 前缀转后端 8081);联调:http://localhost:8081 |
| 鉴权方式 | 所有 /in/wx/** 接口在请求头携带 MATOKEN: <openid> |
| MATOKEN | 就是小程序用户的明文 openid,不做签名;缺失/非法时接口返回业务错误(HTTP 仍是 200) |
1.2 统一返回结构
{ "code": 0, "msg": "success", "data": { } }
code = 0成功;非 0 一律视为失败,直接把msg展示给用户即可(后端已转成用户能看懂的话术)。- HTTP 状态码恒为 200,不要用 HTTP 状态码判断成败。
- 网络异常 / 超时:按微信小程序常规错误处理。
1.3 分页约定
入参:page(默认 1)、limit(默认 10);出参:{ "list": [...], "total": 123 }。
1.4 时间格式
- 日期时间:
yyyy-MM-dd HH:mm:ss - 日期:
yyyy-MM-dd
1.5 枚举速查
| 枚举 | 取值 |
|---|---|
| 支付状态 paymentFlag | UNPAID 未支付 / PAID 已支付 / CANCELLED 已取消 |
| 发货状态 deliveryFlag | NOT_DELIVERED 未发货 / DELIVERED 已发货 |
| 售后状态 afterSaleStatus | PENDING 待审核 / APPROVED 待退款 / REFUNDED 已退款 / REJECTED 已驳回 / CANCELED 已撤销 |
| 售后类型 afterSaleType | REFUND_ONLY 仅退款(未发货)/ RETURN_REFUND 退货退款(已发货) |
| 客服消息角色 senderType | USER 用户 / AGENT 坐席 / SYSTEM 系统欢迎语 |
| 客服内容审查 auditStatus | PASS 通过 / REJECT 拦截 / NONE 无需审查 |
| 抽奖奖品类型 prizeType | PHYSICAL 实物(线下核销)/ INTEGRAL 积分(自动到账)/ THANKS 谢谢参与 |
二、首页宫格配置
宫格共 10 个入口,其中 6 个是固定功能页(优惠券=占位不展示、签到、赢好礼、抽奖、更多活动、客服、退款售后、物流、品牌资讯按产品稿排列)。「赢好礼」和「更多活动」的跳转目标需要从接口取,取不到就隐藏入口。
2.1 获取宫格配置
GET /in/wx/mall/homeGridConfig
出参 data:
| 字段 | 类型 | 说明 |
|---|---|---|
| giftTitle | string | 赢好礼入口标题 |
| giftAppId | string | 第三方小程序 appId,空 = 未配置,隐藏入口 |
| giftPath | string | 第三方小程序页面路径 |
| activityTitle | string | 更多活动入口标题 |
| activityQrcodeUrl | string | 公众号二维码图片地址,空 = 未配置,隐藏入口 |
| activityQrcodeName | string | 二维码图片名称 |
前端交互:
- 赢好礼:
wx.navigateToMiniProgram({ appId: giftAppId, path: giftPath })。 - 更多活动:弹窗展示
activityQrcodeUrl,提示长按识别关注公众号。 - 配置在后台「系统管理 → 系统配置」维护,改完即时生效(有缓存,最多几秒延迟)。
2.2 宫格关联的既有首页接口(早已上线,列于此备查)
| 接口 | 说明 |
|---|---|
GET /in/wx/mall/homeBanner | 首页 banner 列表(不分商品线,按 ID 倒序) |
GET /in/wx/mall/homeActivity | 首页活动列表 |
GET /in/wx/mall/homeInformationType | 资讯分类列表 |
GET /in/wx/mall/homeInformation?informationType= | 品牌资讯 = 此模块,按创建时间倒序 |
homeInformation 出参元素(HomeInformation):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 资讯ID |
| name | string | 标题 |
| informationType | string | 分类 |
| images | array | 图片集 [{url,name}]。仅 jumpType=NONE 时展示(点开展示图片集) |
| miniImages | array | 缩略图 [{url,name}],列表/宫格封面用它 |
| mallGoodsId | long | 关联商品ID(可空) |
| jumpType | string | NONE 不跳转(默认)/ SELF_MINIAPP 跳本小程序页面 / OFFICIAL_ACCOUNT 跳公众号文章 / OTHER_MINIAPP 跳外部小程序 |
| jumpPath | string | 跳转路径。SELF_MINIAPP=本小程序页面路径(如 pages/goods/detail?id=xxx);OFFICIAL_ACCOUNT=公众号文章链接(用 webview 打开) |
| jumpAppId | string | OTHER_MINIAPP 的目标小程序 appId |
| createTime | string | 创建时间 |
注意:资讯没有正文(content)和发布时间(publishTime)字段,2026-09-30 已按产品口径删除,列表排序就是创建时间倒序,不要等这两个字段。
前端跳转交互:NONE 点开看图片集;SELF_MINIAPP 用 wx.navigateTo({ url: jumpPath });OFFICIAL_ACCOUNT 用 web-view 打开 jumpPath;OTHER_MINIAPP 用 wx.navigateToMiniProgram({ appId: jumpAppId, path: jumpPath })。
2.3 首页滚动系统通知(新增)
GET /in/wx/mall/homeNotice
无入参。后端只返回启用中且在生效时间区间内的通知(开始/结束时间为空视为长期有效),按 ID 倒序。
出参 data:数组,元素:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 通知ID |
| content | string | 纯文本内容(≤500 字),直接滚动展示 |
| beginTime / endTime | string | 生效区间,可为 null(null = 长期有效),仅用于调试参考 |
前端交互:列表为空时隐藏滚动条;非空按顺序循环滚动即可(无需自己做过期判断,后端已过滤)。
2.4 商城轮播图(自建商品 / 胖哥商品,新增)
商城页按商品来源线分两段展示轮播,两段各调各的接口,返回空数组就隐藏对应轮播。
| 接口 | 说明 |
|---|---|
GET /in/wx/mall/homeBanner/manual | 自建商品线(MANUAL)轮播 |
GET /in/wx/mall/homeBanner/miguoma | 胖哥商品线(MIGUOMA,米果码推送)轮播 |
两个接口均无入参,按 ID 倒序返回数组。出参元素(HomeBanner):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 轮播ID |
| name | string | 标题 |
| images | array | 轮播图 [{url,name}],多张按上传顺序,展示取第一张即可 |
| type | string | 轮播类型:MANUAL-自建商品,MIGUOMA-胖哥商品(与所在接口一致,调试用) |
| mallGoodsId | long | 关联商品ID,当前恒为空(预留字段),轮播暂不支持点击跳商品 |
后台在「首页管理 → Banner管理」维护,新增/修改时选择「轮播类型」;历史数据全部归入自建商品线(MANUAL),首页 /homeBanner 行为不变。
2.5 商品分类列表(新增分类图片)
GET /in/wx/mall/mallGoodsType
无入参,按创建时间倒序返回全部分类。出参元素(MallGoodsType):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 分类ID |
| goodsTypeName | string | 分类名称 |
| image | object/null | 分类图片(新增):{name, url};未上传为 null,为空时前端隐藏图片位、按纯文字展示 |
| createTime | string | 创建时间 |
分类图片在后台「商品分类」里上传维护,小程序分类列表用它做封面即可。
三、每日签到
3.1 签到
POST /in/wx/sign/in
无入参。同一用户同一天天然幂等(重复调用返回已签结果,不会重复发分)。
活动总开关关闭时返回业务错误 签到活动暂未开启,请稍后再来。
出参 data:
| 字段 | 类型 | 说明 |
|---|---|---|
| dayIndex | int | 本次是周期内第几天(1~7,对应规则第 N 天) |
| integral | decimal | 本次到账积分 |
| repeated | boolean | 是否重复签到(true 时积分已发过,前端提示"今天已签到"即可) |
3.2 今日签到状态
GET /in/wx/sign/status
出参 data:
| 字段 | 类型 | 说明 |
|---|---|---|
| signedToday | boolean | 今天是否已签 |
| enabled | boolean | 签到活动总开关,false 时隐藏签到入口并提示活动未开启 |
| currentDayIndex | int | 当前进行到第几天 |
| todayIntegral | decimal | 今天签到可得积分(规则缺失时为 null) |
3.3 月签到日历
GET /in/wx/sign/calendar?month=2026-09
month 格式 yyyy-MM,不传默认当月。出参 data:已签到日期数组,如 ["2026-09-01","2026-09-02"]。
3.4 签到规则
GET /in/wx/sign/rule
出参 data.items:[{ dayIndex: 1, integral: 1 }, ...](7 天周期,用于签到页展示"第 N 天 +X 分")。
四、积分抽奖
4.1 抽奖页信息(进页面先调)
GET /in/wx/lottery/info
出参 data:
| 字段 | 类型 | 说明 |
|---|---|---|
| activityId | long | 活动ID |
| name | string | 活动名 |
| ruleText | string | 活动规则文案(直接展示) |
| costIntegral | decimal | 单次抽奖消耗积分 |
| dailyLimit | int | 每日限抽次数 |
| remainCount | int | 我今天剩余次数 |
| myBalance | decimal | 我的积分余额 |
| prizes | array | 8 格奖品配置,sortNo 0~7 固定顺序 |
prizes[] 元素:
| 字段 | 类型 | 说明 |
|---|---|---|
| sortNo | int | 转盘格子序号 0~7 |
| name | string | 奖品名 |
| prizeType | string | PHYSICAL / INTEGRAL / THANKS |
| integralAmount | decimal | 积分类奖品的分值 |
| image | string | 奖品图 |
| winRatePercent | decimal | 中奖率(百分数,按用户要求 C 端公示);为 0 表示占位格,转盘照常渲染但永远不会被抽中 |
4.2 抽奖
POST /in/wx/lottery/draw
无入参。按用户+日期加了分布式锁,重复点击会得到"抽奖处理中,请稍后重试"。
出参 data(中奖格子):
| 字段 | 类型 | 说明 |
|---|---|---|
| sortNo | int | 命中格子序号(转盘动画转到这格),不会落在权重 0 的占位格上 |
| prizeId | long | 奖品ID |
| prizeType | string | 同上 |
| prizeName | string | 奖品名 |
| integralAmount | decimal | 积分类奖品分值 |
| remainCount | int | 抽后今日剩余次数 |
| recordId | long | 本次中奖记录ID(新增),抽中实物时凭它调 4.5 填收货信息 |
业务失败(积分不足 / 次数用完 / 无进行中活动)会返回非 0 code + 用户可读 msg,直接 toast。
4.3 我的中奖记录
GET /in/wx/lottery/my-records
出参 data:数组,元素:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 中奖记录ID(新增,填收货信息用) |
| prizeName / prizeImage | string | 奖品名/图 |
| prizeType | string | PHYSICAL / INTEGRAL / THANKS |
| integralAmount | decimal | 积分类奖品分值 |
| verifyStatus | int | 0-待核销(实物,线下找客服核销)、1-已核销/无需核销 |
| receiverName / receiverPhone / receiverAddress | string | 收货信息(新增,仅实物有值),空 = 还没填,展示「填写收货信息」入口 |
| createTime | string | 中奖时间 |
4.4 中奖公示
GET /in/wx/lottery/winners?limit=20
出参 data:[{ nickname, prizeName, createTime }]。谢谢参与不进公示,昵称已脱敏,直接展示。
4.5 填写 / 修改实物收货信息(新增)
POST /in/wx/lottery/receiver
仅限本人的实物奖品记录;可反复调用覆盖修改(已核销也允许改)。
入参(JSON,二选一模式):
| 字段 | 类型 | 说明 |
|---|---|---|
| recordId | long | 中奖记录ID,必填(4.2 draw 返回的 / 4.3 列表里的 id) |
| addressId | long | 模式一:传收货地址簿 ID,直接引用地址簿(姓名/电话/地址以地址簿为准,无需再传下面三个字段);地址簿必须是本人的 |
| receiverName | string | 模式二:手填。收货人姓名,必填,≤50 字 |
| receiverPhone | string | 模式二:手机号,必填,后端校验格式 |
| receiverAddress | string | 模式二:详细地址,≤200 字,可不填(线下发放场景) |
出参 data:无内容(成功即可)。收货信息错误口径(toast):中奖记录不存在 / 无权操作他人的中奖记录 / 仅实物奖品需要填写收货信息 / 收货人姓名不能为空 / 手机号格式不正确 / 收货地址长度不能超过200个字符 / 收货地址不存在 / 无权使用此收货地址。
前端建议:抽中实物的结果弹窗上放「填写收货信息」,优先让用户选地址簿(模式一),没有合适地址再手填(模式二);「我的中奖记录」里实物未填收货的持续提示。
五、客服咨询
按商品来源分两条线:MANUAL 自建商品(甲方客服)、MIGUOMA 米果码商品(我方客服),用户无感知,后端按上下文自动分流。不做 WebSocket,消息用轮询。
5.1 开启 / 进入会话
POST /in/wx/kefu/session/open
入参(JSON,均可选,按入口传):
| 字段 | 类型 | 说明 |
|---|---|---|
| goodsId | long | 从商品详情进线时传 |
| goodsSpecId | long | 从商品详情(已选规格)进线时传 |
| orderId | long | 从订单详情进线时传 |
| sourceType | string | 兜底指定业务线(一般不用传;有订单/商品时后端自动判定) |
行为:已有进行中会话则复用(并把新的商品/订单上下文挂上去),新会话自动发一条系统欢迎语。
出参 data:
| 字段 | 类型 | 说明 |
|---|---|---|
| sessionId | long | 会话ID,后续收发消息都用它 |
| sourceType | string | 分流结果 |
| agentName / agentAvatar | string | 坐席名片 |
| welcomeMsg | string | 欢迎语 |
| contextGoodsName / contextGoodsImage | string | 关联商品摘要(进聊天页顶部展示) |
| contextOrderNo | string | 关联订单号 |
5.2 我的会话列表
GET /in/wx/kefu/session/myList
出参 data:会话数组(元素见下)。用户一般只有 1~2 条(每条业务线一条)。
会话元素(KefuSessionVO):id, maOpenid, userNickname, userAvatar, sourceType, agentName, goodsId, orderId, status(OPEN/CLOSED), lastMessageContent, lastMessageTime, unreadUserCount(用户未读), unreadAgentCount(坐席未读), createTime。
5.3 拉取消息(初次 + 轮询同一个接口)
GET /in/wx/kefu/message/list?sessionId=&lastMessageId=
| 参数 | 说明 |
|---|---|
| sessionId | 会话ID |
| lastMessageId | 可选。不传:取最近 50 条(进聊天页);传上次拿到的最大消息ID:增量拉取(轮询) |
出参 data:按时间升序的消息数组:
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 消息ID(轮询游标) |
| sessionId | long | 会话ID |
| senderType | string | USER / AGENT / SYSTEM |
| senderName | string | 发送者昵称 |
| contentType | string | 目前只有 TEXT |
| content | string | 文本内容 |
| auditStatus | string | REJECT 时内容已被后端替换为"【该内容涉及违规敏感信息,已被拦截】",照常渲染即可 |
| isSelf | boolean | 是否本人发的(决定气泡左右) |
| createTime | string | 时间 |
轮询建议:聊天页可见时每 3~5 秒调一次增量接口;拉到新消息后更新本地 lastMessageId = max(id)。会话列表未读数在拉取消息后后端会自动清零。
5.4 发送消息
POST /in/wx/kefu/message/send
入参:
| 字段 | 类型 | 说明 |
|---|---|---|
| sessionId | long | 会话ID,必填 |
| content | string | 文本内容,必填 |
| contentType | string | 可选,默认 TEXT |
| clientMsgId | string | 建议必传:客户端生成的 UUID,弱网重发时后端按它去重,避免重复消息 |
出参 data:落库后的消息(结构同 5.3 元素),直接 append 到消息流。
内容经微信 msgSecCheck 审查,违规时返回非 0 code("发送内容包含违规或敏感信息,已被系统拦截")。
5.5 坐席身份(个人中心是否显示"客服工作台"入口)
GET /in/wx/kefu/agent/identity
出参 data:{ isAgent, sourceType, agentName, avatar }。isAgent=true 时展示工作台入口。
5.6 小程序坐席接待(客服工作台页)
- 待接待列表:
GET /in/wx/kefu/agent/sessions→ 本业务线的会话数组(结构同 5.2),按最新活跃倒序。 - 拉消息 / 回复:同 5.3 / 5.4(后端自动按身份识别为坐席)。
- 非坐席调用 5.6 会返回"您暂无坐席接待权限"。
5.7 已知报错口径(直接 toast)
| 场景 | msg |
|---|---|
| 黑名单用户 | 您的账号存在风险,已被限制使用客服功能 |
| 该业务线未配置坐席 | 暂无可用客服坐席,请稍后重试 |
六、订单物流轨迹
6.1 查询订单物流
GET /in/wx/mall/orderTrace/{orderId}
只能查自己的已发货订单;订单未发货 / 缺单号会返回非 0 code("订单尚未发货,暂无物流轨迹"等)。
出参 data:
| 字段 | 类型 | 说明 |
|---|---|---|
| shipperCode | string | 快递公司编码(SF/YTO/ZTO…) |
| shipperName | string | 快递公司名 |
| logisticCode | string | 运单号(可一键复制) |
| state | string | 快递鸟状态码 0在途/1揽收/2疑难/3已签收/4退签/5派件/6退回 |
| stateDesc | string | 状态描述 |
| traces | array | 轨迹节点,按时间升序 |
traces[] 元素:{ acceptTime, acceptStation, remark }。
前端交互:订单详情"查看物流"入口 → 时间线展示 traces(建议倒序展示,最新在上)。联调注意:快递鸟账号还没买(国庆后),买好前调用会返回"快递鸟账号尚未配置…"的报错,前端做好兜底提示。
6.2 订单接口新增字段
GET /in/wx/mall/myOrders / GET /in/wx/mall/orderDetail/{orderId} 出参新增:
| 字段 | 类型 | 说明 |
|---|---|---|
| afterSaleStatus | string | 售后状态,见 1.5;空 = 未申请过售后 |
| afterSaleStatusDesc | string | 状态描述(待审核/待退款/已退款/已驳回/已撤销) |
| expressCompanyCode | string | 快递公司编码(如 SF),未发货为空 |
| expressCompanyName | string | 快递公司名(后台发货自动识别) |
| logisticsNumber | string | 运单号,可一键复制 |
| logisticsState | string | 物流状态码:0 无轨迹 / 1 已揽收 / 2 在途中 / 3 已签收 / 4 问题件;未发货为空 |
| logisticsStateDesc | string | 状态中文,直接展示 |
订单列表/详情页据此展示"退款中/已退款"角标;afterSaleStatus 为空且已支付时展示"申请售后"入口。已发货订单直接用 logisticsNumber + logisticsStateDesc 展示物流卡片,点「查看物流」再调 6.1 拉轨迹。
6.3 修改订单收货地址(新增)
POST /in/wx/mall/updateOrderAddress
仅未发货的本人订单可改,已发货/已完成返回业务错误。
入参:
| 字段 | 类型 | 说明 |
|---|---|---|
| orderId | long | 订单ID,必填 |
| areaCode | array | 省市区编码 ["440000","440100","440106"] |
| areaName | array | 省市区名称 ["广东省","广州市","天河区"] |
| username | string | 收货人姓名 |
| phone | string | 收货人手机号 |
| address | string | 详细地址 |
出参 data:无内容。地址编辑页复用下单页的同一套表单(区域树 GET /in/wx/mall/areaTree)。
七、售后退款
流程:未发货且无金额的订单申请 → 系统自动通过(积分立即退回)→ 现金由我方在管理后台点击退款(调微信商户平台接口)→ 已退款;含金额订单(未发货也不自动通过)与已发货订单申请 → 人工审核 → 通过后退积分、现金同上 → 已退款(已发货需凭证 + 说明必填)。驳回 / 待审核阶段用户可撤销(撤销仅限待审核)。
7.1 上传凭证图片(先传图再申请)
POST /in/wx/maUser/uploadLocal
- 表单字段名:
multipartFile(文件) - 出参
data:{ url, name }→ 直接塞进申请的evidenceImages数组。
7.2 提交售后申请
POST /in/wx/afterSale/apply
入参:
| 字段 | 类型 | 说明 |
|---|---|---|
| orderId | long | 订单ID,必填 |
| applyRemark | string | 申请说明。已发货(退货退款)必填 |
| evidenceImages | array | 凭证图片 [{url,name}]。已发货必传 |
售后类型不用传,后端按发货状态自动判定(未发货=仅退款,已发货=退货退款)。
出参 data(申请结果):
| 字段 | 类型 | 说明 |
|---|---|---|
| id | long | 售后单ID |
| orderId | long | 订单ID |
| afterSaleType / afterSaleTypeDesc | string | 售后类型 |
| status / statusDesc | string | 申请后状态:未发货且无金额的单直接 APPROVED 待退款;含金额单与已发货单 PENDING 待审核 |
| integralRefund / moneyRefund | decimal | 应退积分 / 应退现金 |
| goodsName / goodsImage / exchangeNum | - | 商品摘要 |
| auditRemark / auditTime | string | 审核意见与时间 |
业务失败示例(toast 即可):该订单已有处理中的售后申请 / 订单未支付 / 已超过售后申请时效(发货后 30 天内可申请)/ 退货退款需上传凭证图片。
7.3 我的售后列表
GET /in/wx/afterSale/myList?page=1&limit=10&status=
status 可选(见 1.5)。出参分页,list 元素同 7.2 出参。
7.4 售后详情
GET /in/wx/afterSale/detail/{id}
出参同 7.2(含审核意见、退款时间),只能查自己的。
7.5 撤销申请
POST /in/wx/afterSale/cancel/{id}
仅 PENDING 待审核 可撤销,其他状态返回"售后申请已进入处理流程,无法撤销"。撤销后可重新申请。
八、联调注意事项(后端侧已知状态,2026-10-12 上线日刷新)
- 快递鸟未开通:物流轨迹接口在配置填好前统一报"快递鸟账号尚未配置…",买好账号在
application.yml的kdniao段填上即生效,接口不变。订单上的logisticsState/Desc字段同理(未发货/无轨迹为空)。 - 客服坐席未绑定:现网
kefu_agent两条默认坐席还没绑人,用户能建会话、能发消息,但坐席端收不到(后台没人接待)。联调客服请在后台「坐席配置」先绑一个maOpenid。 - 抽奖活动时间窗:奖位 8 格已配齐且后端全流程实测过(抽奖/收货信息/核销)。当前「国庆抽奖」活动结束时间为 2026-10-11(已过),C 端 info 会得到空活动、draw 报"活动未开始或已结束"——联调前在后台「抽奖活动」把结束时间改到未来即可,改完即时生效,无需重启后端。签到规则已配 7 条可直接用。
- 售后现金退款:由我方在管理后台人工点击执行(调微信商户平台退款接口),小程序端只需展示状态流转,不做任何支付相关调用。
- 枚举与文案:所有
*Desc字段都是后端拼好的中文,直接展示;新增枚举值前会同步本文档。 - 混合支付待实测:混合支付改造已完成编码并随 mall2.0 上线,现网需小额实测一轮「下单 → 支付 → 回调 → 取消 → 退款」后再放开。见第九章。
九、积分 + 现金混合支付(2026-09-30 改造)
定价规则(后台配置,C 端无需处理):米果码商品仅积分兑换(保持现状,规格金额恒为 0);自建商品支持「积分 + 现金」混合价,规格的 integralCost 与 moneyCost 均为手工维护。
9.1 下单兑换(接口不变,返回结构扩展)
POST /in/wx/mall/exchange,入参不变。出参 data 扩展:
| 字段 | 类型 | 说明 |
|---|---|---|
| orderId | long | 订单ID(新增;凭此轮询支付状态、继续支付) |
| needPayFlag | boolean | true=含现金需拉起微信支付;false=纯积分订单已直接完成(PAID) |
| jsapiResult | object | 仅 needPayFlag=true 时返回,wx.requestPayment 所需参数(timeStamp/nonceStr/package/signType/paySign),直接透传 |
C 端流程:needPayFlag=true → 拿 jsapiResult 调 wx.requestPayment → 成功后轮询 GET /in/wx/mall/refreshPayStatus/{orderId} 直到 paymentFlag=PAID;取消/失败可调 9.2 重新拉起,或 POST /in/wx/mall/cancelOrder/{orderId} 取消(积分自动原路退回)。
9.2 继续支付(新增)
POST /in/wx/mall/repay/{orderId}
仅「未支付 UNPAID 且含现金」的本人订单可调,返回结构同 9.1(needPayFlag 恒为 true,含新的 jsapiResult)。支付参数丢失、收银台中途关闭时用。
9.3 取消与超时语义(重要)
- 含现金的未支付订单取消时,后端会先关闭微信侧支付单再退积分;若用户恰好在取消瞬间完成支付(并发撞车),订单保持已取消,后端收到回调后自动原路退款,C 端无需处理,钱 1-3 个工作日退回。
- 未支付订单超 60 分钟由系统自动取消并退积分(原有逻辑不变)。
- 已支付且含现金的订单不可自行取消(原有限制),走售后流程。
9.4 订单接口字段
myOrders / orderDetail 出参中 moneyCost(订单现金部分,元)此前恒为 0,混合支付上线后可能大于 0,展示「积分 xx + ¥xx」;其余字段不变。