Nodejs下微信支付与本地开发环境搭建

发布于2023-10-17 15:43 阅读1050次 
Nodejs下微信支付与本地开发环境搭建,众所周知微信的公众号小程序本地开发过程中实分不友好,不管是认证,调试需要反复的上传给开发过程带来诸多不便,微信的支付环境更是要求更加严苛,而且官方还不提供nodejs的开发范例及sdk。
此文我们主要讲如何实现本地开发微信公众号和小程序的环境搭建及nodejs的开发范例。代码在nuxt和vue中测试均可用,这里默认使用vue3的setup语法糖编写,在nuxt3.4.3环境中测试通过。
1.建立nginx反向代理,并指向本地内网映射或花生壳等网络映射工具提供的域名和端口,这里我使用了RouterOS路由器自带提供的ip cloud提供的映射。远程服务器上面建立一个nginx网站,并绑定已备案的域名,配置nginx反向代理:
```
location /
expires 12h;
if ($request_uri ~* "(php|jsp|cgi|asp|aspx)")
{
expires 0;
}
proxy_pass http://xxx.sn.mynetname.net:3000; #这是要指向到本地服务器的映射地址和端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
add_header Cache-Control no-cache;
add_header X-Cache $upstream_cache_status;
proxy_set_header Accept-Encoding "";
sub_filter_once off;
}
```
2.微信支付开发:到这里基本就可以实现微信的本地功能开发,微信的支付还不行,这里我们推荐使用wechatpay-node-v3,使用微信支付的apiV3方式加密认证,下载好相对应的证书文件。
```
#安装wechatpay-node-v3
npm i wechatpay-node-v3 --save
#这里以公众号支付为例,后端生成订单信息,返回给前端,前端拉起支付,(扫码支付略有不同)
import WxPay from 'wechatpay-node-v3';
//创建订单对象
const pay = new WxPay({
appid:'公众号appID',
mchid:‘微信支付商号号',
publicKey: fs.readFileSync('apiclient_cert.pem'), // 公钥
privateKey: fs.readFileSync('apiclient_key.pem'), // 秘钥
});
//定义支付参数
const params = {
description:'测试支付', // 订单描述
out_trade_no:'20230502'+Math.random().toString(32).substring(2,15), // 订单号,一般每次发起支付都要不一样,可使用随机数生成
notify_url: '支付回调地址,需公网能访问,微信服务会访问此地址并post支付结果数据过来',
amount: {
total: 1, // 支付金额,单位为分
},
attach:`[{"amount":1},{"remark":"支付备注"},{"product_id":"测试产品01"}]`,
payer: {
openid:res[0].openid, // 微信小程序用户的openid,一般需要前端发送过来
},
scene_info: {
payer_client_ip: 'ip', // 支付者ip,这个不用写也没有问题
},
};
//生成订单数据
const result = await pay.transactions_jsapi(params);
3.#前端拉起支付
const payment=(data)=>{
if (typeof WeixinJSBridge == "undefined") {
if (document.addEventListener) {
document.addEventListener("WeixinJSBridgeReady",onBridgeReady(data),false);
} else if (document.attachEvent) {
document.attachEvent("WeixinJSBridgeReady", onBridgeReady(data));
document.attachEvent("onWeixinJSBridgeReady", onBridgeReady(data));
}
} else {
onBridgeReady(data);
}
};
const onBridgeReady=(data)=>{
//注意挂在window
window.WeixinJSBridge.invoke("getBrandWCPayRequest",data,res=> {
if (res.err_msg === "get_brand_wcpay_request:ok") {
useNuxtApp().$toast('支付成功');
//this.payResult(true);
} else if (res.err_msg === "get_brand_wcpay_request:fail") {
useNuxtApp().$toast('支付失败');
//this.payResult(false);
}
});
};
```
4.支付回调路径,接收微信服务器post回来的数据并解密处理支付订单
```
import WxPay from 'wechatpay-node-v3';
var params = await readBody(e);//支付回调路径中params参数是从nuxt3中 readBody中读取;各开发环境读取不一样。
//创建订单对象
const pay = new WxPay({
appid:'公众号appID',
mchid:‘微信支付商号号',
publicKey: fs.readFileSync('apiclient_cert.pem'), // 公钥
privateKey: fs.readFileSync('apiclient_key.pem'), // 秘钥
});
const result=pay.decipher_gcm(params.resource.ciphertext,params.resource.associated_data,params.resource.nonce,app.config.partner_key);
//处理相关订单状态
return 'SUCCESS'//返回SUCCESS 给微信以确认支付结果并不再回调
```