公众号&H5微信支付接入
商户在微信公众平台或开放平台提交微信支付申请,微信支付工作人员审核资料无误后开通相应的微信支付权限。微信支付申请审核通过后,商户在申请资料填写的邮箱中收取到由微信支付小助手发送的邮件,此邮件包含开发时需要使用的支付账户信息。
支付接入流程

支付场景
JSAPI(公众号支付)
商户已有H5网站,用户通过消息或扫描二维码在微信内打开网页时,可以调用微信支付完成下单购买的流程
只能从微信浏览器中发起
可用微信浏览器内置方法,不需要引入微信jssdk
官方文档
H5支付
H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,
商户发起本服务呼起微信客户端进行支付。主要用于触屏版的手机浏览器请求微信支付的场景。可以方便的从外部浏览器唤起微信支付
支付配置:登录商户平台-->产品中心-->我的产品-->支付产品→H5支付
用户从非微信浏览器进入发起支付,不能从微信客户端调起
要求商户已有H5商城网站,并且已经过ICP备案
官方文档
JSAPI支付(公众号支付)
步骤一:添加开发者,微信授权登录配置
添加开发者
公众号登录管理后台,启用开发者中心,在开发者工具——web 开发者工具页面,向开发者微信号发送绑定邀请:

微信授权登录
开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头,授权回调域名配置规范为全域名,比如需要网页授权的域名 为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权。回调域名最多添加两个,需上传指定文件至回调域名根目录:

| scope参数 | 说明 |
|---|---|
| snsapi_base | 静默授权,获取openid,直接进入业务页面,用户无感知 |
| snsapi_userinfo | 需要用户手动同意,获取用户基本信息,对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scope为snsapi_userinfo,也是静默授权,用户无感知 |
具体而言,网页授权流程分为四步:
1、引导用户进入授权页面同意授权,获取code,接口示例:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
2、通过code换取网页授权access_token(与基础支持中的access_token不同)
3、如果需要,开发者可以刷新网页授权access_token,避免过期
4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
前端授权获取code后通过code调用后端接口获取用户信息,需要提供AppId,AppSecret
步骤二:设置支付域名与支付回调目录。
在微信商户平台(pay.weixin.qq.com)设置您的JSAPI支付支付目录,设置路径:商户平台-->产品中心→开发配置,JSAPI支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。
支付目录配置

请求目录与设置目录必须一致,否则验证失败,支付不成功。
步骤三:微信内调用支付可用微信浏览器内置方法(不需要引入微信jssdk):
if (typeof WeixinJSBridge === 'undefined') {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
{
appId: newLevelOrder.appId,
timeStamp: newLevelOrder.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: newLevelOrder.nonceStr, // 支付签名随机串,不长于 32 位
package: `prepay_id=${newLevelOrder.prePayId}`, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: newLevelOrder.paySign, // 支付签名
},
function(res: any) {
if (res.err_msg === 'get_brand_wcpay_request:ok') {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
// Toast.info('支付成功', 1, () => {});
router.push('/package-buy/pay-success');
} else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
Toast.info('取消支付', 1);
} else if (res.err_msg === 'get_brand_wcpay_request:fail') {
// Toast.info('支付失败', 1);
router.push(
`/package-buy/pay-fail?name=${query.name}&price=${query.h5Price}&packid=${query.id}&type=${query.type}`,
);
}
},
);
}
网页端接口请求参数列表(参数需要重新进行签名计算,参与签名的参数为:appId、timeStamp、nonceStr、package、signType,参数区分大小写与顺序。)
调起支付请求参数由后端server调用统一下单接口返回,需提供AppId等。
微信支付接口签名校验工具,此工具旨在帮助开发者检测调用【微信支付接口API】时发送的请求参数中生成的签名是否正确。
本地开发使用开发者工具,可用https://ngrok.com/做内网穿透,实现本地授权回调,支付调起需真机环境
微信平台与名词说明
H5支付接入
微信平台申请:登录微信商户平台-->产品中心-->我的产品-->支付产品--> H5支付

申请流程:选择 H5支付-->填写 H5 支付产品设置

1)写入对应的支付域名(最多可添加5个),域名必须通过 ICP 备案;当域名备案主体与公司名称不一致,需要上传授权函(设置页面不支持直接上传);上传方式:账户中心-->企业账号-->公司网站,输入网址,上传授权函(审核3-7个工作日)
2)填写售卖场景/使用产品
3)输入产品对应网站域名
点击提交申请,页面提示审核时间为3-5个工作日(审核结果会反馈在消息中心)
流程:
1、用户在商户侧完成下单,使用微信支付进行支付
2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB
3、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”),商户通过mweb_url调起微信支付中间页
4、中间页进行H5权限的校验,安全性检查(此处常见错误请见下文)
5、如支付成功,商户后台会接收到微信侧的异步通知
6、用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)
7、商户在展示页面,引导用户主动发起支付结果的查询
8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态
10、展示最终的订单支付结果给用户
使用JS-SDK实现公众号支付
步骤一: 在公众号后台配置相关参数“网页授权域名”、“JS接口安全域名”,在商户后台配置“支付授权目录”。
| 参数名称 | 配置地址 | 意义 | 可配置个数 |
|---|---|---|---|
| 网页授权域名 | 公众号后台-公众号设置-功能设置 | 在获取code的接口中配置的redirect_uri必须在这个域名下 | 2个 |
| JS接口安全域名 | 公众号后台-公众号设置-功能设置 | 调用微信开放的JS接口的页面必须在此域名下 | 3个 |
| 支付授权目录 | 产品中心-开发配置-支付授权目录 | 调起微信支付的页面所在的目录 | 5个 |
步骤二:在需要调用JS接口的页面引入JS-SDK: 。
步骤三:通过config接口注入权限验证配置。
所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。
wx.config({
debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp: , // 必填,生成签名的时间戳
nonceStr: '', // 必填,生成签名的随机串
signature: '',// 必填,签名
jsApiList: [] // 必填,需要使用的JS接口列表
});
步骤四:通过ready接口处理成功验证、通过error接口处理失败验证。
wx.ready(function () {
wx.checkJsApi({
jsApiList: ['chooseWXPay'], // 需要检测的JS接口列表,所有JS接口列表见附录2,
success: function () {
// 以键值对的形式返回,可用的api值true,不可用为false
// 如:{"checkResult":{"chooseImage":true},"errMsg":"checkJsApi:ok"}
}
});
});
config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
wx.error(function(res){
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开 config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
});
步骤五:发起一个微信支付请求。
wx.chooseWXPay({
timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
nonceStr: '', // 支付签名随机串,不长于 32 位
package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
signType: '', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
paySign: '', // 支付签名
success: function (res) {
// 支付成功后的回调函数
}
});
参数通过统一下单接口拿到,paySign 采用统一的微信支付 Sign 签名生成方法,注意这里 appId 也要参与签名,appId 与 config 中传入的 appId 一致,即最后参与签名的参数有appId, timeStamp, nonceStr, package, signType。