上一篇讲到拿到了 预支付交易标识 wx251xxxxxxxxxxxxxxxxxxxxxxxxxxxxx078700javascript
微信文档中已经明确给出了全部参数名和参与签名计算的参数,即php
微信文档中给出参与签名的参数是 appId、timeStamp、nonceStr、package、signType,要注意计算签名的方法和《微信支付 第二篇 JSAPI 调用统一下单接口获取预支付交易数据》计算方式是一致的,回顾一下html
须要注意的是,参数名要严格按照腾讯文档的命名方式,包括大小写,如 appId 不能写成 appid 或 appID。开发时为了方便,H5页面将部分参数设置成了可编辑文本框,先看一下它的样子前端
本例中,点击建立随机字符串将得到当前时间戳,将其做为 nonceStr 和 timeStamp 的值,点击建立签名计算出完整结果,本例中因为 JS 实现 hmacsha256 比较麻烦,就改用了 MD5 方式,根据微信要求统一下单接口中的签名算法也改成了 MD5,下面列出本例实现代码java
<!--建立完整签名--> <script type="text/javascript"> function onCreatePaySign() { // 从网页的各个文本框获取参数值 var appid = $("#text-appid").val(); var nonceStr = $("#text-nonceStr").val(); var prepayid = $("#text-prepayid").val(); var timeStamp = nonceStr; var signType = "MD5"; // 拼接字符串 var sourceStr = ""; sourceStr += "appId=" + appid; sourceStr += "&nonceStr=" + nonceStr; sourceStr += "&package=prepay_id=" + prepayid; sourceStr += "&signType=" + signType; sourceStr += "&timeStamp=" + timeStamp; sourceStr += "&key=asxxxxxxxxxxxxxxxN82"; // MD5方式计算 var hash = md5(sourceStr).toUpperCase(); // 在页面中查看一下计算结果 $("#text-paySign").val(hash); // 在控制台查看拼接字符串原文和MD5结果 console.log("拼接字符串结果: " + sourceStr); console.log("MD5结果: " + hash); } </script>
对比查看结果(为了避免泄露,appId和mchKey均做了处理,但由于算法固定,所以签名计算结果彻底不影响正确性)web
这一步的"坑"是,必需要在真实设备下进行访问,也就是手机、平板等运行微信APP的设备,微信开发者工具都不行,会报错没法运行。所以,H5 页面或者说运行微信支付的那部分 JS 必定要在真实设备上才能正确运行。先看一下微信给出的源代码(官方文档里有)算法
function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":"wx2421b1c4370ec43b", //公众号名称,由商户传入 "timeStamp":"1395712654", //时间戳,自1970年以来的秒数 "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //随机串 "package":"prepay_id=u802345jgfjsdfgsdg888", "signType":"MD5", //微信签名方式: "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ){ // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 } }); }
就是这段代码,必需要在真实设备运行,所以本例中采起的方式是将 H5 页面放到服务器上,用开发者工具运行 获取openid 和 获取预支付交易标识 两个步骤,拿到交易标识后在手机端微信里打开 H5 页面,生成签名并运行支付。根据实际状况,对放到 H5 页面中的 onBridgeReady 函数进行了修改,使其从文本框中获取真实数据api
<!--微信支付调用--> <script type="text/javascript"> function onBridgeReady() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId": $("#text-appid").val(), //公众号名称,由商户传入 "timeStamp": $("#text-nonceStr").val(), //时间戳,自1970年以来的秒数 "nonceStr": $("#text-nonceStr").val(), //随机串 "package": "prepay_id=" + $("#text-prepayid").val(), "signType": "MD5", //微信签名方式: "paySign": $("#text-paySign").val() //微信签名 }, function (res) { console.log("微信支付返回值:"); console.log(res); if (res.err_msg == "get_brand_wcpay_request:ok") { // 使用以上方式判断前端返回,微信团队郑重提示: //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。 alert("get_brand_wcpay_request:ok"); } alert(res.err_msg); alert(res); // 显示是个 Object }); } </script>
在手机中,点击页面上的支付按钮,将调起真实的微信支付页面,支付时忘了截图,首先先显示的是信息页和金额,点击支付输入密码/录入指纹,验证成功即支付成功,显示支付成功页面(这个有),而且在用户微信内也会接到来自微信支付的通知消息。本例实现时并无作H5支付成功后的处理页面,所以在支付成功页面中点击完成,就回到了H5页面中,运行了 function (res) 内的代码,并在弹窗中显示出了相关信息服务器
至此,完成了微信支付 JSAPI 支付主要流程。罗列一下关键点微信