# 微信小程序团购服务 — 商家接入指引
商家通过 POI 挂载「团购优惠」服务,需完成以下核心步骤:
- 认领微信位置及关联小程序:微信位置运营 | 微信开放文档
- 挂载团购服务:规范团购下单页路径 → 接入退款能力 → 接入核销组件 → 创建服务 → 授权账期管理。
通过审核后,你的微信位置页将展示「团购优惠」入口,点击后可跳转至团购页面。未完成审核挂载前,可先使用核销组件的调试预览模式完成组件开发和审核截图准备。
# 一、规范团购页面路径
- 区分两种页面路径
| 路径类型 | 用途 | 填写建议 |
|---|---|---|
| 服务页面路径 | 用户在 POI 页点击「团购优惠」后进入的小程序页面 | 多个套餐可填团购列表页;只推广一个套餐可填该套餐详情页 |
| 团购下单页面路径 | 平台识别团购订单所使用的统一支付页路径 | 所有套餐共用一个页面路径,通过不同参数区分套餐 |
- 统一团购下单页面路径
平台通过「团购下单页面路径(path)」来识别哪些订单属于团购订单。因此你需要确保:小程序内所有团购套餐的下单页面,都必须通过参数挂载在同一个页面路径下。
正确示例:
提审填写的团购下单页面路径为:page/groupbuy/pay
- 套餐 A 的下单链接:
page/groupbuy/pay?id=283✅ 正确 - 套餐 B 的下单链接:
page/groupbuy/pay?id=456✅ 正确
错误示例:
- 套餐 C 的下单链接:
page/shopping/pay?id=789❌ 路径不一致,无法识别
注意:如果有团购套餐的下单页不在提审路径下,审核将被驳回。
新增套餐怎么办?
新增团购套餐只需通过不同的参数(如 ?id=新ID)挂载在同一个页面路径下即可,无需重新提审。
# 二、接入退款能力(随时退 & 过期退)
为保障消费者权益,商家必须接入平台提供的退款接口,实现以下两种退款能力:
| 退款类型 | 说明 | 商家需做 |
|---|---|---|
| 随时退 | 用户在有效期内未核销,可随时申请退款 | 在购买成功页面提供退款入口,用户申请后调用退款接口 |
| 过期退 | 团购券超过有效期未核销,自动退款给用户 | 根据有效期字段,到期后需商家调用退款接口退款 |
页面要求:
- 团购详情页需展示「随时退」「过期退」标识
- 支付成功后的订单详情页需包含「申请退款」入口
# 三、接入核销组件
平台提供标准化的「用户二次确认核销组件」,确保用户到店消费时可安全核销。
用户在组件中确认后,平台侧完成核销确认并进入资金解冻流程;商户侧订单是否已核销,仍由商户扫码及自己的订单系统管理。
1. 请求核销接口:
开发者可通过调用 wx.openBusinessView 方式在本小程序打开团购核销组件,让用户完成团购券确认核销操作。
通过审核并正式挂载到 POI 前,订单尚不能按团购订单识别,直接请求核销可能报错或使组件静默关闭。此阶段请通过调试预览模式完成联调并获取审核截图,请查看调试预览模式章节了解。
核销接口参数
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
businessType | string | 是 | 固定配置:weappOrderConfirm |
extraData | object | 是 | 用于向组件传递团购核销信息;通过 transaction_id 唯一指定订单,通过 group_buy_item 传递团购商品详情。 |
extraData 字段:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
transaction_id | string | 是 | 真实的用户交易单号。正式核销和调试预览都需要传入真实订单,调试模式可以传入任意类型的真实订单,正式核销场景需要传入真实团购订单,否则会返回失败信息。 |
group_buy_item | GroupBuyItem | 是 | 团购商品详情,见下方数据结构说明 |
GroupBuyItem 数据结构
group_buy_item 为团购商品详情,由开发者组装并通过 extraData 传入,包含团购券信息 coupon 和套餐分组 packages 两部分。
coupon 团购券信息:
| 属性 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
name | string | 是 | 团购名称,≤ 30 字 | '【双人实惠】烤全鱼双人餐' |
quantity | number | 是 | 券数量,≥ 1;多券时一次性全部核销,不支持部分核销 | 1 |
original_price | number | 是 | 原价,单位为分;必须 ≥ 实付金额 | 29800 |
paid_amount | number | 是 | 实付金额,单位为分;需与订单实际支付金额一致 | 19900 |
valid_until | number | 是 | 有效期至,Unix 时间戳(秒级);过期后核销将返回失败 | 1788769682 |
packages 套餐分组:
| 属性 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
group_name | string | 是 | 分组名称,≤ 20 字 | '招牌' / '小食' |
select_type | number | 是 | 1=固定包含,2=N 选 1,3=N 选几;仅用于展示,用户无需选择 | 1 |
select_count | number | 否 | select_type=3 时必填,表示可选数量;必须小于本组餐品总数 | 2 |
items | PackageItem[] | 是 | 分组下的餐品列表 | [{ name: '烤全鱼', quantity: 1 }] |
PackageItem 餐品信息:
| 属性 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
name | string | 是 | 餐品名称,只填写菜品名称,≤ 30 字 | '烤全鱼' |
quantity | number | 是 | 份数,≥ 1 | 1 |
核销组件回调
组件通过 wx.navigateBackMiniProgram 回调小程序,开发者可以通过 App.onShow 处理回调参数。
回调参数位于 referrerInfo,其中 appId 固定为 wx1183b055aeec94d1,extraData 定义如下:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
status | string | 是 | success:核销成功/预览模拟成功;fail:组件内查单、参数校验或核销失败;cancel:用户取消 |
errormsg | string | 否 | 当 status=fail 时返回具体失败原因 |
req_extradata | any | 是 | 开发者调用组件时传入的完整原始 extraData,原样返回 |
常见组件内业务结果
以下结果均表示组件已经成功拉起,调用方通过 App.onShow 接收回调。页面表现 描述的是组件内用户看到的内容。
| 场景 | status | errormsg | 页面表现 |
|---|---|---|---|
| 缺少有效订单号 | fail | invalid order info | 提示「无有效订单信息」 |
| 未查询到对应订单 | fail | order not found | 提示「获取用户订单失败」,请先检查对应商户号是否已完成账期授权。 |
缺少 group_buy_item | fail | missing group_buy_item | 提示「团购订单缺少商品信息」 |
group_buy_item 结构无效 | fail | invalid group_buy_item | 提示「团购商品信息无效」 |
| 正式模式传入团购参数但查到非团购订单 | fail | not groupbuy order | 静默关闭,不展示 Toast,建议开发者自行衔接原有展码页面 |
| 实付金额不一致 | fail | paid_amount mismatch | 提示「传入的实付金额与微信支付订单实付金额不一致,无法发起核销」 |
| 团购券已过期 | fail | coupon expired | 提示「团购券已过期」 |
| 团购券已核销 | fail | already verified | 提示「该团购券已核销」 |
| 正式核销接口返回成功 | success | 无 | 提示「核销成功」 |
| 用户关闭主半屏 | cancel | 无 | 直接关闭 |
需注意:非调试模式下,如果传入了 group_buy_item,但真实订单不是团购订单,组件会静默关闭并返回,开发者需要自行处理非团购订单场景的后续逻辑,建议自行衔接原有展码流程。开发者可以在回调中接收:
{
status: 'fail',
errormsg: 'not groupbuy order'
}
核销示例代码
// 组装团购商品详情
const groupBuyItem = {
coupon: {
name: '【双人实惠】烤全鱼双人餐',
quantity: 1,
original_price: 29800, // 单位:分,即 ¥298.00
paid_amount: 19900, // 单位:分,即 ¥199.00,需与订单实付金额一致
valid_until: 1788519809
},
packages: [
{
group_name: '招牌',
select_type: 1,
items: [{ name: '烤全鱼', quantity: 1 }]
},
{
group_name: '小食',
select_type: 3,
select_count: 2,
items: [
{ name: '薯条', quantity: 1 },
{ name: '鸡米花', quantity: 1 }
]
}
]
}
wx.openBusinessView({
businessType: 'weappOrderConfirm',
extraData: {
transaction_id: '420123123123123123123',
group_buy_item: groupBuyItem,
},
success() {
// do something
},
fail() {
// do something
},
complete() {
// do something
}
})
// 响应组件回调
App({
onShow(options) {
// do something
}
})
调试预览模式
调试预览模式用于审核通过前的组件联调,以及挂载团购服务所需的审核截图。请求参数和业务回调沿用上一节的接口定义,按以下方式开启调试模式。
调用 wx.openBusinessView 时,在 extraData 中传入精确值 mode: 'dev' 即可开启调试预览模式;正式上线前需要删除该参数。
extraData 字段新增调试字段:
| 属性 | 类型 | 说明 |
|---|---|---|
mode | string | 仅未完成 POI 准入流程时调试使用,传入精确值 'dev' 时开启调试预览模式;未传或传入其他值时走正式流程,正式上线需要删除该参数。 |
调试预览模式不会发生真实核销,但仍会使用 transaction_id 查询真实订单,并校验传入的套餐、金额和过期时间;但是会跳过真实订单是否属于团购订单以及订单状态校验。
用户点击「确认」后,组件会返回模拟成功事件:
{
status: 'success',
simulated: true,
}
调用方可以通过 simulated === true 判断是否为模拟结果。调试预览模式与正式核销模式均返回 status: 'success'。
调试预览模式的调用示例:
wx.openBusinessView({
businessType: 'weappOrderConfirm',
extraData: {
transaction_id: '420123123123123123123',
group_buy_item: groupBuyItem,
mode: 'dev',
},
success() {
// do something
},
fail() {
// do something
},
complete() {
// do something
}
})
调试预览模式下,用户在二次确认页点击「确认」后,页面提示「模拟核销成功」,并通过 App.onShow 回调:
| 场景 | status | simulated | 页面表现 |
|---|---|---|---|
| 调试预览二次确认点击「确认」 | success | true | 提示「模拟核销成功」 |
2. 建议接入方式:
① 用户进入订单详情页,点击「确认核销/获取二维码」。
② 商家调用接口请求核销,展示二次确认组件。 用户在组件上确认套餐信息无误,点击「确认」
③ 确认成功后,小程序向用户展示核销二维码,商户扫码后成功核销,由商户系统记录实际消费及核销状态。
④ 平台收到用户确认事件后,资金按 T+3 解冻给商户号。
⚠️ 注意:平台必须收到用户确认事件,才能完成平台侧核销并按规则解冻。
建议将二次确认放在展码前;如果先展码、商户已扫码但用户未确认,资金将无法按该核销链路解冻。
3. 套餐变更提示:
若套餐内容有变更,商家需同步更新二次确认组件中的字段和套餐详情页,并与用户沟通确认。平台以核销时组件上展示的信息为准处理纠纷。
4. 购买数量与核销的限制
因微信支付首期仅支持整笔订单统一冻结和打款,暂不支持分次核销(即一笔订单购买多张券后分批到店使用)。建议你在开发团购时将每个订单的购买数量限制为 1 张;若用户需购买多张,可引导其分多次下单。
# 四、创建团购服务
1. 特别说明:
- 目前首期支持「美食」一级类目
- 创建服务前,请先完成「微信位置认领」及「关联小程序账号」,详情参考:微信位置运营 | 微信开放文档
- 账期授权入口仅面向已认领 POI 且提交团购审核的小程序展示。若看不到「已关联商户号」或账期授权入口,请先确保已提交团购服务审核。
2. 创建服务操作步骤:
① 进入「微信位置管理」小程序,点击「服务管理 - 创建服务」
② 选择服务类型为「团购优惠」,填写小程序及服务页面路径(用户从 POI 入口进入的小程序页面)
③ 填写「团购下单页面路径」:所有团购套餐挂载的统一下单页路径
④ 上传「团购流程截图」并提交审核。此时尚未完成正式审核挂载,请使用核销组件的调试预览模式获取核销组件截图。
⑤ 服务进入审核流程后,登录 MP 后台「支付与交易 - 微信支付」,即可查看「已关联商户号」与账期授权入口,并按第五章完成授权。审核通过并正式挂载后,再切换到线上验证核销。
3. 团购流程截图要求:
| 截图内容 | 数量 | 要求 |
|---|---|---|
| 含「随时退」「过期退」标识的团购详情页 | 1 张 | 需清晰展示相应标识 |
| 含「申请退款」入口的已支付订单详情页 | 1 张 | 需展示退款入口 |
| 核销流程页面(获取二维码 → 用户二次确认 → 展码) | 3 张 | 需包含完整核销链路;可使用调试预览模式准备核销组件截图。 |
注意:所有截图需包含小程序名称或 AppID 以验证真实性。截图不清晰或信息不完整将被驳回。
# 五、授权账期管理
1. 什么是账期管理?
为保障消费者权益,团购订单的资金不会立即到账,而是在核销成功后才解冻打款给商家。
默认规则:团购订单资金默认冻结 90 天。核销成功后,资金将在 T+3 个工作日解冻打款至你的商户号账户。
2. 如何授权?
小程序需属于美食类目,且已手动认领 POI 并提交团购服务审核,才展示账期授权入口。
注:如通过支付服务商接入微信支付,请在授权前告知服务商,当前小程序正接入餐饮团购,将涉及账期管控,避免误判为实物电商。
尚未看到入口的餐饮小程序,应先认领 POI、关联小程序、并提交团购服务审核;进入审核流程后,再进行以下操作:
① 登录微信小程序管理平台
② 进入「支付与交易 - 微信支付」
③ 找到对应「已关联商户号」,在 MP 后台逐个点击授权,对应商户号超级管理员在移动端确认授权申请。
说明:如果你的小程序/服务商此前已经授权过「交易结算管理」,则无需重复操作,系统会自动识别为已授权。
3. 商户类型说明:
| 商户类型 | 授权方式 |
|---|---|
| 直联商户 | 在小程序 MP 后台逐个点击授权,对应商户号超级管理员在移动端确认授权申请。 |
| 间联商户(普通服务商) | 在小程序 MP 后台逐个点击授权,对应商户号超级管理员在移动端确认授权申请。 |
| 间联商户(银行、第三方支付机构等) | 需对应支付机构与微信支付线下签约授权,授权后机构代开的所有商户号均支持。授权前,请先联系你对应的支付机构,告知当前在接入餐饮团购,会进行账期授权和管控。 |
4. 账期解冻完整规则:
| 情况 | 冻结时长 | 资金去向 |
|---|---|---|
| 核销成功 | 核销后 T+3 | 打款给商家 |
| 有效期内用户退款 | 即时 | 退还用户 |
| 有效期内商户退款 | 即时 | 退还用户 |
| 超有效期自动退 | 有效期满 | 退还用户 |
| 兜底:平台自动退 | 满 90 天 | 退还用户 |
# 六、(可选)接入小程序订单展示功能
1. 这个功能有什么用?
接入后,顾客在你小程序里下的每一笔团购订单,都会自动同步到微信「我 - 小店与卡包 - 小程序购物订单」中。顾客可以在这里集中查看所有订单,包括:
- 订单列表和商品描述
- 支付时间、支付金额、退款金额、交易单号
- 每个订单都配有「前往小程序」按钮,点击后直接跳转到你小程序里对应的订单详情页
顾客查单更方便,你也少接「我的订单在哪」这类咨询。
2. 接入流程
第一步:签署授权协议
进入小程序管理后台 - 订单管理,找到订单中心相关入口,完成授权协议签署。签署后才能进行后续配置。
第二步:配置订单跳转路径
方式 01:在小程序管理后台配置订单跳转路径
授权完成后,在小程序管理后台配置订单详情路径。这个路径就是顾客在「小程序购物订单」中点击「前往小程序」时,要跳转到的小程序页面。
路径需要包含 ${商品订单号} 这个固定占位符。举个例子,如果你的订单详情页路径是 pages/order/detail/index,接收一个名为 orderId 的参数,那么配置的路径应该是:
pages/order/detail/index?orderId=${商品订单号}
方式 02:调用 API 接口配置订单跳转路径
如果你是由服务商代为操作,或者希望通过代码自动化管理,可以通过以下接口来配置:
POST https://api.weixin.qq.com/wxa/sec/order/update_order_detail_path?access_token=ACCESS_TOKEN
请求参数:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
| path | string | 是 | 订单详情路径 |
请求示例:
{
"path": "pages/index/index?id=${商品订单号}"
}
返回示例(成功):
{
"errcode": 0,
"errmsg": "ok"
}
常见错误码:
| 错误码 | 含义 | 解决方法 |
|---|---|---|
| -1 / 10060012 | 系统繁忙 | 稍后重试 |
| 10060034 | 授权协议未签署 | 先完成第一步的授权签署 |
| 10060035 | path 有误 | 检查路径格式是否正确 |
| 10060036 | 编码问题 | 确保使用 UTF-8 编码 |
该接口所属权限集 ID 为 182,服务商获得授权后可使用
authorizer_access_token代商家调用。
第三步:下单时给微信支付传入商品描述和订单号
在下单时(使用 JSAPI 或小程序支付接口 JSAPI/小程序下单),需要在接口中传入两个关键字段:
| 字段 | 作用 |
|---|---|
| description | 作为商品描述,展示在「小程序购物订单」的订单列表和详情页中,让顾客一眼看出买了什么 |
| out_trade_no | 你的商品订单号,用于实现跳转——当顾客点击「前往小程序」时,系统会自动把路径中的 ${商品订单号} 替换为该订单的真实 out_trade_no |
# 七、常见问题
1. MP 后台为什么看不到已关联商户号或账期授权入口?
入口展示有前置条件:小程序需属于「美食」类目,且已手动认领 POI 或已自动匹配到 POI。看不到入口的餐饮小程序,完成技术改造后先认领 POI、关联小程序并提交「团购优惠」服务审核;进入审核流程后,即可登录 MP 后台「支付与交易 - 微信支付」查看商户号并授权。
2. 审核前无法使用正式核销组件 如何准备审核截图?
审核通过并正式挂载到 POI 前,订单尚不能按正式团购订单识别,直接以正式模式调用可能报错或静默关闭。请在 extraData 内传入 mode: 'dev',通过调试预览模式获取截图后提交审核。调试仍需真实交易单号、匹配的实付金额和未过期的有效期;审核通过并挂载团购优惠在 POI 后,再验证正式流程。
3. 核销组件返回not groupbuy order 怎么处理?
表示传入订单不是团购订单,资金不会按团购规则冻结;组件会静默关闭。常见原因包括未通过审核挂载到 POI、未授权账期或小程序类目非餐饮。开发者需在 App.onShow 中处理该返回,自行衔接原有展码流程。
4. 核销组件返回 order not found 怎么处理?
多数是小程序未授权账期管理,订单未同步到团购侧。请先在 MP 后台完成对应商户号的账期授权;服务审核通过并正式挂载后,用新下单的团购订单验证。
5. 用户确认后为何商户订单仍显示待核销?
用户确认触发的是平台侧核销与后续解冻流程;商户订单状态由商户自己的系统管理。用户确认后仍需商户扫码消费,再更新商户侧核销状态。
6. 用户确认后没有扫上码怎么办?
若尚未被商户扫码核销,应允许用户再次获取有效核销码。检查小程序是否将展码错误地限制为一次,以及扫码结果是否正确同步到订单;不要将重新展码等同于重新发起平台核销。
7. 团购订单产生交易纠纷如何处理?
可参考:小程序交易投诉开发者处理流程指引。
8. 如何查询小程序是否已完成账期授权?
可使用接口查询:查询小程序是否已完成交易结算管理确认
# ✓ 联系我们
接入中有任何疑问,可扫码添加以下企业微信进行咨询。
添加时,请简述你遇到的问题+小程序appid
