Skip to content
TestAPI 40.68.0构建信息

MetaEco 余额支付 ​

接入 MetaEco 余额下单、支付查询、退款和成功通知。业务金额与订单由应用后端管理,小程序负责展示订单和触发用户确认。

主体变更与支付 ​

适用版本 40.6.0 的同一 AppID 主体变更包含逐笔处理支付阻断;实际环境和运行版本以站点 release.json 与发布记录为准。平台完成企业和授权审核后,申请等待当前管理员最终确认;审核通过不切换主体,也不提前停用收款配置。

最终确认会实时检查未结支付、退款及尚未处理或投递完成的支付回调,审核后新增的交易同样参与检查。存在未结事项时返回“未结交易阻止主体变更”,应用主体保持原值。当前唯一应用管理员且同时是 owner 和申请发起人,可查看六类金融阻断摘要及与最终确认金融保护条件一致的未结订单列表,其中包括 pending、refunding 和其它未识别状态;只有本地 pending 且历史资金快照完整的余额订单可逐笔重新输入当前管理员密码后明确关闭。该内部操作沿用订单历史资金快照和 Purse 稳定操作号,旧原生订单与 V3 订单均适用,不会自动关闭或批量处理,也不改变申请状态或应用主体。已有 paid 终态本身不再阻断;若标准付款通知尚未投递,通知仍会阻断。V3 商户签名接口和支付协议保持不变。

资金服务或本地提交结果未知时,不能把超时视为关单成功;按原 order_id 只读回查 closed 或 paid 状态。closed 表示服务端已恢复本地终态;paid 表示付款完成,应按摘要中的其他未结事项继续处理。订单未出现在未结订单列表中不代表已关闭。最终确认只在重新核对全部当前阻断后单独执行;未结事项不阻止平台驳回或管理员取消申请。

切换成功时只停用本应用旧主体的商户绑定和支付配置,不停用其他应用共享的商户。旧配置不能用于新订单;历史订单、退款及资金账户继续使用原归属,历史查询和退款仍需原商户合法凭据。此次变更不迁移历史资金,也不自动办理新主体商户接入;恢复收款须按以下流程重新绑定当前主体商户,不能复活已退役的旧配置。

主体变更后恢复收款 ​

此入口适用版本 40.7.0,随支付重新绑定功能发布后提供;共享环境是否已开放以实际发布记录为准。当前应用管理员进入“应用详情 → 支付商户”,分别查看“商户审核状态”和“本应用绑定状态”。旧商户仍有效、但绑定已停用时,本应用不能继续用它收款。

  1. 选择当前已认证主体的可用已审核商户,或填写商户名称申请新商户。候选直接显示名称和商户号,无需查找内部 ID。已退役的历史商户,以及已被其他应用有效绑定、待审绑定或关联微信兼容支付配置的商户,不列入此次恢复选项;没有可用商户时申请新商户。
  2. 当前管理员输入密码确认绑定。复用已审核商户后绑定生效;新商户需等待另一位平台管理员审核,驳回后可按审核意见重新申请。页面过期或主体、管理员、绑定已变化时须刷新后重办。
  3. 使用微信协议支付的应用,在同页登记新商户的证书序列号、商户证书和 API V3 Key,使用 V2 查单时再配置 API V2 Key。商户号取自当前已审核绑定,保存须密码重新认证。私钥保存在业务后端,不上传;页面不回显 API 密钥。原生余额支付继续使用“配置与应用密钥”中的应用请求公钥入口。
  4. 将业务后端的新订单配置切换至新商户,并完成受控验收后恢复收款。保留旧商户的合法历史凭据用于旧订单查单和退款;平台也保留退役配置供原订单验签及通知,不将历史资金责任转给新商户。

重复提交、跨主体选择、普通运营成员发起,以及覆盖有效、待审或当前主体被明确停用的绑定都会被拒绝。重新绑定不会自动更新隐私指引中的企业名称,仍须按实际内容单独办理。

商户 API 证书申请与下载 ​

在线证书管理适用版本为 40.8.0;环境开放情况以实际发布记录及页面提示为准。当前应用管理员进入“应用详情 → 支付商户 → 商户 API 证书”,可选择:

  1. 本机生成:点击“生成并下载私钥”,妥善保存下载的 apiclient_key_商户号.pem,再勾选私钥保存确认。浏览器只向平台提交 CSR,私钥不上传,平台不能找回。
  2. 已有证书请求串:技术人员在业务服务器生成 RSA-2048 私钥和使用 SHA-256 签名的 PKCS#10 CSR,将 CSR 粘贴或上传;私钥留在业务服务器。

输入当前管理员密码后,平台使用独立商户签发 CA 签发证书。申请无需填写商户号、主体 ID 或证书序列号,平台会按当前已认证主体及有效收款绑定核验。签发后的证书可随时下载 PEM。已启用支付的商户可直接把新私钥和序列号部署到业务后端,继续使用现有 API 密钥,无需重新保存平台支付配置。首次启用时,可通过“填入支付配置”自动填写下方的证书和序列号,再按原入口配置 API V3 Key 和需要时的独立 API V2 Key。签发不会自动修改密钥。

平台新签发的证书有效期 5 年,已登记证书保留原有效期。每个商户最多同时持有 3 张未过期有效证书,包含仍在使用的人工登记证书。同一 CSR 重复提交返回同一有效证书;新证书签发不影响旧证书。切换时先在业务后端部署新私钥和对应序列号,验证后对不再使用的证书执行“作废”。作废立即拒绝后续用该证书签名的请求,已经通过验签的在途操作仍按原业务幂等规则完成。平台不会从作废状态恢复证书。

首次收款还须完成商户审核、有效绑定及 API 密钥配置;申请证书本身不授予收款资格。主体变更后的历史交易继续使用原商户及合法历史凭据。当前已上线的人工登记证书继续保留,不能因部署此入口自动作废或替换易购现行凭据。

身份验证差异:本期使用管理员密码二次验证,暂不增加短信验证。私钥本地保管、CSR 申请、5 年期限与最多 3 张并行证书参考微信商户 API 证书申请说明;MetaEco 证书由 MetaEco 自有签发方签发。

微信协议 SDK 接入准备 ​

现有原生接口继续按本页后续章节使用。商城的标准 SDK 迁移正在受邀 Test 验收,本地实现与测试不代表已经部署开放。目标是一次性接入 SDK 域名配置后,业务后端通过必要配置完成环境切换;不要求小程序或业务后端传递平台内部调试字段。

WxJava 小程序 SDK 基线为 4.7.0,支付使用独立制品 top.metaeco.sdk:weixin-java-pay:4.7.0-metaeco.1。上游 SDK 对自定义支付域名不执行商户签名和响应验签,因此仅修改域名或升级上游版本不足以接入。独立制品将明确配置的 HTTPS Origin 纳入原有签名/验签,拒绝自定义 Origin 的重定向和跨域请求;它不是上游发行版。制品的源码、许可证及摘要由受邀接入流程提供,目前没有公开 Maven 分发地址。

配置提供方与用途
小程序 API Origin当前获准环境的 API 入口,配置 SDK apiHostUrl
支付 API Origin同一环境的支付入口,配置 SDK payBaseUrl
AppID、AppSecret当前应用配置,用于登录和手机号接口 token;只保存在业务后端
商户号与绑定已审核、有效且属于该 AppID 的商户,凭据登记不授予商户资格
商户证书、私钥、证书序列号业务后端保管私钥,平台登记匹配证书;商户签名用于下单及 paySign
API V3 Key独立 32 字节密钥,用于平台证书和标准 V3 通知解密
API V2 Key使用 V2 查单时配置独立 32 字节密钥,不与 V3 Key 混用

平台原生应用请求公钥和标准商户证书是各自协议的配置,不能仅登记前者就省略后者。平台证书接口返回 MetaEco 当前环境的证书,由 SDK 验证成功响应;原生通知公钥不能代替它。

标准协议当前迁移验证范围
POST /v3/pay/transactions/jsapi预下单、重复请求、金额冲突、draft 及 disabled 边界
GET /v3/pay/transactions/out-trade-no/{out_trade_no}按商户订单号查单
GET /v3/pay/transactions/id/{transaction_id}按平台交易号查单
POST /pay/orderquery商城既有 V2 XML 查单,MD5/HMAC-SHA256 及响应验签
POST /v3/pay/transactions/out-trade-no/{out_trade_no}/close未付款订单关单、重复关单及与付款互斥
POST /v3/refund/domestic/refunds原订单退款及业务退款号幂等
GET /v3/refund/domestic/refunds/{out_refund_no}查询持久化退款状态,不触发再次退款
GET /v3/certificatesSDK 自动获取平台证书

业务后端调用流程沿用微信标准参数:登录获得应用 OpenID,按该身份下单,把 SDK 生成的支付参数传给小程序。宿主对 active 或 draft 分别验证对应运行资格,商户有效绑定、付款用户、订单归属、签名及会话仍是必要条件。合法 debug_session 不需要强制把应用切换为 active;失效、撤销或用户/应用不匹配的会话不能付款。

标准 V3 成功通知使用 Wechatpay-* 签名头与 AES-256-GCM 加密 resource,接收方可使用 SDK 验签解密,再核对 AppID、商户、业务单号和金额并幂等更新。处理失败返回非 2xx 以便重试,不能以 HTTP 200 内的业务错误代替失败状态。该通知与后文原生事件协议分开,历史订单按创建时的协议收尾。

付款结果不明时,业务后端使用原商户订单号查单。标准 V2/V3 查询会核对已经提交的资金事实,恢复因服务中断未写回的订单状态和成功通知;查单本身不扣款,也不要求用户再次提供 PIN 或前台调试会话。资金查询或状态回写失败会返回错误,应稍后重试原订单,不能据此新建另一笔付款。

V3 关单成功返回带签名的空正文 204,后续查单为 CLOSED,已关闭订单不能继续付款。同一商户重复关闭同一订单仍返回 204,这是已明确约定的 MetaEco 兼容差异;微信官方资料仅核验了首次成功 204。付款已经提交时拒绝关闭,并恢复付款状态;资金或数据库结果未明时返回错误,按原订单查单或更换签名 nonce 重试,不能把超时当成已关闭。

发货、订阅消息、企业付款、店铺自动分账及跨域账单下载不包含在本次“仅改配置”的验收承诺中。完成全部必需契约、Test 配置及真机收银台验收后再更新开放状态;看到收银台即可取消,真实付款由用户确认。

前置条件 ​

条件准备方式
应用与商户应用为 active 或 draft,已审核商户与当前 AppID 有效绑定
接口 token按配置与凭据取得,保存在后端
应用请求密钥后端保管 RSA 私钥,在控制台登记对应公钥
通知入口公网 HTTPS URL,处理原始正文验签、去重和查单
宿主支付能力使用支持 wx.requestPayment 的宿主版本

开发调试支付 ​

尚未发布的 draft 应用可以在商户绑定、应用凭据和支付请求公钥配置完整后下单。手机通过有效的本地开发调试会话,或具有当前体验资格的已上传体验版会话运行应用,由宿主调起收银台;应用后端沿用本页下单参数,小程序沿用 wx.requestPayment,无需提交调试令牌或运行实例字段。

付款时仍校验当前用户、订单归属和会话;普通体验资格撤销/到期或体验包取消后不能继续付款。调试会话过期、撤销或开发权限被移除时,应重新取得合法调试资格后继续;不能通过换订单号绕过。查单与原订单退款由后端凭据和订单权限控制,不要求前台调试会话仍有效。停用应用的接口 token 不能继续访问这些支付接口。

调试不自动模拟成功,也不免支付密码;用户确认后可能发生真实余额扣款。应用发布状态不替代支付资格,其他普通业务接口仍按各自准入规则执行。

接入步骤 ​

  1. 登记应用支付请求公钥,配置后端签名。
  2. 使用稳定业务订单号创建支付单,保存平台订单 ID。
  3. 将 data.request_payment 返回给小程序,用宿主支付入口让用户确认。
  4. 后端查询原支付单,校验订单和金额。
  5. 接收成功通知,验签、查单并幂等更新业务状态。
  6. 需要退款时沿用原订单和稳定业务退款号;结果未明时查询原退款。

预期结果: 本地业务单与平台订单映射一致,业务终态来自服务端查单及已验证通知。小程序回调不作为资金终态的唯一依据。

退出期间的交易处理 ​

归档、注销申请暂停或最终退出后,普通下单和普通退款按当前应用状态拒绝,不能凭旧页面、旧 token 或新操作号绕过。已经发出的资金操作仍须按原交易核实结果;受限善后由当前获权人员处理。

平台在注销办理时自动核对原交易,实际提交前会重查;未处理完、对不上、查不全或来源未接入时继续阻断。完整财务结清另由获明确授权的财务人员在现有善后页面确认一次,三段审批复用有效结果;失败的退款仍有应退未退金额时,也属于未结事项。没有交易须有完整来源证明,不能只凭空清单确认。对于从创建起具有受保护完整记录、从未开通支付且没有资金业务的应用,平台可直接核验“无支付业务”,由原财务人员确认一次无资金义务,无需先创建商户或钱包账户。旧应用缺少可信历史、存在支付开通或资金记录时,继续按原来源核实,不能仅因当前没有商户或订单就通过。正常余额可留在原商户账户,注销后的必要原订单退款由当前获授权财务人员通过受限善后办理,不恢复普通支付权限。单笔查询和自动汇总均不代表整体结清;应用后端无需增加内部核对参数。

当前开放注销申请可在原财务页面登记退款申诉和付款争议。未解决事项及旧申请中的未结记录都会阻断财务结清;登记与处置不会直接改写主体确认、独立复核或原七天期限。失败/关闭的退款先按仍需核实处理,查钱包也不能替代对退款义务的判断。空记录、关闭工单和操作员说明都不能代替完整来源及真实处置凭证。

本轮发布候选为已停用、完整核实无真实资金业务及未结争议且已安全停服的应用提供直接删除,不再要求上述正式注销的单独财务签字、独立复核或最终确认,由管理员一次密码确认逻辑删除并保留历史。旧创建历史未知和发布记录不单独阻断;资金归属、完整账本或停服来源缺失仍阻断,当前零商户/零订单不等于通过。有真实资金业务继续原正式注销和受限善后。本段规则随对应版本发布生效,实际应用资格以所在环境的预检为准。

对于“这笔退款是否到账”,财务可从原退款详情直接登记核实,记录固定绑定退款编号和金额;系统查询原账本成功后,财务一次核实并关闭,无需另做补证。普通争议仍须对应的真实处理凭证,单笔到账不代表其他争议解决或整体结清。查询失败、信息变化或权限失效时继续阻断;结果不明按原操作号回读。

当前同步核对上限为付款、退款合计1000笔;超过上限或查询超时会阻断,不能用部分结果放行。

下单提交返回 503 且原因是 payment_commit_outcome_unknown 时,先核对原业务订单。退款结果未明时保留原退款号和原参数;重复 POST 只查证原资金操作,查询不到也不能认定未发生。只有平台明确原操作未发生且当前资格有效时,才可用原退款号重新授权;不自动换订单号或退款号。

应用支付请求公钥与签名 ​

下单和退款每次都要求应用请求签名。平台到应用的成功事件由平台私钥签名,应用后端用平台通知公钥验签;应用到平台的下单和退款由应用私钥签名,平台用应用上传的应用请求公钥验签。这两组密钥独立。开发者中心的“应用配置与应用密钥”页提供平台通知公钥的只读下载,以及应用请求公钥的上传与状态管理;应用后端也可用接口 token 调用读取通知公钥。平台和浏览器均不应接收应用私钥。

应用管理员或具备 miniapp:members 权限的成员按以下顺序接入。应用开发者可以查看公钥及 signature_required 状态,变更密钥需要成员管理权限。

  1. 在应用后端生成 RSA 2048~4096 位密钥对,将私钥放在受保护的服务端密钥存储中,导出标准 SPKI -----BEGIN PUBLIC KEY----- PEM 公钥。不同环境使用不同密钥对;不要把私钥放进小程序、宿主、浏览器、公开仓库或日志。

  2. 在“应用配置与应用密钥”页选择公钥 PEM 文件或粘贴公钥文本,点击“生成持钥验证挑战”。此时尚未登记为有效公钥。页面展示公钥 key_id、完整待签原文 signing_message 和五分钟有效期;平台保存一次性的挑战 ID。key_id 是规范化 SPKI DER 的 SHA-256 摘要前 16 字节,用 32 位小写十六进制表示。

  3. 由持有私钥的应用后端对返回的 signing_message 原始 UTF-8 字节生成 RSA PKCS#1 v1.5 + SHA-256 签名,再用标准 Base64 编码。原文已包含用途、环境、AppID、key_id 和挑战值;不要自行重组或改换行。浏览器只提交签名结果,不接触私钥。

    可先从页面下载待签原文,在受控服务器用 openssl dgst -sha256 -sign app-request-private.pem -out proof.sig signing-message.txt 签名,再用 openssl base64 -A -in proof.sig 取得要粘贴的文本。文件名按实际保存路径替换,原文末尾换行必须保留。

  4. 先让应用后端部署请求签名逻辑。在页面粘贴标准 Base64 签名结果,点击“验证并启用公钥”,按提示输入本人密码重新认证。票据严格绑定当前 AppID 和挑战返回的 key_id,页面提交同一公钥、挑战 ID 和签名结果。登记成功后密钥立即为 active,可用于当前环境的签名请求;旧版遗留的 pending 密钥可单独补启用。

只有 POST /miniapp/v1/apps/{app_id}/payments/orders 和 POST /miniapp/v1/apps/{app_id}/payments/orders/{order_id}/refunds 使用应用请求签名;查单、获取接口 token 和平台通知验签不使用它。两条资金写请求始终携带原有 Authorization: Bearer <接口 token> 及四个必填签名头:X-MetaEco-App-Key-ID、X-MetaEco-App-Timestamp、X-MetaEco-App-Nonce、X-MetaEco-App-Signature。未登记有效公钥的应用也不能省略签名。前者是正在使用的 active 公钥 ID;时间戳是十进制 Unix 秒,允许前后五分钟;nonce 由安全随机源生成 16~48 字节,再做无填充 Base64URL 编码;签名值是标准 Base64。

签名串遵循微信支付 API v3 的五行请求格式,但使用 MetaEco 独立签名头与公钥。依次连接大写 HTTP 方法、去域名但包含实际 AppID 和订单号的 URL 路径、与 Header 完全一致的时间戳、nonce、实际发送的 JSON 正文字节,五行均以 \n 结尾。不得先解析后重新序列化正文,不得在这两条路径添加 Query;签名算法为 RSA PKCS#1 v1.5 + SHA-256。示意如下,rawBody 表示原始字节,不是字面字段名:

text
POST
/miniapp/v1/apps/<app_id>/payments/orders
<timestamp>
<nonce>
<rawBody>

签名缺失、错误、过期或与应用不匹配返回 HTTP 401;同一密钥的 nonce 重放返回 409;正文超过 16 KiB 返回 413;验签所需存储或时钟不可用返回 503 并失败关闭。资金结果未明时先按原业务单号查单;确需重试原操作时保持业务订单号、业务退款号和参数不变,重新生成时间戳、nonce 与签名。签名 nonce 只防请求重放,资金幂等仍由稳定业务号保证。

轮换时先登记新公钥并验证签名;新公钥上传后立即生效,最多可有两把 active 公钥。让应用后端切换到新私钥后,在页面对旧钥点击“撤销”并重新认证。撤销后新到达的验签请求立即拒绝旧钥;此前已通过验签的在途请求继续按原业务幂等规则处理。即使撤销最后一把 active 公钥,signature_required 仍为 true,下单和退款都会失败关闭,直到登记新钥。密钥管理使用开发者中心身份,不能用应用接口 token 操作。此协议属于 MetaEco 原生余额资金接口,不替代微信支付商户证书或微信 API v3 的 Authorization 格式。

余额支付接入示例 ​

应用后端签名示例 ​

以下 Node.js 示例仅构造请求,不发起资金操作。origin 是确认过的 Test API Origin,path 是上述两条资金路径之一,包含真实 AppID 和退款时的订单 ID;payload 是本次完整请求对象。interfaceToken、keyId 和 privateKeyPem 从应用后端受保护配置取得,公钥须已登记为 active。签名后按返回的 body 原样发送,禁止再序列化。

js
import { constants, randomBytes, sign } from 'node:crypto'

export function buildSignedPaymentRequest({
  origin, path, interfaceToken, keyId, privateKeyPem, payload
}) {
  if (path.includes('?') || path.includes('#')) {
    throw new Error('资金写请求路径不能包含 Query 或片段')
  }
  const body = JSON.stringify(payload)
  if (Buffer.byteLength(body, 'utf8') > 16 * 1024) {
    throw new Error('资金写请求正文超过 16 KiB')
  }
  const timestamp = String(Math.floor(Date.now() / 1000))
  const nonce = randomBytes(24).toString('base64url')
  const message = ['POST', path, timestamp, nonce, body].join('\n') + '\n'
  const signature = sign('RSA-SHA256', Buffer.from(message, 'utf8'), {
    key: privateKeyPem,
    padding: constants.RSA_PKCS1_PADDING
  }).toString('base64')
  return {
    url: origin + path,
    init: {
      method: 'POST',
      redirect: 'error',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${interfaceToken}`,
        'X-MetaEco-App-Key-ID': keyId,
        'X-MetaEco-App-Timestamp': timestamp,
        'X-MetaEco-App-Nonce': nonce,
        'X-MetaEco-App-Signature': signature
      },
      body
    }
  }
}

业务后端显式发起操作时,使用 fetch(request.url, request.init) 或等价 HTTP 客户端发送;同时检查 HTTP 状态、平台 code/error 及 X-Request-ID。超时或 503 后先查原单;经核对确需重试时复用原业务号和参数,重新调用此函数生成时间戳、nonce 和签名。

下单、查单与退款 ​

接入前核对经审核的平台商户与 AppID 绑定及通知入口。创建支付单的 payload 示例为:

json
{
  "openid": "oid_0123456789abcdef0123456789abcdef0123456789abcdef",
  "business_type": "shop",
  "business_order_no": "ORDER20261010001",
  "description": "测试商品订单",
  "amount_minor": 100,
  "currency": "CNY",
  "notify_url": "https://merchant.example.com/api/metaeco/payments/notify"
}

这些值须换为本应用实际身份、稳定业务号和公网通知地址。订单金额由业务后端根据订单确定,单位为整数分;不能相信小程序提交的金额。使用签名函数构造 POST /miniapp/v1/apps/{app_id}/payments/orders 请求。成功为 HTTP 201、code=miniapp_success,保存 data.order_id 与本地业务单的映射;仅将返回的 data.request_payment 交给支持该支付参数的宿主入口。创建支付单不等于资金已支付。

用户确认后,应用后端以平台订单 ID 和原业务订单号查询:

sh
curl --get "$PLATFORM_ORIGIN/miniapp/v1/apps/$APP_ID/payments/orders/$ORDER_ID" \
  --header "Authorization: Bearer $ACCESS_TOKEN" \
  --data-urlencode "business_order_no=$BUSINESS_ORDER_NO"

查单为只读接口,无应用请求签名;核对订单号、金额及资金终态,不能单凭小程序回调判定业务支付成功。通知接收继续执行本页的验签、事件 ID 持久去重及查单规则。

退款的 payload 示例为:

json
{
  "business_order_no": "ORDER20261010001",
  "business_refund_no": "REFUND20261010001",
  "amount_minor": 100,
  "reason": "测试订单退款"
}

按本笔实际退款金额填写,并用签名函数构造 POST /miniapp/v1/apps/{app_id}/payments/orders/{order_id}/refunds。省略 notify_url 时沿用原支付单通知地址。保留原业务退款号;创建/查询返回 pending 或结果未明时,不换新业务号申请另一笔退款。应用后端查询原退款:

sh
curl "$PLATFORM_ORIGIN/miniapp/v1/apps/$APP_ID/payments/orders/$ORDER_ID/refunds/$BUSINESS_REFUND_NO" \
  --header "Authorization: Bearer $ACCESS_TOKEN"

成功为 HTTP 200、code=miniapp_success;data.status 为 pending、refunded 或 failed,退款成功时返回 refunded_at。该查询也无需签名。核对原订单、业务退款号和金额后再更新业务终态。字段约束见下单、支付查单、退款和退款查询。

小程序触发支付 ​

将业务后端返回的 request_payment 原样传给 wx.requestPayment。参数为 timeStamp、nonceStr、package、signType 和 paySign;小程序不重新计算这些签名字段:

js
// requestPayment 来自自己的业务后端,不包含接口 token 或应用私钥。
wx.requestPayment({
  ...requestPayment,
  success() {
    // 通知自己的业务后端查单,再展示确认后的订单状态。
  },
  fail(error) {
    // 取消或失败时返回订单页;资金结果仍由后端查单确认。
  },
  complete() {
    // 结束页面等待状态。
  }
})

Android 和 iOS 均将这些参数交给宿主支付流程,用户确认、支付密码及资金执行由宿主处理。iOS 依赖安装版本配置的支付处理器,Android 使用宿主钱包确认入口;没有对应支付流程的安装版本不可用于支付联调。不要在小程序补传宿主内部字段。

MetaEco 余额支付事件通知 ​

应用后端创建余额支付单时必须提供 notify_url,例如 https://merchant.example.com/api/metaeco/payments/notify。地址须为平台可访问的公网 HTTPS 完整路径,总长不超过 255 个 UTF-8 字节,不得包含 Query、片段或 URL 用户信息。平台把地址固化在订单中;同一业务订单号重复下单时不能更换地址。退款可传自己的 notify_url,省略时沿用原支付单地址。通知目标属于应用后端,不填小程序页面地址,也不把接口 token 放在通知 URL 中。完整字段见创建余额支付单和原路退款。

平台只在资金操作已确认、支付或退款单已提交成功终态后发送成功事件。通知为 POST、Content-Type: application/json,正文信封有 id、create_time、event_type、resource。支付 resource 包含 app_id,order_id,business_type,business_order_no,transaction_id,amount_minor,currency,paid_at,status=paid;退款在同一原订单字段之外还包含 refund_id,business_refund_no,refund_amount_minor,refunded_at,status=refunded。金额均为整数分。事件 ID 与正文跨重投保持稳定;投递的时间戳、nonce 和签名每次重新生成。完整结构也包含在应用服务端 OpenAPI的 webhooks.metaEcoBalancePaymentEvent 中。

json
{
  "id": "men_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "create_time": "2026-09-23T10:00:00Z",
  "event_type": "REFUND.SUCCESS",
  "resource": {
    "app_id": "miniapp_example",
    "order_id": "45ed7c79-e614-4806-8cbd-7a68172f1eb6",
    "business_type": "shop",
    "business_order_no": "ORDER20260923001",
    "transaction_id": "TX20260923001",
    "amount_minor": 9900,
    "currency": "CNY",
    "paid_at": "2026-09-23T09:00:00Z",
    "refund_id": "208c693b-0131-4316-97ba-2d74c3e6485a",
    "business_refund_no": "REFUND20260923001",
    "refund_amount_minor": 9900,
    "refunded_at": "2026-09-23T10:00:00Z",
    "status": "refunded"
  }
}

平台发送 X-MetaEco-Event-ID(与正文 id 相同)、X-MetaEco-Key-ID、X-MetaEco-Timestamp(十进制 Unix 秒)、X-MetaEco-Nonce 和 X-MetaEco-Signature。签名算法为 RSA PKCS#1 v1.5 + SHA-256,签名值为标准 Base64。验签串按下式连接,末尾也有换行;rawBody 是收到的原始 UTF-8 正文字节,不可先解析再序列化:

text
keyID + "\n" + timestamp + "\n" + nonce + "\n" + rawBody + "\n"

应用后端用接口 token 调用读取通知公钥,按 key_id 选择受信任的 PEM 公钥验签;该公钥与微信支付平台证书、宿主预支付签名密钥分离。先校验所有签名头、事件 ID 一致性、前后 5 分钟时间窗和 AppID,再核对本地业务单号、平台单号和金额。支付事件通过支付查单核对支付事实:当前状态可能是 paid,也可能在全额退款后成为 refunded,两者都必须具有与事件相同的交易号、支付时间、业务号和金额;退款事件通过退款查单确认 refunded 和对应业务退款号。验签、查单和业务校验通过后,幂等更新本地订单或退款状态;无法确认时返回非 2xx,并按原业务号继续核查。不得单凭小程序支付成功回调或通知正文宣称资金成功;查询依赖暂不可用时保留待确认并返回非 2xx。

接收方应以事件 ID 持久化去重,相同业务终态重复到达也要安全应答。验签及处理成功、或已确认处理过时,5 秒内返回任意 2xx;验签或业务校验失败返回非 2xx。平台 5 秒超时,失败退避重试,最多投递 10 次后停止自动投递。通知采用至少一次交付,不能作为唯一结果来源;查询与定期恢复用于补齐延迟或遗漏。历史没有 notify_url 的订单不会自动补发通知。此事件协议由 MetaEco 定义,不是微信支付 API v3 的加密资源通知。

常见失败 ​

现象处理
401检查接口 token、active 公钥、四个签名头和原始正文
nonce 重放 409使用新时间戳、nonce 和签名;业务号及参数保持不变
订单冲突或余额不足按错误码查原单,核对订单参数及账户状态
超时、503 或退款 pending先查原业务单,不换号发起另一笔操作
通知验签失败保留原始 UTF-8 字节,检查公钥、Header、时间窗和 AppID

下一步 ​

完成允许、取消、超时、重复通知和退款场景测试,再按体验、审核与发布交付版本。具体字段和响应见支付 API 参考。

MetaEco 小程序开发者文档 · Test · API 40.68.0