一、引言
随着电子支付的快速发展,微信支付已成为线上线下交易的重要支付手段。为了提供更加安全、高效、便捷的支付体验,微信官方在2020年12月25日正式推出了微信支付v3版本。相较于旧版本v2,v3在接口设计、数据交互格式、加密算法等方面均进行了全面升级。由于官方文档主要支持Java和PHP,本文将介绍如何在Node.js和TypeScript中封装微信支付v3的API,并分享一些实践中的经验和心得。
二、微信支付v3版本概述
前言
微信官方在2020-12-25正式开放了v3版本的接口,相比较旧版本v2有了不少改变,例如:
-
遵循统一的Restful的设计风格
-
使用JSON作为数据交互的格式,不再使用XML
-
使用基于非对称密钥的SHA256-RSA的数字签名算法,不再使用MD5或HMAC-SHA256
-
不再要求HTTPS客户端证书
-
使用AES-256-GCM,对回调中的关键信息进行加密保护
由于官方文档只支持java和php,所以我在这里使用ts简单的封装了一个版本,支持在js或者ts中使用,后续会更加完善这个npm包,谢谢。
使用
yarn add wechatpay-node-v3@2.1.8
(也可以用npm,请加上版本号,使用正式版本)
import WxPay from 'wechatpay-node-v3'; // 支持使用require
import fs from 'fs';
import request from 'superagent';
const pay = new WxPay({
appid: '直连商户申请的公众号或移动应用appid',
mchid: '商户号',
publicKey: fs.readFileSync('./apiclient_cert.pem'), // 公钥
privateKey: fs.readFileSync('./apiclient_key.pem'), // 秘钥
});
# 这里以h5支付为例
try {
# 参数介绍请看h5支付文档 https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_1.shtml
const params = {
appid: '直连商户申请的公众号或移动应用appid',
mchid: '商户号',
description: '测试',
out_trade_no: '订单号',
notify_url: '回调url',
amount: {
total: 1,
},
scene_info: {
payer_client_ip: 'ip',
h5_info: {
type: 'Wap',
app_name: '网页名称 例如 百度',
app_url: '网页域名 例如 https://www.baidu.com',
},
},
};
const nonce_str = Math.random().toString(36).substr(2, 15), // 随机字符串
timestamp = parseInt(+new Date() / 1000 + '').toString(), // 时间戳 秒
url = '/v3/pay/transactions/h5';
# 获取签名
const signature = pay.getSignature('POST', nonce_str, timestamp, url, params); # 如果是get 请求 则不需要params 参数拼接在url上 例如 /v3/pay/transactions/id/12177525012014?mchid=1230000109
# 获取头部authorization 参数
const authorization = pay.getAuthorization(nonce_str, timestamp, signature);
const result = await request
.post('https://api.mch.weixin.qq.com/v3/pay/transactions/h5')
.send(params)
.set({
Accept: 'application/json',
'Content-Type': 'application/json',
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
Authorization: authorization,
});
console.log('result==========>', result.body);
} catch (error) {
console.log(error);
}
如果你使用的是nest框架,请结合nest-wechatpay-node-v3
一起使用。
使用自定义 http 请求
import { IPayRequest, Output } from 'wechatpay-node-v3/dist/define';
自己实现 IPayRequest
接口,使用如下方法注入
pay.createHttp(...);
WxPay 介绍
import WxPay from 'wechatpay-node-v3';
或者 const WxPay = require('wechatpay-node-v3')
参数介绍
参数名称 | 参数介绍 | 是否必须 |
---|---|---|
appid | 直连商户申请的公众号或移动应用appid | 是 |
mchid | 商户号 | 是 |
serial_no | 证书序列号 | 否 |
publicKey | 公钥 | 是 |
privateKey | 密钥 | 是 |
authType | 认证类型,目前为WECHATPAY2-SHA256-RSA2048 | 否 |
userAgent | 自定义User-Agent | 否 |
key | APIv3密钥 | 否 有验证回调必须 |
注意
-
serial_no是证书序列号 请在命令窗口使用
openssl x509 -in apiclient_cert.pem -noout -serial
获取 -
头部参数需要添加 User-Agent 参数
-
需要在商户平台设置APIv3密钥才会有回调,详情参看文档指引http://kf.qq.com/faq/180830E36vyQ180830AZFZvu.html
使用介绍
以下函数是我针对微信相关接口进行进一步封装,可以直接使用。
api名称 | 函数名 |
---|---|
h5支付 | transactions_h5 |
native支付 | transactions_native |
app支付 | transactions_app |
JSAPI支付 或者 小程序支付 | transactions_jsapi |
查询订单 | query |
关闭订单 | close |
申请交易账单 | tradebill |
申请资金账单 | fundflowbill |
下载账单 | downloadBill |
回调解密 | decipher_gcm |
合单h5支付 | combine_transactions_h5 |
合单native支付 | combine_transactions_native |
合单app支付 | combine_transactions_app |
合单JSAPI支付 或者 小程序支付 | combine_transactions_jsapi |
查询合单 | combine_query |
关闭合单 | combine_close |
获取序列号 | getSN |
申请退款 | refunds |
查询退款 | find_refunds |
签名验证 | verifySign |
微信提现到零钱 | batches_transfer |
分账 | create_profitsharing_orders |
微信支付v3版本在多个方面进行了重大改进,主要包括:
-
遵循统一的Restful设计风格,使得接口更加清晰、易于理解和使用。
-
使用JSON作为数据交互格式,替代了v2中的XML格式,提高了数据交互的效率和可读性。
-
采用基于非对称密钥的SHA256-RSA数字签名算法,提高了交易的安全性。
-
取消了HTTPS客户端证书的要求,简化了开发流程。
-
使用AES-256-GCM加密算法对回调中的关键信息进行加密保护,进一步提升了数据的安全性。
三、微信支付v3在Node.js和TypeScript中的封装实践
为了简化在Node.js和TypeScript中使用微信支付v3的流程,我们可以通过封装API来实现。以下是一些关键的封装步骤和要点:
-
环境准备:首先,需要在微信商户平台注册并获取相应的商户ID、API密钥等信息。同时,需要安装Node.js和TypeScript的开发环境。
-
API封装:根据微信支付的官方文档,我们可以使用axios等HTTP库来封装微信支付v3的API。在封装过程中,需要注意处理各种异常情况和错误码,确保代码的健壮性。
-
签名验证:微信支付v3使用SHA256-RSA签名算法进行验证。在请求和响应中,需要生成并验证签名。我们可以使用Node.js的crypto模块来实现SHA256-RSA签名和验签功能。
-
加密解密:对于回调中的关键信息,微信支付v3使用AES-256-GCM加密算法进行加密保护。我们需要使用相应的加密解密库来实现AES-256-GCM的加密解密功能。
-
接口测试:在封装完成后,我们需要对API进行充分的测试,确保各种场景下的正确性。可以使用Postman等工具进行接口测试。
四、实践中的经验和心得
在封装和使用微信支付v3的过程中,我们积累了一些经验和心得:
-
仔细阅读官方文档:微信支付的官方文档非常详细,包含了API的详细定义、请求参数、响应参数、错误码等信息。在开发过程中,我们需要仔细阅读官方文档,确保对API有充分的理解。
-
注意安全性:微信支付涉及到资金交易,因此安全性至关重要。在开发过程中,我们需要注意保护商户密钥、API密钥等敏感信息,避免泄露。同时,需要对请求和响应进行签名验证和加密解密处理,确保数据的安全性。
-
处理异常情况:在调用微信支付API时,可能会遇到各种异常情况,如网络错误、参数错误、签名错误等。我们需要对这些异常情况进行处理,确保程序的健壮性。
-
持续更新和维护:随着微信支付的更新和升级,API可能会发生变化。我们需要持续关注微信支付的官方公告和更新日志,对封装的API进行更新和维护。
五、总结与展望
本文介绍了微信支付v3在Node.js和TypeScript中的封装实践和应用。通过封装API,我们可以简化在Node.js和TypeScript中使用微信支付v3的流程,提高开发效率。同时,我们需要注意安全性、处理异常情况、持续更新和维护等方面的问题。未来,随着微信支付的不断发展,我们将继续完善和优化封装的API,为开发者提供更加便捷、高效、安全的支付解决方案。
项目下载地址:
https://www.npmjs.com/package/wechatpay-node-v3
关注公众号私信可加“前端技术交流”