网页开发者在项目中常常会遇到需要在 H5 页面中调用 APP 微信支付的情况。而使用微信支付,相对于其它支付方式,拥有便捷支付、高安全性、大众接受度高等优势。因此,本文将详细介绍个人开发 H5 调用 APP 微信支付的原理和步骤。
## 一、支付准备工作
在开始开发 APP 微信支付之前,需要先完成以下的支付准备工作:
1. 拥有微信商户号,在微信支付控制台完成商户注册和实名认证;
2. 在微信开放平台上创建应用,并获取 AppID;
3. 安装微信开发者工具。
## 二、微信支付流程
微信支付的流程分为两类,Web 接口和 Native 接口。Web 接口以网页形式呈现,不需要安装 App,只需使用微信扫一扫即可打开 Web 页面完成支付。而 Native 接口需要在移动设备上安装微信 App 才能调用微信支付。
本文主要讲解 Native 接口的微信支付流程。
1. 应用向微信终端发起支付请求,微信终端调起支付模块;
2. 用户输入密码或扫描指纹,在微信终端内完成支付;
3. 微信终端向商户服务器发送支付结果通知,商户服务器执行相关操作(比如发货、发票);
4. 微信支付完成。
## 三、H5 接入微信支付
H5 接入微信支付与 Native 接入微信支付的原理不一样,具体步骤如下:
1. 应用将支付信息发送给商户的服务器;
2. 商户服务器对支付信息进行验证,并调用微信支付统一下单 API,获取 prepay_id;
3. 商户服务器使用 prepay_id 进行签名,生成 JSAPI 支付请求参数;
4. 将 JSAPI 支付请求参数返回到 H5 页面;
5. H5 页面中调用微信 JSAPI 接口,并将该接口返回的数据通过“统一下单接口”获得的 prepay_id 生成微信支付界面。
具体步骤详见下文代码示例。
## 四、支付交互流程
以下是 H5 页面和 Native 端的交互流程:
1. H5 页面调用商户服务生成 JSAPI 支付参数;
2. 商户服务将生成的支付参数返回给 H5 页面;
3. 用户在 H5 页面上点击“支付”按钮;
4. H5 页面通过微信 JSAPI 调起微信原生支付界面;
5. 用户在微信原生支付界面内完成支付;
6. 返回到商户的支付结果回调页面,完成支付。
## 五、代码示例
下面是一个简单的微信 H5 支付实现示例,实例代码使用 Node.js 进行编写。
1. 首先在 Node.js 中选择 http 模块启动一个服务器:
```javascript
var http = require('http');
var url = require('url');
var util = require('util');
var fs = require('fs');
var path = require('path');
http.createServer(function(req, res) {
var pathname = url.parse(req.url).pathname;
var realPath = __dirname + pathname;
console.log(pathname);
fs.readFile(realPath, function(err, data) {...
```
2. 接着,在服务器起来时,我们访问服务器时会向服务器发送 GET 请求,在 Node.js 的 http 模块中,我们可以通过 req.url 获取到 url 中的参数,此时我们需要对接收到的信息进行签名和回调处理。这里示例代码采取了 GET 静默授权模式:
```javascript
var urlObj = url.parse(req.url, true);
var query = urlObj.query;
var sign = '';
// 签名算法
sign = ...
// 利用小程序的授权码code,获取openid和access_token
...
// 预支付交易单子
var paymentData = '';
// 可以在此处生成商户订单号
var out_trade_no = ...
// 支付信息
var paymentInfo = {
appid: 'your appid',
body: 'XXXX',
mch_id: 'your mch_id',
nonce_str: '',
notify_url: 'http://www.xxx.com/wxpay_notify.asp',
openid: '',
out_trade_no: out_trade_no,
spbill_create_ip: '192.168.2.210',
total_fee: '',
trade_type: 'JSAPI'
};
paymentInfo.nonce_str = ...
// 根据相关参数生成信息
paymentInfo.sign = ...
var innerXML = '' +
'appid' + paymentInfo.appid + '/appid>' +
'body' + paymentInfo.body + '/body>' +
'mch_id' + paymentInfo.mch_id + '/mch_id>' +
'nonce_str' + paymentInfo.nonce_str + '/nonce_str>' +
'notify_url' + paymentInfo.notify_url + '/notify_url>' +
'openid' + paymentInfo.openid + '/openid>' +
'out_trade_no' + paymentInfo.out_trade_no + '/out_trade_no>' +
'spbill_create_ip' + paymentInfo.spbill_create_ip + '/spbill_create_ip>' +
'total_fee' + paymentInfo.total_fee + '/total_fee>' +
'trade_type' + paymentInfo.trade_type + '/trade_type>' +
'';
var url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
...
```
3. 完成签名和支付信息的处理之后,我们向微信统一下单接口发送预支付单号生成请求:
```javascript
var options = {
hostname: hostname,
path: path,
method: method,
headers: {
'Content-Type': 'application/xml',
'Content-Length': Buffer.byteLength(reqBody)
}
};
var req = https.request(options, function(res) {
var resBody = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
resBody += chunk;
});
res.on('end', function() {
var parseString = require('xml2js').parseString;
parseString(resBody, function(err, result) {
if (result.xml.result_code == 'SUCCESS' &&
result.xml.return_code == 'SUCCESS') {
var ret = {
appId: paymentInfo.appid,
timeStamp: timeStamp.toString(),
nonceStr: paymentInfo.nonce_str,
package: 'prepay_id=' + result.xml.prepay_id,
signType: 'MD5'
};
ret.paySign = ...
}
});
});
});
req.on('error', function(err) {
console.log('请求微信支付服务器出错:' + err.message);
});
req.write(reqBody);
req.end();
```
4. 最后,我们将获得的微信支付 ID 处理为 JSAPI 支付方式,并将返回数据发送到 H5 页面:
```javascript
var jsApiData = {
appId : '',
timeStamp : '',
nonceStr : '',
package : '',
signType : 'MD5',
paySign : ''
};
jsApiData.appId = ...
jsApiData.timeStamp = ...
res.writeHead(200, {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
});
res.write(JSON.stringify(jsApiData));
res.end();
```
至此,我们就能在 H5 页面中调起微信原生支付界面,实现 H5 调用微信支付的功能了。
## 六、总结
以上就是个人开发 H5 调用 APP 微信支付的原理和步骤详解。需要注意的是,随着微信支付的不断更新,其支付流程和接口调用方式可能会有所改变,同时在开发过程中需要严格按照微信支付 API 的要求来进行,确保支付过程中的正确性和安全性。