1. 微信支付三剑客H5、JSAPI、Native的核心区别第一次接触微信支付接入时我被H5、JSAPI、Native这三个名词搞得晕头转向。直到踩过几次坑才明白它们其实对应着三种完全不同的支付场景。简单来说H5支付是给普通浏览器用的JSAPI专供微信生态内部使用而Native支付则是PC网页扫码支付的解决方案。去年我们做电商项目时就因为在H5页面错误调用了JSAPI接口导致安卓用户无法支付。后来排查发现关键区别在于运行环境和身份验证方式H5支付就像给所有浏览器发的通用门票不需要微信登录态。用户在手机浏览器访问你的网站时点击支付会跳转到微信支付页面。典型场景比如用户在Safari打开淘宝下单选择微信支付。JSAPI支付相当于微信生态的VIP通道必须要有微信登录态openid。这个通道又分两个入口一个是微信公众号/服务号里的网页另一个是微信小程序。比如在京东小程序下单或者从公众号文章跳转到商城页面付款。Native支付这是PC端的解决方案生成支付二维码让用户用手机微信扫码。常见于PC版美团外卖、携程网页版等场景。注意JSAPI和H5最容易被混淆。判断标准很简单——如果页面能在Chrome浏览器正常打开就必须用H5如果页面只能在微信里打开才能用JSAPI。2. H5支付非微信浏览器的万能钥匙2.1 适用场景与限制条件上周帮一个客户调试H5支付时他们疑惑为什么在微信内置浏览器调用H5支付会被拦截。其实这是微信的环境检测机制在起作用当检测到微信环境时会自动阻止H5支付流程强制要求改用JSAPI。H5支付的核心特点是适用所有手机浏览器包括iOS的Safari、安卓的Chrome不需要提前获取用户openid支付流程会跳出商户页面进入微信支付页单笔金额限制较严格通常单笔≤5万典型使用场景手机浏览器访问的电商网站APP内嵌WebView发起的支付需配置支付域名白名单短信链接打开的支付页面2.2 服务商模式配置实战配置H5支付时最容易出错的是**场景信息scene_info**部分。这是微信用于风控的重要参数缺少可能导致支付失败。以下是经过实测的PHP示例$data [ sp_appid 服务商APPID, sp_mchid 服务商商户号, sub_mchid 子商户号, description 测试订单, out_trade_no NO.date(YmdHis), notify_url https://yourdomain.com/notify, amount [ total 1, // 单位分 currency CNY ], scene_info [ // 关键参数 payer_client_ip 用户IP, h5_info [ type Wap, app_name 你的应用名, app_url https://yourdomain.com ] ] ];常见踩坑点h5_info里的app_url必须与商户平台配置的支付域名一致测试环境建议金额设为1分钱避免误操作确保服务器时间与北京时间误差在1分钟内3. JSAPI支付微信生态的专属通道3.1 双模式下的参数选择JSAPI支付在服务商模式下有个特别容易搞混的点——到底用sp_openid还是sub_openid这取决于用户是通过谁家的公众号/小程序发起的支付。去年我们对接一个连锁品牌时他们既有服务号又有各分店的小程序。最终方案是总部服务号菜单进入的页面 → 用sp_openid服务商APPID分店小程序发起的支付 → 用sub_openid子商户APPID关键区别在于openid的生成来源sp_openid用户通过服务商公众号授权登录获得sub_openid用户通过子商户公众号/小程序授权获得3.2 小程序支付的特别注意事项小程序支付必须使用sub_openid这是微信的强制要求。因为小程序的登录体系是独立的无法跨APPID使用。具体流程前端调用wx.login()获取code将code传给后端用子商户的APPID和密钥换取openid支付时必须传这个openid和对应的子商户APPID错误示例会导致支付失败// 错误不能用服务商APPID换小程序openid wx.request({ url: https://api.weixin.qq.com/sns/jscode2session, data: { appid: 服务商APPID, // 这里必须是小程序自己的APPID js_code: code, grant_type: authorization_code } })4. Native支付PC端扫码的最佳实践4.1 二维码生成与状态维护Native支付最麻烦的不是发起支付而是支付状态同步。我们吃过亏——用户扫码后付款成功但页面一直显示等待支付。问题出在没有正确处理异步通知。推荐的做法是生成二维码时创建数据库订单记录状态为待支付前端每10秒轮询查询订单状态同时配置微信支付通知回调notify_url收到回调后更新订单状态并通知前端Python生成二维码的示例import qrcode from wechatpayv3 import WeChatPay wxpay WeChatPay( appid服务商APPID, mch_id商户号, keyAPI密钥 ) def create_native_order(): resp wxpay.create_order( out_trade_no订单号, total_fee100, # 单位分 body商品描述, notify_urlhttps://yourdomain.com/notify ) qr qrcode.QRCode() qr.add_data(resp[code_url]) img qr.make_image() img.save(payment.png)4.2 多商户号下的路由策略对于平台型电商需要根据商户动态选择子商户号。我们的解决方案是建立商户号映射表缓存根据商品ID查找对应子商户信息支付时动态传入sub_mchid关键代码逻辑// Java示例 public String getSubMchId(String productId) { // 从缓存获取商户配置 MerchantConfig config cache.get(merchant:productId); if(config null) { config db.query(SELECT * FROM merchants WHERE product_id ?, productId); cache.set(merchant:productId, config); } return config.getSubMchId(); }5. 支付方式选型决策树面对三种支付方式我总结了一个快速决策流程运行环境是什么PC网页 → Native手机浏览器 → H5微信内公众号/小程序 → JSAPI是否微信生态是 → 是否需要子商户隔离需要 → JSAPIsub_openid不需要 → JSAPIsp_openid否 → H5是否需要扫码支付是 → Native否 → 回到第1步判断最近帮一个在线教育平台做支付改造时他们既有PC端课程购买Native又有公众号内的会员续费JSAPI还有外部推广链接带来的新用户H5。按照这个决策树梳理后支付失败率从15%降到了3%以下。