接入易错点

更新时间:2026.10.30
||| 安装 Skill

一、场景与调用入口

注意事项

说明、正确应该怎么做

不做会怎么样

 小程序内不得通过 web-view 或跳转 H5 页面发起 JSAPI 支付

 说明:小程序 web-view 中的网页仅支持部分 JSSDK 接口,其中不包含支付接口,该权限无申请或配置入口;小程序场景应使用小程序支付。小程序的「开发调试」模式仅用于开发调试,其表现与正式环境不同,不能作为线上方案依据。
正确应该怎么做:① 页面运行在小程序内时,调用小程序下单并按小程序支付流程用 wx.requestPayment 拉起;② 按入口来源分流,H5 场景保留 JSAPI 支付,不为小程序投放 H5 支付入口;③ 页面承载方式改为小程序原生页面,或改用公众号内打开的 H5 页面(后者可按 JSAPI 方式拉起);④ 服务商/从业机构模式下使用与从业机构号同主体的小程序 appid 下单并拉起,无需与每个间连子商户单独绑定;⑤ 联调与验收一律在正式环境(关闭小程序「开发调试」模式)下进行,不以调试模式能拉起收银台作为上线依据。
典型反例:在小程序 web-view 内嵌的 H5 里用 WeixinJSBridge.invoke('getBrandWCPayRequest') 拉起支付;以「打开开发调试就能拉起」作为上线依据;在小程序中通过 web-view 承载 H5 商城并复用公众号 JSAPI 支付链路收款。 见 web-view(微信开放文档)、4012791869-JSAPI支付常见问题、4012791870-JSAPI支付开发指引 

 正式环境下调起被拦截,返回 system:access_denied 或 getBrandWCPayRequest:fail_no permission to execute,拉不起微信支付收银台,交易无法完成。 

 小程序经营虚拟商品须接入官方虚拟支付能力,不涉及虚拟商品的须补充实物或服务类目

 说明:小程序经营虚拟商品交易的,须统一接入「官方虚拟支付能力」用于安卓及其余非 iOS 系统的线上支付;如小程序不涉及虚拟商品交易服务,须在账号后台补充实物交易/服务类目,能力限制将自动解封。
正确应该怎么做:① 先按小程序实际经营内容判定是否属于虚拟商品交易;② 属于虚拟商品的,按小程序官方虚拟支付能力接入,不在小程序内用 JSAPI 支付完成虚拟商品收款;③ 不属于虚拟商品的,登录账号后台「账号设置—服务类目」添加实物交易或服务类目,确认支付能力限制解除后再上线。 见 4012791869-JSAPI支付常见问题 

 小程序使用 JSAPI 支付时提示「小程序对应支付能力已被限制」,线上收款整体不可用。

二、产品权限与 AppID 绑定

注意事项

说明、正确应该怎么做

不做会怎么样

 指定身份支付须先单独开通权限

 说明:基础支付下单指定支付用户身份时,需单独开通指定身份支付权限;基础支付支持传入指定支付人姓名和身份证号进行本人支付检验。
正确应该怎么做:① 确认拟使用的支付产品及其下单接口支持指定支付人身份字段;② 向对接运营申请并开通指定身份支付权限;③ 权限开通后按下单接口文档传入指定支付人的身份信息。
见 4011935211-JSAPI支付常见问题 

 未开通指定身份支付权限时,相关下单或支付会提示商家暂无此类交易权限,指定支付人身份的校验能力无法使用。

 调用 APIv3 JSAPI 下单前须开通 JSAPI 支付产品权限并完成 AppID 绑定

 说明:JSAPI 支付是需单独申请的产品权限,同一商户号已开通的其他支付产品(如医保移动支付)权限不等同于 JSAPI 支付权限;下单使用的 appid 须已与该商户号完成授权绑定。
正确应该怎么做:① 使用商户号管理员账号登录微信支付商户平台(pay.weixin.qq.com),进入【产品中心】→【产品大全】;② 找到「JSAPI支付」点击【开通】/【申请】,按提示选择需绑定的公众号或小程序 AppID 并提交,已有商户号新增权限审核周期为 7 个工作日内;③ 登录公众平台【微信支付 → 商户号管理】,在「待关联商户号」中确认授权绑定;④ 通过【产品中心 → APPID账号管理 → 我关联的APPID账号】核实绑定结果后,再调用 /v3/pay/transactions/jsapi 下单;⑤ 新商户号接入时同步核对商户号、API 密钥、证书与 appid 均换成新商户号的配置。
典型反例:以同一商户号已开通的其他支付产品权限替代 JSAPI 支付权限,未单独申请开通即调用 JSAPI 下单接口;新商户号接入时直接复用原代码里已配置的 appid,未发起并完成该 appid 与新商户号的绑定。 见 4012791854-申请JSAPI支付权限指引、4013287010-管理商户号绑定的APPID账号、4012791856-JSAPI下单、4012791869-JSAPI支付常见问题、4012791870-JSAPI支付开发指引 

 调用 /v3/pay/transactions/jsapi 下单返回 NO_AUTH,提示「商户号该产品权限未开通,请前往商户平台>产品中心检查后重试」,无法取得 prepay_id。 

三、AppID、OpenID 与用户身份

注意事项

说明、正确应该怎么做

不做会怎么样

 JSAPI 支付须绑定并使用已通过微信认证的服务号 appid 

 说明:微信客户端内网页支付(JSAPI 支付)需要用已通过微信认证的服务号(或政府、媒体类认证公众号)的 appid 换取 openid 并下单;订阅号、未认证公众号不具备相应 scope 权限,小程序 appid 不能替代服务号 appid 用于该场景。
正确应该怎么做:① 接入前在公众平台确认账号类型与认证状态,非认证服务号先完成微信认证再接入;② 在商户平台「产品中心—APPID授权管理」发起绑定,并在公众平台确认授权后再发起交易;③ 用该服务号 appid 发起网页授权获取 openid,并用同一 appid 下单;④ 公众号发生改名、主体或认证信息变更后,重新确认账号类型与认证状态仍然有效。
典型反例:订阅号或认证已过期的账号仍按服务号方式接入支付;用小程序 appid 换取 openid 后按公众号场景下单。 见 4015423216-JSAPI支付开发接入准备、4012791869-JSAPI支付常见问题、4016328613-管理商户号绑定的APPID账号、4012791870-JSAPI支付开发指引 

 调起支付时报「此公众号并没有这些 scope 的权限」,错误码 10005;使用小程序 appid 时则报「appid和openid不匹配」或无法调起支付,公众号场景与小程序场景混用 appid 时交易链路无法走通。

 网页授权须按所需 scope 使用 snsapi_userinfo 授权方式

 说明:需要获取用户身份信息或完成微信登录时,网页授权须使用 snsapi_userinfo;snsapi_base 为静默授权,仅能取得 openid。
正确应该怎么做:① 生成授权链接时按业务需要选择 scope,需要用户信息的场景填 snsapi_userinfo;② 回调页取得 code 后交后端换取 openid 与用户信息,再进行 JSAPI 下单。
典型反例:需要完成微信登录的链路统一使用 snsapi_base 静默授权。 见 4012791869-JSAPI支付常见问题 、微信网页授权 

 授权与登录阶段报「此公众号并没有这些 scope 的权限」,错误码 10005,微信登录与后续支付流程中断。

 网页授权回调须公网可达且不能依赖固定IP

 说明:网页授权回调由用户浏览器访问 redirect_uri,该地址须为微信侧可正常访问的HTTPS回调地址;微信不提供可用于只开放固定出访IP的网页授权回调地址。
正确应该怎么做:① 将网页授权回调服务部署在可被公网用户访问的域名和端口;② 在公众平台配置对应的完整授权域名;③ 不要仅依赖IP白名单开放回调入口;④ 用真实手机和正式域名验证授权后可携带 code 正常返回;⑤ 后端再使用 code 换取 openid。
典型反例:把网页授权回调放在仅允许特定微信出口IP访问的防火墙后,未向公网用户开放。
见 微信网页授权、4012791870-JSAPI支付开发指引、 

 用户授权后回调页面不可达,无法取得 code 与 openid,后续H5签约或支付流程受阻。 

 网页授权 code 仅限使用一次,须防止重复换取并确认拿到 openid 后再下单

 说明:网页授权的 code 只能换取一次 openid,重复用同一 code 调用授权接口会被拒绝;openid 取不到时 JSAPI 下单即缺参。
正确应该怎么做:① 由后端接收回调中的 code 并立即换取 openid,换取成功后把结果按业务单据缓存,避免同一 code 被重复提交换取;② 对授权回调地址(redirect_uri)做防重复提交与并发控制,避免回调被重复触发时直接复用旧 code;③ 服务端确认已拿到非空 openid 后再调用 JSAPI 下单接口,未拿到时返回明确错误而不是继续下单。
典型反例:授权回调地址被重复访问两次,第二次仍拿同一 code 去换 openid;商户侧未做 code 去重。 见 微信网页授权、4012791870-JSAPI支付开发指引 

 换取 openid 时返回 40163 code been used,JSAPI 下单报「JSAPI下单,商户未传openid或者sub_openid」,该笔交易无法创建,偶发时表现为零星支付失败。

 JSAPI 下单的 openid 须由本次下单的 appid 获取,并由后端用 code 换取

 说明:下单传入的 openid 必须是本次下单所用 appid(服务商模式下为 sub_appid 或 sp_appid)下的用户标识;更换公众号或小程序后须用新 appid 重新走网页授权获取,旧 appid 下的 openid 不能沿用。这与「openid 所属用户须与实际付款用户一致」是两条不同约束,需同时满足。
正确应该怎么做:① 在本次实际发起支付的公众号/小程序所对应的 appid 下发起网页授权取得 code;② 回调页把 code 交商户后端换取 openid(secret、access_token 不下发到页面),授权链接里的 appid 须与下单 appid 一致;③ 服务端校验 openid 非空后再下单,并把该 openid 与下单 appid 一并入库留存;④ 下单前确认该字段填的是 openid 值(形如 o 开头的 28 位标识)而非 appid 本身。
典型反例:更换新小程序下单后,仍把旧 appid 下缓存的 openid 传给下单接口;下单报文中 openid 字段误填成了 appid 的值。 见 4012791870-JSAPI支付开发指引、4012791869-JSAPI支付常见问题、微信网页授权 

 下单返回 PARAM_ERROR,提示「appid和openid不匹配」(服务商模式为「sub_appid和sub_openid不匹配」)或「无效的openid」,订单无法创建,用户无法进入收银台。 

 下单传入的 openid 所属用户须与实际付款用户一致

 说明:下单 openid(服务商模式下为 sp_openid / sub_openid)所属用户,必须与实际拉起收银台付款的用户为同一人,该校验按商户号维度生效;即使 openid 是实时获取的,若所属用户与实际付款人不一致也会被拦截。
正确应该怎么做:① 在用户实际付款的微信客户端内完成网页授权,确保换取的 openid 属于当前付款用户;② 服务端在下单前校验已拿到非空 openid,未拿到时不向前端返回调起参数;③ 不把带有用户 A openid 的支付链接、二维码或调起参数分享给用户 B 打开付款。
典型反例:把已生成的、带有他人 openid 的支付页面链接或静态码发给另一用户扫码付款;把已带用户 A openid 生成的下单链接或收银台会话分享给用户 B 打开付款。 见 4013334850-JSAPI支付常见问题(服务商)、4012791870-JSAPI支付开发指引、4012791869-JSAPI支付常见问题 

 用户调起支付时提示「下单账号与支付账号不一致,请核实后再支付」,无法完成付款;同一商户号下批量出现时表现为大面积支付失败。

四、支付授权目录与网页授权域名

注意事项

说明、正确应该怎么做

不做会怎么样

 获取 openid 的网页授权域名与调起支付的支付授权目录须分别配置

 说明:这是两套相互独立的配置——网页授权域名在公众平台(该 appid 所属公众号/小程序)配置,用于网页授权获取 code/openid,固定最多 2 个;JSAPI 支付授权目录在收单侧的支付后台配置,用于调起支付:普通商户(直连)在商户平台「产品中心—开发配置—支付授权目录」配置,一个商户号最多 5 个;服务商模式在服务商平台配置,服务商最多为全体子商户配置 5 个,也可再为每个子商户单独配置 5 个,服务商或子商户其中一处配置了匹配目录即可调起支付。两类模式的网页授权域名都在公众平台侧配置,商户平台/服务商平台上的支付授权目录不能替代它;只配支付授权目录时,网页授权仍会失败。支付授权目录须填写支付页面所在目录并以 / 结尾,域名须已完成 ICP 备案;未配置或配置不一致时调起支付会报「当前页面的 URL 未注册」,见 4012791870-JSAPI支付开发指引。
正确应该怎么做:① 登录公众平台,在「设置—公众号设置—功能设置—网页授权域名」配置实际发起授权的域名;② 普通商户登录商户平台「产品中心—开发配置—支付授权目录」添加目录;服务商登录服务商平台,为全体子商户配置走「产品中心—开发配置」,为指定子商户单独配置走「合作伙伴功能—商户基础服务—开发配置参数—搜索子商户号—开发配置」,配置后一般 5 分钟内生效;③ 服务商模式下按实际承接支付页面的商户范围,确认是走全体子商户配置还是该子商户的单独配置;④ 两套配置都完成后再联调下单与调起。
典型反例:只在商户平台或服务商平台维护了支付授权目录,就认为公众平台侧的网页授权域名也已配置完成;服务商模式下只维护了服务商自身(全体子商户)的目录,未确认实际承接支付页面的子商户是否已有匹配目录。 见 4015423216-JSAPI支付开发接入准备、4013287088-配置JSAPI支付授权目录、4012069853-开发接入准备(服务商)、4013335127-配置JSAPI支付授权目录(服务商)、4012069859-JSAPI支付开发指引(服务商) 

 网页授权跳转报「redirect_uri域名和后台配置不一致,错误码 10003」,拿不到 code,无法换取 openid,JSAPI 下单链路中断。

 支付授权目录须按调起支付页面的实际目录配置,协议、域名、目录与大小写均须一致

 说明:调起收银台前会校验实际支付页面 URL 与商户平台(服务商模式为服务商平台)配置的支付授权目录是否匹配;只配置到域名时只校验协议与域名,配置到最后一级目录时还校验多级目录;区分大小写、不支持 IP 形式,须以 http:// 或 https:// 开头并以 / 结尾;服务商模式下服务商(全体子商户)或子商户单独其一配置了匹配目录即可调起。
正确应该怎么做:① 取实际调起支付页面的完整 URL,去掉文件名后得到目录(如 https://www.weixin.com/123/456/abc.html → https://www.weixin.com/123/456/);② 登录商户平台「产品中心—开发配置—支付授权目录」(服务商模式为服务商平台「产品中心—开发配置」或「合作伙伴功能—商户基础服务—开发配置参数」按子商户号单独配置)添加该目录,配置后一般 5 分钟内生效;③ 按报错提示中给出的实际地址核对;④ 页面较多且仅域名、协议相同时可只配置到域名以缩减配置数量。
典型反例:页面由 http:// 升级为 https:// 后只保留原 http:// 目录,未新增 https:// 目录;只配置到多级目录的上一级目录;协议或大小写与页面不一致。 见 4013287088-配置JSAPI支付授权目录、4013335127-配置JSAPI支付授权目录(服务商)、4013334850-JSAPI支付常见问题(服务商)、4012791870-JSAPI支付开发指引 

 调起支付时提示「当前页面的 URL 未注册」,用户无法拉起收银台;使用 JS-SDK 时表现为 chooseWXPay:fail, the permission value is offline verifying。 

 网页授权域名须在公众平台配置为完整域名,并与实际授权回调域名一致

 说明:网页授权域名须填写实际发起授权的完整域名,只填主域名不覆盖其下子域名;服务商机构下的交易仍须在该 appid 所属公众号平台完成配置,机构账户与子商户账户上的配置不能替代。redirect_uri 须指向该域名下的页面并正确 URL 编码,不一致时授权页返回 10003「redirect_uri域名与后台配置不一致」,见 微信网页授权。
正确应该怎么做:① 登录公众平台「设置—公众号设置—功能设置—网页授权域名」,逐个填写实际发起授权的域名;② 生成授权链接时核对 redirect_uri 所属域名与后台配置完全一致;③ 服务商机构下的交易在该 appid 所属公众号平台配置,不以机构账户或子商户账户上的配置替代。
典型反例:只配置主域名即认为其下子域名均已生效;仅在机构账户或子商户账户配置域名而未在公众号侧配置。 见 4013334850-JSAPI支付常见问题(服务商)、4012791870-JSAPI支付开发指引 

 授权阶段报「redirect_url 域名与后台配置不一致」(错误码 10003),或交易报「解析 openid 业务失败」,取不到 openid 导致 JSAPI 下单失败。

五、签名、证书与验签

注意事项

说明、正确应该怎么做

不做会怎么样

 使用 APIv3 须先在商户平台设置 APIv3 密钥,才能解密支付成功回调取得业务内容

 说明:APIv3 回调通知中的业务数据以 AEAD_AES_256_GCM 加密后放在 resource.ciphertext 中,商户须用在商户平台设置的 APIv3 密钥(32 位字母数字组合)解密后才能取得明文;回调的签名校验使用的是平台证书或微信支付公钥,与 APIv3 密钥是用途不同的两套凭证(密钥用于解密回调与平台证书,证书/公钥用于验签与加密敏感字段),APIv3 密钥与 APIv2 密钥也相互隔离、互不影响。未设置 APIv3 密钥时,支付成功回调无法加密下发。
正确应该怎么做:① 由超级管理员登录商户平台「账户中心—账户设置—API安全—APIv3密钥」设置 32 位 APIv3 密钥(设置后不支持查看,只支持重新设置),并把密钥配置到服务端的回调解密逻辑中;② 同时按方案 A(微信支付公钥,推荐)或方案 B(平台证书)完成验签凭证配置,两套只取一套、不混用;③ 完成配置后再联调支付,并核验能正常收到且能成功解密支付成功回调通知。 见 4012072195-配置APIv3密钥、4012071382-如何解密回调报文和平台证书、4012791861-支付成功回调通知、4024350132-证书密钥概览 

 用户已支付成功但商户侧收不到支付成功回调通知;即使收到回调,也因缺少 APIv3 密钥无法解密出业务内容,订单状态无法及时更新,只能靠查单兜底。

 新申请商户号默认使用微信支付公钥验签模式,须按实际验签模式获取验签凭证

 说明:目前新申请的商户号默认使用微信支付公钥验签模式,该模式下没有平台证书,调用下载平台证书接口(GET /v3/certificates)获取不到平台证书。
正确应该怎么做:① 接入前先确认商户号的验签模式(商户平台「账户中心—API安全」查看微信支付公钥/平台证书);② 使用微信支付公钥验签模式的,按微信支付公钥方式获取并使用公钥验签;③ 确认必须使用平台证书的,按「如何从微信支付公钥切换成平台证书」指引完成切换后再调用下载平台证书接口。 见 4015419357-如何从微信支付公钥切换成平台证书、4012153196-微信支付公钥产品介绍 

 调用 /v3/certificates 报获取不到平台证书,按平台证书方案编写的验签逻辑初始化失败,接口调用整体中断。

六、防重复下单与 prepay_id 有效期

注意事项

说明、正确应该怎么做

不做会怎么样

 前端支付入口须做防抖拦截,服务端须对同一业务单据做幂等控制

 说明:支付结果确认前若再次露出支付入口,且服务端未做幂等校验,用户在快速连点、网络卡顿或设备响应延时下会对同一笔业务生成多笔不同 out_trade_no 的订单并多次扣款。未支付订单再次发起支付仍复用原 out_trade_no,不为每次请求生成新的商户订单号,见 4011984682-支付回调和查单实现指引。
正确应该怎么做:① 前端在用户点击「下单/支付」后立即置灰禁用入口,待接口返回或查单/回调确认终态后再恢复;② 服务端对同一业务单据做防重复提交与幂等控制,重复请求直接复用并返回原支付单参数;③ prepay_id 未满 2 小时用原参数调起,已满 2 小时用原 out_trade_no 和原参数重新下单,确保同一笔业务只生成一笔有效支付单。
典型反例:前端已做按钮防抖(按下后 5 秒才允许再次点击),但服务端无防重复提交兜底策略,并发或设备延时响应时仍生成多笔订单;仅在前端做限制、队列化异步处理未做单据级去重;支付结果确认前就重新露出付款入口。 见 4012791870-JSAPI支付开发指引、4012069859-JSAPI支付开发指引(服务商)、4012791869-JSAPI支付常见问题 

 同一笔业务生成多笔订单并导致用户重复扣款,商家收到用户客诉并产生额外的人工核对与退款成本;在充电桩、场馆预约等场景下还会造成同一用户占用多份设备或库存资源。

 调起支付须在 prepay_id 有效期内完成,超期须用原参数重新下单

 说明:JSAPI 下单成功后返回的 prepay_id 有效期为 2 小时,超过后不能再用于调起支付。
正确应该怎么做:① 下单成功后及时用返回的 prepay_id 组装调起支付参数并返回前端拉起收银台;② 弱网、机舱网络等可能导致用户长时间停留在页面的场景,服务端须在超过 2 小时后用原 out_trade_no 和原参数重新调用下单接口获取新的 prepay_id,不得沿用已过期的值。
典型反例:下单后把 prepay_id 缓存并留给用户十几分钟甚至更久之后才拉起支付,未做过期重下单处理。 见 4012791870-JSAPI支付开发指引、4012791856-JSAPI/小程序下单 

 用已过期的 prepay_id 调起支付会失败,无法拉起收银台,用户侧表现为支付流程中断,需要重新下单并重新走一次拉起流程。

七、调起支付参数与 JS-SDK

注意事项

说明、正确应该怎么做

不做会怎么样

 使用 JS-SDK 调起支付前须先完成 wx.config,并在 wx.ready 回调中调用

 说明:wx.config 用于校验当前页面并注入本次要用的 JS 接口权限,是异步过程;用 wx.chooseWXPay 拉起收银台时,jsApiList 必须包含 chooseWXPay,且须等 wx.ready 触发后再调用,在此之前调用权限尚未注入。
正确应该怎么做:① 页面引入 JS-SDK 后先由服务端下发签名等参数并调用 wx.config,确认 wx.config 成功通过;② jsApiList 中显式声明 chooseWXPay;③ 页面加载完成即需拉起支付的,把 wx.chooseWXPay 写在 wx.ready 回调函数内,由用户点击触发的也须在 wx.ready 之后执行;④ 在真机微信内置浏览器中验证,不在模拟器或外部浏览器中验证。
典型反例:把 wx.chooseWXPay 写在 wx.config 之后但未放进 wx.ready 回调,config 异步未完成时即调起。 见 4012791870-JSAPI支付开发指引、JS-SDK 使用说明、4020401138-JS-SDK使用权限签名 

 首次可能偶尔调起成功、之后每次调起均报 the permission value is offline verifying,支付功能整体不可用。 

 调起支付的 package 参数须为 prepay_id=xxx 格式且不可为空

 说明:调起支付时 package 取的是下单接口返回的 prepay_id,格式为 prepay_id= 后直接拼接该值,不是只传 prepay_id 本身,也不能为空。
正确应该怎么做:① 服务端下单成功后把 prepay_id 原样保存并返回给前端;② 前端构造调起参数时按 package: "prepay_id=wx201222229874569b201de80e089456213" 的格式拼装;③ 用户关闭收银台后重新发起时,先复用未过期的 prepay_id,已过期则用原 out_trade_no 和原参数重新下单取新的 prepay_id。 见 4012791870-JSAPI支付开发指引、4012791857-JSAPI调起支付 

 前端报「调用支付JSAPI缺少参数:total_fee」,无法拉起收银台。

 调起支付参数 appId 须与下单 appid 及当前实际调起支付的公众号一致

 说明:调起支付参数 appId 须填写下单接口传入的 appid,且必须与当前实际调起支付的公众号一致;服务商模式下填写下单时传入的 sp_appid 或 sub_appid,当前实际调起支付的公众号必须是二者之一。
正确应该怎么做:① 后端下单时记录本次实际使用的 appid(服务商模式为 sp_appid 或 sub_appid)并随订单落库;② 由后端用同一个值生成调起支付参数中的 appId,不使用前端页面或路由中携带的 appid,也不跨主体取值;③ 联调前确认当前页面所属公众号与下单使用的 appid 为同一账号。
典型反例:后端按商户配置取 appid 下单,前端按当前页面所属公众号另取一个 appid 拼装调起参数。 见 4012791857-JSAPI调起支付、4012069855-JSAPI调起支付(服务商)、4012791870-JSAPI支付开发指引、4012069859-JSAPI支付开发指引(服务商) 

 无法调起支付,或提示账号不一致,用户无法完成付款。

 下单接口的 appid 与调起支付的 appId 参数名不同,须分别按各接口文档拼写

 说明:该参数在 JSAPI 下单接口的请求包体中为全小写 appid(服务商模式为 sp_appid / sub_appid),在 JSAPI 调起支付的前端参数与签名串中为驼峰 appId;调起支付其余参数 timeStamp、nonceStr、signType、paySign 同样为驼峰命名。两处取值必须相同,拼写须各自遵循所属接口的字段定义。
正确应该怎么做:① 后端调用下单接口时按文档写 appid(服务商模式写 sp_appid、sub_appid);② 后端生成调起支付参数并计算 paySign 时,按文档写 appId、timeStamp、nonceStr、signType;③ 不把下单请求体原样透传给前端当作调起参数,也不在签名串与调起参数之间混用大小写。
典型反例:直接把下单请求体的 appid 作为调起参数传给前端,导致调起参数中缺少 appId。 见 4012791856-JSAPI下单、4012738519-JSAPI下单(服务商)、4012791857-JSAPI调起支付、4012069855-JSAPI调起支付(服务商) 

 调起参数缺少 appId 导致无法拉起收银台;签名串与调起参数命名不一致时 paySign 校验不通过,支付失败。

八、支付结果、查单与关单

注意事项

说明、正确应该怎么做

不做会怎么样

 支付回调地址须公网可达并以查单兜底

 说明:notify_url 须为公网可访问的 HTTPS 全路径,不能使用内网地址;回调失败或未收到通知时,须主动调用查单接口确认订单状态。
正确应该怎么做:① 配置真实、公网可访问的 HTTPS notify_url,不要携带参数;② 防火墙/安全组放行微信支付回调 IP;③ 回调处理验签并在 5 秒内应答;④ 未收到回调时按查单指引轮询查询订单,不要直接更换订单号重新下单。
典型反例:notify_url 使用内网地址或防火墙未放行回调 IP,导致微信侧连接超时;仅依赖回调更新订单状态,没有查单兜底。
见 4012075420-回调通知注意事项、4012075249-支付回调和查单实现指引 

 回调请求超时或失败(工单日志为 网络读写超时(-1003)),商户收不到支付结果通知,订单状态不同步,可能影响发货、退款或引发用户投诉。 

 NOTPAY 不得直接判定为支付失败,须先查单再决定是否关单

 说明:未支付状态下用户仍可能继续完成付款;需要订单进入终态时,须由商户主动调用关单接口。下单未传 time_expire 时,系统以下单时间为起点,超过 7 天未支付的订单无法再支付。未主动关单的订单在下单后较长时间内仍可被支付,应按业务时效设置 time_expire,超时或取消时调用关单接口,见 4012791881-关闭订单。
正确应该怎么做:① 先查单确认 trade_state;② 确认仍为 NOTPAY 且不再需要收款时调用关单接口,关单返回「订单已支付」则重新查单并按已支付处理;③ 关单成功后本地标为已关闭,用户再次购买时用新的 out_trade_no 重新下单。
典型反例:查到 NOTPAY 就直接把本地单置为失败并释放库存。 见 4012791870-JSAPI支付开发指引 

 出现「微信侧已支付、商户侧记为失败」的差异单,引发重复下单、超卖或漏发货;不主动关单时订单长时间停留在未支付态,商户无法判断终态。

 下单与查单须使用同一套产品接口,不得跨产品混用

 说明:通过基础支付统一下单接口创建的订单,须使用对应的基础支付查单接口查询,不能用其他产品(如酒店押金)的查单接口查询该笔订单;操作员手工查询时须按订单业务类型区分查询入口。
正确应该怎么做:① 在系统中按下单接口与查单接口一一对应的关系配置查询路由;② 提供人工查询入口时按订单所属业务类型区分,不让操作员跨产品选择查单接口;③ 对历史混用逻辑排期改造,统一为基础支付下单—基础支付查单的配套调用。
典型反例:为省事统一调用酒店押金查单接口查询所有订单(含统一下单产生的订单)。 见 4012791870-JSAPI支付开发指引 

 跨产品查单后续可能返回报错,订单状态无法确认,对账与补单流程受阻。

 下单须传入 time_expire 明确用户可完成支付的最后时限

 说明:time_expire 是用户能够完成该笔订单支付的最后时限(并非订单关闭时间),须按 rfc3339 格式 yyyy-MM-DDTHH:mm:ss+TIMEZONE 传入,取值须在下单时间 15 天以内且不早于下单时间后 1 分钟,超出边界的取值会被自动调整。未传时系统默认以下单时间为起始点计算,超过 7 天未支付的订单无法再支付。
正确应该怎么做:① 下单时按业务可接受的收款窗口计算并传入 time_expire(如 2015-05-20T13:29:35+08:00);② 超过该时限且订单仍为 NOTPAY 时,调用关单接口关闭订单,再使用新的 out_trade_no 重新下单生成全新订单;③ 与本地订单超时、库存释放策略对齐。
典型反例:依赖默认 7 天时效承接短时有效的订单(限时优惠、座位或库存占用),本地已超时放行后用户仍能完成支付。 见 4012791856-JSAPI下单、4012738519-JSAPI下单(服务商)、4012791870-JSAPI支付开发指引、4012069859-JSAPI支付开发指引(服务商) 

 商户业务上已超时失效的订单在微信侧仍可被支付,产生「已释放库存或已过期优惠却被付款」的差异单;未传 time_expire 时超过 7 天的订单无法再支付,用户付款被拒。

 APIv3 支付是否成功须看查单的 trade_state 或支付成功回调,不能把下单返回的 prepay_id 当成已付款

 说明:POST /v3/pay/transactions/jsapi 返回 HTTP 200 和 prepay_id 只表示预支付会话已生成,用于调起支付,不代表用户已付款。是否支付成功看查单返回的 trade_state(SUCCESS 为支付成功)或支付成功回调。前端返回 get_brand_wcpay_request:ok 不保证绝对可靠,须再查单。长时间未收到支付成功回调时须轮询查单,不能以未收到回调判断订单未支付。
正确应该怎么做:① 下单返回 prepay_id 后只用于调起支付,不把订单标为已支付;② 后端接入「商户订单号查询订单」或「微信支付订单号查询订单」至少一个;③ 前端返回成功或报错后都交由后端查单,按 trade_state 更新订单;④ 未收到支付成功回调时按查单指引轮询查单,不以未收到回调当作未支付;⑤ 不以 get_brand_wcpay_request:ok 作为支付成功依据。
典型反例:把下单返回的 prepay_id 或前端 ok 当作支付成功并据此履约;只等支付成功回调,回调未到时订单一直停在未支付。 见 4012791856-JSAPI下单、4012791859-商户订单号查询订单、4012791861-支付成功回调通知、4012791857-JSAPI调起支付、4012075249-支付回调和查单实现指引、4012791870-JSAPI支付开发指引 

 把下单返回的 prepay_id 当成已支付时,查单 trade_state 仍可能是 NOTPAY,导致提前发货或错误履约;回调未到就当未支付时,用户已扣款而订单仍显示未支付,引发重复支付与用户投诉,商家需人工核对与退款。