PAYATHON 2026

非小程序及代扣投诉订单如何接入并通过API监测?

支付老李

结论

非小程序支付和代扣交易产生的投诉,只要已经进入微信支付的“支付交易投诉”体系,通常都可以通过“消费者投诉 2.0”接口监测,无需针对小程序、H5、Native、App 或代扣场景分别接入。

建议同时使用两种方式:

  1. 配置投诉通知回调,实时接收新增投诉和状态变更。
  2. 定时调用投诉单列表接口进行补偿查询,避免因回调失败而漏单。

需要注意,页面中可见的数据未必全部向接口开放。如果某类投诉没有出现在 GET /v3/merchant-service/complaints-v2 的查询结果中,应先确认该投诉是否属于消费者投诉 2.0 的开放范围、是否归属于当前商户号,以及当前账号是否具备相应的接口权限。对于尚未开放 API 的页面数据,修改查询参数也无法获取,不建议通过抓取管理后台页面解决。

接入前提

接入前需要准备:

  • 商户号 mchid
  • 商户 API 证书及私钥
  • API v3 密钥
  • 微信支付平台证书或平台公钥
  • 可通过公网 HTTPS 访问的回调地址
  • 当前商户号对应的投诉接口权限

如果使用服务商模式,还要确认投诉实际归属于服务商商户号还是特约商户号。调用查询接口时使用的身份必须与投诉归属关系一致,否则可能出现“页面可见、接口查不到”的情况。

相关接口

消费者投诉 2.0 的常用接口包括:

GET    /v3/merchant-service/complaints-v2
GET    /v3/merchant-service/complaints-v2/{complaint_id}
POST   /v3/merchant-service/complaint-notifications
DELETE /v3/merchant-service/complaint-notifications

这些接口分别用于:

  • 分页查询投诉单
  • 查询投诉单详情
  • 创建投诉通知回调地址
  • 删除投诉通知回调地址

具体的请求参数和字段应以接入时的微信支付官方 API 文档为准。需要特别确认日期范围、分页限制,以及服务商模式下的商户号参数。

第一步:配置投诉通知回调

先向微信支付登记一个 HTTPS 回调地址:

POST /v3/merchant-service/complaint-notifications
Authorization: WECHATPAY2-SHA256-RSA2048 ...
Accept: application/json
Content-Type: application/json
Wechatpay-Serial: PLATFORM_CERTIFICATE_SERIAL

{
  "url": "https://merchant.example.com/wechatpay/complaint/notify"
}

对应的 curl 请求如下:

curl -X POST \
  'https://api.mch.weixin.qq.com/v3/merchant-service/complaint-notifications' \
  -H 'Authorization: WECHATPAY2-SHA256-RSA2048 ...' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Wechatpay-Serial: PLATFORM_CERTIFICATE_SERIAL' \
  -d '{
    "url": "https://merchant.example.com/wechatpay/complaint/notify"
  }'

Authorization 不能直接写死,需要使用商户私钥,按照微信支付 API v3 的签名规则动态生成。生产环境中更适合使用微信支付官方 SDK 完成签名和验签。

第二步:接收并处理通知

收到投诉通知后,应按以下流程处理:

  1. 使用应答头中的签名、时间戳、随机串和原始请求体进行验签。
  2. 使用 API v3 密钥解密通知中的 resource。
  3. 提取投诉单号等必要信息。
  4. 调用投诉详情接口获取完整数据。
  5. 按投诉单号幂等写入。
  6. 返回成功响应。

通知密文采用 AES-256-GCM 加密。下面仅展示解密部分,不能代替通知签名验证:

import crypto from 'node:crypto';

function decryptResource(apiV3Key, resource) {
  const key = Buffer.from(apiV3Key, 'utf8');
  const nonce = Buffer.from(resource.nonce, 'utf8');
  const associatedData = Buffer.from(resource.associated_data || '', 'utf8');
  const ciphertext = Buffer.from(resource.ciphertext, 'base64');

  const authTag = ciphertext.subarray(ciphertext.length - 16);
  const encryptedData = ciphertext.subarray(0, ciphertext.length - 16);

  const decipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);
  decipher.setAAD(associatedData);
  decipher.setAuthTag(authTag);

  const plaintext = Buffer.concat([
    decipher.update(encryptedData),
    decipher.final()
  ]);

  return JSON.parse(plaintext.toString('utf8'));
}

不要在验签前信任回调内容或将其写入数据库。即使解密成功,也不能证明请求一定来自微信支付。

第三步:定时补偿查询

回调可能因网络故障、服务发布或处理超时而失败,因此还需要定时查询投诉列表:

GET /v3/merchant-service/complaints-v2?begin_date=2026-09-13&end_date=2026-09-14&limit=50&offset=0
Authorization: WECHATPAY2-SHA256-RSA2048 ...
Accept: application/json

示例:

curl -X GET \
  'https://api.mch.weixin.qq.com/v3/merchant-service/complaints-v2?begin_date=2026-09-13&end_date=2026-09-14&limit=50&offset=0' \
  -H 'Authorization: WECHATPAY2-SHA256-RSA2048 ...' \
  -H 'Accept: application/json'

轮询程序需要处理分页,并在本地保存同步游标或最近一次成功同步的时间。为避免因时间边界而漏单,可以让相邻查询窗口保留少量重叠,再按投诉单号去重。

监测流程可以设计为:

投诉通知到达
    -> 验签并解密
    -> 获取投诉单号
    -> 查询投诉详情
    -> 幂等写入数据库
    -> 触发告警或工单

定时补偿任务
    -> 查询最近一段时间的投诉列表
    -> 遍历所有分页
    -> 按投诉单号去重
    -> 更新投诉状态
    -> 补发遗漏告警

接口查不到时如何排查

如果后台页面中存在投诉,但列表接口没有返回,可以依次检查以下几项。

商户号是否一致

支付交易可能由另一个商户号、特约商户号或服务商体系发起。页面账号可以查看投诉,不代表当前用于签名的商户号具有相同的数据权限。

是否属于同一投诉产品

确认页面展示的是“支付交易投诉”,而不是小程序平台申诉、违规处理、风险处置或其他业务模块。不同产品后台的数据不一定共用消费者投诉接口。

查询条件是否覆盖

检查日期范围、分页偏移量,以及服务商场景下的被诉商户条件。不能只查询第一页,也不能仅按原支付订单的时间判断投诉发生时间。

接口权限是否开通

确认商户平台已经开通消费者投诉相关接口权限,并检查商户证书、API v3 密钥和平台证书是否配置正确。

是否确实未开放 API

如果投诉归属的商户号、查询条件和接口权限都没有问题,但该投诉仍然只能在页面中看到,应向微信支付商户支持确认这类页面数据是否开放 API。如果尚未开放,只能通过管理后台处理,无法用消费者投诉接口替代。

注意事项

  • 不能只依赖回调,需要保留定时补偿查询。
  • 投诉通知可能重复发送,数据库写入和告警都要具备幂等性。
  • API v3 密钥必须为 32 字节,并应保存在密钥管理系统中。
  • 日志中不要记录 API v3 密钥、商户私钥、完整身份证号、手机号或完整的回调明文。
  • 平台证书可能轮换,验签程序需要支持证书更新。
  • 投诉单状态可能多次变化,已经入库不等于已经处理完成。
  • API 返回的支付场景、订单号等字段可能因投诉来源不同而缺失,进行业务关联时应允许字段为空。
  • 不建议通过自动登录、页面抓取或模拟管理后台接口来监测投诉,这些方式在稳定性和合规性方面都有风险。

实际接入可以采用“通知回调实时发现、列表接口定时补偿、详情接口更新状态”的方式。如果经过核实,特定的非小程序或代扣投诉不在消费者投诉 2.0 的开放范围内,就无法只依靠公开 API 完成监测,需要继续通过商户平台查看,或等待相应能力开放。

备注:内容仅供参考。