微信小程序怎么接入美团团购核销?为什么要接、如何落地
在第一篇《微信小程序怎么接入美团、抖音团购核销?申请步骤、材料与成本对比》中,我们比较了自行申请平台能力和通过三方服务商接入需要准备的材料、时间与成本。
如果已经决定通过三方服务商接入,下一步就是判断为什么要优先接美团,并把团购核销真正接进自己的微信小程序。本文只讲美团:小程序负责选店、输码和确认,自己的业务服务端负责用户权限、门店映射与权益,无限聚核负责连接美团授权及核销接口,再把结果返回业务系统。

阅读导航
一、为什么值得优先接入美团
美团仍是重要的本地生活交易入口。新华网援引美团2025年第三季度业绩称,过去12个月交易用户数突破8亿;2025年全年核心本地商业收入为2608亿元。需要注意,8亿是全平台交易用户,2608亿元对应核心本地商业分部,两者都不能直接解释为到店团购用户数或到店交易额。美团2025年Q3业绩报道 · 美团2025年全年业绩报道
到店市场已经从一家独大转向更激烈的竞争。一篇公开文章援引《晚点LatePost》和券商调研,将2025年美团与抖音的到店格局估算为约6:4。这不是平台官方份额,底层报告的核销前后口径也没有在公开页面完整展开,因此本文只把它作为行业约数。对已经拥有预约、会员或自助服务小程序的团队来说,接入美团的直接价值,是把平台上的团购交易接回自己的门店和履约系统。第三方到店格局报道

二、一张图看懂完整接入链路
推荐的结构不是“小程序直接请求美团”,而是:
微信小程序 → 自己的业务服务端 → 无限聚核 → 美团平台

四层分别负责:
| 层级 | 主要职责 | 不应该承担的事情 |
|---|---|---|
| 微信小程序 | 选门店、输入券码、展示套餐、确认使用、显示结果 | 保存API Key或直接调用带平台凭据的接口 |
| 业务服务端 | 用户权限、业务门店映射、确认上下文、成功记录、预约或会员权益 | 把前端一次点击直接当成平台核销成功 |
| 无限聚核 | API鉴权、系统门店、美团商家授权、预核销、核销、撤销和统一结果 | 替代接入方自己的会员、预约与经营系统 |
| 美团平台 | 保存平台套餐、券状态和核销事实,执行平台侧核销或撤销 | 理解接入方的本地权益和预约规则 |
商户、门店和美团门店是什么关系
以“XXX”品牌在全国开了100家门店为例:
- 业务品牌是“XXX”;
- 无限聚核商户可以建为“XXX”,用来管理这100家门店;
- 无限聚核门店是每一家实际经营门店,例如“XXX余杭万达店”,每家都有自己的
shopId; - 这家具体门店完成美团授权后,再核对它对应的美团授权账号和平台门店。

shopId。这里不是简单按名称自动匹配。公开接口中的 meituanName 是最新有效美团外部账号显示名,不保证等于平台单店名称;完成授权后仍要核对实际门店关系。对于100家连锁门店,应保存100条具体门店映射,而不是让所有门店共用一个商户ID发起核销。
API Key只放在业务服务端。小程序提交自己的门店ID、券码和确认上下文;服务端找到对应的无限聚核具体门店 shopId,再调用公开API。接口返回后,服务端保存结果并决定是否发放预约权益。
三、顾客最终会经历什么
顾客不需要理解后端有几层服务,他看到的流程应该很短:
- 在小程序中选择实际使用的门店;
- 输入美团团购券码;
- 查看套餐、数量和本地可获得的权益;
- 明确确认后执行核销;
- 核销成功,进入预约、会员或服务使用流程。

例如,一张“三小时门店服务”团购券,可以在核销成功后转换为本地的一张预约权益。美团负责这张券是否可用、是否已核销;自己的业务系统负责三小时权益对应哪个套餐、能预约哪些房间和时间。
四、先分清接入方式和责任
微信小程序接入美团核销,大体有两条路径:自行以第三方服务商身份申请平台能力,或者通过已经具备合作与接口能力的三方服务商接入。
自行申请适合准备长期维护平台能力、具备相应资质、安全材料和研发投入的团队;具体申请条件和阶段可以回看第一篇。通过无限聚核接入时,团队无需重新实现整套平台连接,但仍要完成自己的小程序页面、业务服务端、门店映射和权益逻辑。
这里要避免一个误区:使用三方接口不等于“什么都不用开发”。无限聚核解决的是美团授权及团购核销的连接问题;顾客是谁、能访问哪家店、核销后得到什么、什么时候可以预约,仍由接入方决定。
五、准备API Key和具体门店
开始联调前,至少准备三项:
- 无限聚核开发者后台的API Key;
- 自己业务门店与无限聚核具体门店的映射;
- 准备完成美团授权的实际门店。
当前公开文档给出的API Host是 https://newopen.elys.cn。所有需授权接口在请求头中使用:
Authorization: Bearer <key>
Content-Type: application/json
API Key不能放进小程序代码,也不能随接口响应返回给前端。
无限聚核当前后台和公开接口统一使用“商户/门店”。实际授权和核销使用具体门店 shopId,不要把以下几个ID混在一个字段里:
- 自己系统的业务门店ID;
- 无限聚核商户ID;
- 无限聚核具体门店
shopId; - 美团平台门店或套餐ID。
如果还没有数据,先新建商户,再在商户下逐家新建门店。新版后台会在商户卡片中显示门店数量,并为每家门店分别展示美团授权状态和授权入口。



shopId。六、为具体门店完成美团授权
业务服务端调用授权链接接口:
POST /api/hexiao/v2/get/auth/url
请求体只需要明确具体门店与平台:
{
"shopId": 123,
"platform": 1
}
platform=1 表示美团。接口成功时,data 是需要交给商家打开的授权URL。

拿到授权链接不等于授权完成。商家需要在美团页面完成操作,业务系统再核对对应具体门店的授权状态。接入方如果配置了授权成功Webhook,也不能把一次事件投递当作唯一事实来源,仍应保留状态查询或后台核对路径。无限聚核公开API文档
七、最小核销闭环只需要四类接口
不用一开始把全部接口铺满。最小闭环可以按下面的顺序实施:
| 能力 | 接口 | 是否必接 | 用途 |
|---|---|---|---|
| 团购列表 | ddzh-tuangou-deal-queryshopdeal |
按需 | 配置平台套餐与本地权益的映射 |
| 预核销 | ddzh-tuangou-receipt-prepare |
是 | 检查券当前是否可用,获得套餐和核销凭证 |
| 核销 | ddzh-tuangou-receipt-consume |
是 | 顾客确认后执行真实核销 |
| 撤销核销 | ddzh-tuangou-receipt-cancel |
按需 | 售后时撤销符合条件的成功核销记录 |
团购列表到底解决什么
团购列表回答的是:这家美团门店当前卖了哪些商品? 它通常用于管理后台配置,而不是用来判断顾客手里的某一张券现在能不能使用。
列表会提供平台商品ID、套餐名称、价格、售卖状态等信息。管理员可以从列表中选择一个美团商品,再明确它对应自己系统里的哪个套餐或权益。例如:
- 美团商品:三小时畅玩套餐;
- 平台:美团
platform=1; - 无限聚核具体门店:
shopId=1001; - 美团商品:
dealId=MT-3001; - 本地权益:
benefitId=PLAY-3H,代表三小时预约权益。

为什么不能核销成功后直接按套餐名称发权益?因为平台商品和本地履约不是同一套模型:
- 美团商品描述“卖了什么”,本地权益还要定义能预约哪家门店、哪些房间、可用时段和使用次数;
- 套餐名称可能调整,不同门店可能存在同名商品;
- 促销会改变实付金额,不能把金额当成商品身份;
- 同一个业务同时接入美团和抖音时,也不能把两边的同名套餐当成同一个平台商品。
因此,推荐用 platform + shopId + dealId → localBenefitId 保存映射。platform 区分平台,shopId 限定实际门店,dealId 标识平台商品,localBenefitId 指向自己的预约、会员或服务权益。
运行时仍有一道重要边界:预核销的统一响应不保证直接提供中立的 data.dealId。接入方应通过针对美团响应编写的商品适配器识别可靠商品身份,再查询已经配置的映射;不要解析 ticketInfo,也不要只按 ticketName 猜测。如果识别不到商品或没有映射,应停止真正核销并提示管理员先完成配置,而不是核销后再猜该发什么权益。
完整顺序是:管理员拉取团购列表并配置映射 → 顾客输入券码 → 服务端预核销 → 识别商品并找到本地权益 → 顾客确认 → 真正核销 → 按 localBenefitId 幂等发放权益。
下面使用Java 17与Jackson风格的伪代码串起四个核心接口。它不是无限聚核SDK,没有编译或调用真实券;business 代表接入方自己的权限、门店映射、确认单和权益服务。
final class MeituanRedemptionService {
private static final int MEITUAN = 1;
private final ObjectMapper json;
private final HttpClient http;
private final String apiKey; // 只从服务端配置注入
private final BusinessPort business;
// 共用HTTP封装:真实实现还要处理超时、日志脱敏和traceId。
JsonNode postJson(String path, ObjectNode body) throws Exception {
HttpRequest request = HttpRequest.newBuilder(
URI.create("https://newopen.elys.cn/api/hexiao/v2/" + path))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body.toString()))
.build();
HttpResponse<String> response = http.send(
request, HttpResponse.BodyHandlers.ofString());
return json.readTree(response.body());
}
// 1. 获取团购信息:让管理员把美团商品映射到本地套餐或权益。
JsonNode queryDeals(String localStoreId, int page, int pageSize) throws Exception {
business.requireStoreAdmin(localStoreId);
long shopId = business.hexiaoShopId(localStoreId);
ObjectNode body = json.createObjectNode()
.put("shopId", shopId).put("platform", MEITUAN)
.put("offset", page).put("limit", pageSize);
JsonNode reply = postJson("ddzh-tuangou-deal-queryshopdeal", body);
if (!reply.path("success").asBoolean(false)) {
throw business.apiFailure(reply);
}
return reply.path("data");
}
// 2. 预核销:只核对券和套餐,不发权益、不改变券的使用状态。
PrepareView prepare(String localStoreId, String code) throws Exception {
String userId = business.requireUserAccess(localStoreId);
long shopId = business.hexiaoShopId(localStoreId);
ObjectNode body = json.createObjectNode()
.put("shopId", shopId).put("platform", MEITUAN).put("code", code);
JsonNode reply = postJson("ddzh-tuangou-receipt-prepare", body);
if (!reply.path("success").asBoolean(false)) {
throw business.apiFailure(reply);
}
JsonNode data = reply.path("data");
String ticketInfo = data.path("ticketInfo").asText();
String productId = business.meituanProductAdapter()
.resolveProductId(shopId, data.deepCopy()); // 不按ticketName猜
String benefitId = business.requireBenefitMapping(
MEITUAN, shopId, productId); // 未配置则停止
String confirmId = business.savePending(userId, localStoreId, shopId,
code, 1, ticketInfo, productId, benefitId, data.deepCopy());
return new PrepareView(confirmId, data.path("ticketName").asText(),
benefitId, data.path("payAmount").asLong());
}
// 3. 核销:从服务端确认单读取原参数,首次成功后再创建本地权益任务。
void consume(String confirmId) throws Exception {
PendingRedemption pending = business.loadOwnedPending(confirmId);
if (business.hasSavedSuccess(confirmId)) return;
ObjectNode body = json.createObjectNode()
.put("shopId", pending.shopId()).put("platform", MEITUAN)
.put("code", pending.code()).put("num", pending.num())
.put("ticketInfo", pending.ticketInfo());
JsonNode reply = postJson("ddzh-tuangou-receipt-consume", body);
if (reply.path("success").asBoolean(false)) {
business.saveFirstSuccessAndCreateBenefitJob(confirmId, reply.deepCopy());
return;
}
if (reply.path("code").asInt() == 10500 || business.isUnknown(reply)) {
business.markNeedsReview(confirmId, reply.deepCopy());
return; // 不凭已核销提示或unknown直接补发权益
}
throw business.apiFailure(reply);
}
// 4. 撤销核销:逐项保存平台结果,成功项再幂等回收本地未使用权益。
void cancel(String redemptionId) throws Exception {
SavedRedemption saved = business.loadCancellable(redemptionId);
business.requireBenefitReversible(saved);
ObjectNode body = json.createObjectNode()
.put("shopId", saved.shopId()).put("platform", MEITUAN)
.set("consumeCredential", json.valueToTree(saved.consumeCredentials()));
JsonNode reply = postJson("ddzh-tuangou-receipt-cancel", body);
for (JsonNode item : reply.path("data")) {
business.saveCancelItem(redemptionId, item.deepCopy());
if ("succeeded".equals(item.path("status").asText())) {
business.retractUnusedBenefitOnce(redemptionId,
item.path("consumeCredential").asText());
}
}
}
}
四段伪代码刻意保留三条边界:预核销不发权益;核销只使用服务端保存的原参数;撤销按逐项状态处理,不能把顶层失败理解成全部失败。
同一业务确认必须继续使用相同的具体门店、券码、数量和 ticketInfo。进入成功处理的依据是顶层 success=true,不能只看HTTP状态,也不能单独看到 code=10000 就发放权益。
核销成功后,建议保存:
- 自己的业务确认单ID;
- 业务门店ID与无限聚核
shopId; - 券码的安全业务关联;
- 首次成功响应及
wxdgOrderNo; data[i]与consumeCredential[i]的对应关系;traceId与本地处理状态。
完整字段和多语言示例应以当前公开API文档为准,本文只保留接入主线。
八、重复点击、超时和结果未知怎么处理
接口幂等不等于业务幂等。小程序可能重复点击,网络也可能在平台已经处理后丢失响应。因此业务服务端仍应以“券码+自己的业务确认单”建立去重,并把一次确认固定成一份服务端请求上下文。

建议按三类结果处理:
- 首次成功:
success=true,保存完整成功记录,再进入本地权益处理; - 明确业务拒绝:
success=false且有明确原因,展示可理解提示,不循环重试; - 已核销提示或结果未知:不凭提示补造首次成功数据,也不立即发放权益;先核对原业务记录、
wxdgOrderNo、traceId和平台券状态。
当前公开文档说明,相同业务请求命中已成功订单时,可能返回 success=false、code=10500,不再原样返回首次成功明细。因此第一次成功响应必须保存好,不能指望重复调用把原数据重新取回来。
这一层正是无限聚核发挥作用的位置:它向接入方提供统一的美团调用入口、业务结果和定位字段;接入方则用自己的确认单和权益记录完成最后一层业务幂等。更底层的多平台聚合幂等、状态记录与对账机制,将在后续专项文章中单独展开。
九、核销成功后,再发放自己的权益
美团核销成功和本地预约创建成功不是同一件事。推荐顺序是:
- 先保存平台核销首次成功事实;
- 为该成功记录创建唯一的本地权益发放任务;
- 发放预约券、会员权益或服务时长;
- 发放失败只重试本地任务,不再次核销同一张美团券。
例如,美团“三小时门店服务”套餐可以映射为本地一张指定套餐全额抵扣权益。套餐名称只用于展示,真正映射应使用接口返回的平台商品ID、具体门店和本地权益ID,避免同名套餐串错。
页面也应区分两种状态:
- “美团券核销成功”;
- “预约权益正在发放”或“权益发放完成”。
这样即使本地系统短暂失败,顾客也不会因为页面只显示一个笼统错误而再次提交核销。
十、撤销核销不等于消费者退款
需要售后时,先判断自己的权益是否已经使用、是否允许撤回,再处理平台撤销。
新版聚合核销成功后,consumeCredential[] 与 data[] 按下标对应。需要撤销时,使用原门店、platform=1 和要撤销的凭证调用:
{
"shopId": 123,
"platform": 1,
"consumeCredential": [
"核销成功时保存的凭证"
]
}
撤销结果要逐项检查 succeeded、rejected 或 unknown。只有全部成功时,顶层 success 才为 true。
撤销核销处理的是平台券的使用状态;消费者付款退款、自己系统的权益回收和预约取消是另外的业务动作。它们可能互相关联,但不能把一次撤销接口成功直接描述成“消费者已经收到退款”。
十一、上线前按结果验收
至少检查下面这些场景:
- API Key只存在服务端,错误Key不会泄露到小程序日志;
- 自己的业务门店能稳定映射到正确的无限聚核具体门店;
- 商家完成美团授权后,后台状态与实际门店一致;
- 正常券、无效券、已核销券和不适用门店的券都有明确页面结果;
- 预核销成功不会自动发权益,顾客确认后才执行核销;
- 首次成功响应、
consumeCredential、wxdgOrderNo和traceId能回查; - 重复点击不会产生两次核销后的两份本地权益;
- 响应超时或结果未知时,页面进入待确认状态,不盲目重发;
- 平台核销成功、本地权益失败时,可以只补发本地权益;
- 撤销核销、权益回收、预约取消和退款分别记录结果。
本文所有代码块都只是请求形状示例,没有使用真实券码执行核销或撤销。真正联调前,应再次核对公开文档的当前字段和风险说明。
十二、下一篇:微信小程序怎么接入抖音团购核销
美团接通以后,下一步是抖音生活服务。两边看起来都是团购核销,但商家授权、券凭证、预核销返回值和异常恢复并不完全相同。
下一篇将单独介绍微信小程序怎么接入抖音团购核销,重点比较它与美团接入最容易混淆的地方。现在准备开始美团联调,可以先打开无限聚核API文档,获取API Key,准备具体门店 shopId,再从商家授权与预核销开始。
资料核对于2026年9月21日。市场数据分别来自新华网对美团业绩的报道与公开文章援引的第三方估算,口径已在正文说明。卡通图片和关系图均为示意,不是真实小程序界面、客户案例或生产运行证明。三张新版后台截图来自当前“商户/门店”界面,公开版已裁切并不透明遮蔽商户名、门店名、门店ID及平台账号;原图仅保留在私有审稿目录,不进入发布包。