使用nodejs搭建微信小程序支付接口的详细过程

目录
  • 前言
  • 支付流程
  • 在微信小程序发起支付
  • 支付模块
    • 使用npm安装
    • 引入依赖包
    • 创建支付实例
    • 获取支付参数
  • 处理业务逻辑
    • 解密回调结果
  • 完整代码
  • 最后
  • 参考

前言

前段时间在开发一个微信小程序的时候需要用到支付功能,我就去看了下微信支付的官方文档,好家伙,微信官方只提供了java、php还有Go语言的sdk。PHP我会点吧,但又不是很会,做为一个菜鸡前端,java也不会更别说go了。恰好我最近刚学了下nodejs,我就想找找有没有人做nodejs版的sdk开源,在微信开发者社区逛了逛没想到还真有,又可借此机会再复习一下nodejs也挺好的。在这里我将大致记录一下我的一些使用方法。

支付流程

一、向后端服务器获取支付所需参数

二、用获得的参数调用小程序内置的的支付api

三、在回调的后端接口中处理业务逻辑

在微信小程序发起支付

查看微信小程序的官方文档,我们可以查到微信小程序发起支付的api

wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success (res) { },
  fail (res) { }
})

可以看到这里需要我们携带五个参数( timeStamp, nonceStr,package,signType,,paySign)才能正常发起支付。

那我们要在哪里才能获取到这些参数呢,这就需要我们的nodejs上场了。

支付模块

使用npm安装

npm i wechatpay-node-v3

这个包集成了H5、App端的支付能力,更多详细的介绍可以去看一下这个包的官方文档,这里就只介绍在微信小程序的应用。

引入依赖包

const WxPay = require('wechatpay-node-v3');
const fs = require('fs');
const request = require('superagent');
const express = require('express');

其中fs是一个文件处理的内置模块模块,superagent是一个发起请求的模块,若没有的话使用npm提前安装一下,这里就不多做介绍了。因为我们需要搭建一个可供前端请求的接口,我们就需要用到express服务器搭建框架,同样也是需要使用npm提前安装一下的。

创建支付实例

const pay = new WxPay({
  appid: '你的微信小程序appid',
  mchid: '商户号',
  publicKey: fs.readFileSync('./apiclient_cert.pem'), // 公钥
  privateKey: fs.readFileSync('./apiclient_key.pem'), // 秘钥
});

其中商户号需要凭营业执照才能申请,个人是无法接入微信支付的。

申请到商户号之后还需要在微信小程序的管理平台关联一下商户号。

然后还需要去申请公钥和私钥证书。具体的申请流程可看下方微信官方的文档:微信支付接入前准备

之后把申请的公钥私钥证书文件放到同级目录下。

获取支付参数

async function payInfo(req,res){
	const params = {
        description: 'Asnull的支付测试', // 订单描述
        out_trade_no: '2022080711111111', // 订单号,一般每次发起支付都要不一样,可使用随机数生成
        notify_url: 'https://pay.lipux.cn/notify_url',
        amount: {
          total: 1, // 支付金额,单位为分
        },
        payer: {
          openid: 'drEc8QfY', // 微信小程序用户的openid,一般需要前端发送过来
        },
        scene_info: {
          payer_client_ip: 'ip', // 支付者ip,这个不用理会也没有问题
        },
    };
      const result = await pay.transactions_jsapi(params);
      console.log(result);
}

其中的回调url是当用户成功支付之后微信服务器就会向这个回调url发支付结果的信息,一般我们是在这个回调url里面进行一些支付成功之后的业务处理,而且这个回调url是需要ssl证书认证的也就是https,且在链接后面不能携带参数。url示例:https://pay.lipux.cn/notify_url

注意:这个回调url必须能公网访问的哦,不能是本地环境的链接

由于pay.transactions_jsapi返回的是一个promise对象,因此我们使用async和await函数进行接收结果,其中result就是微信小程序api发起支付所需要的参数。

result的打印结果:

{
    appId: 'drEc8QfY',
    timeStamp: '1609918952',
    nonceStr: 'y8aw9vrmx8c',
    package: 'prepay_id=wx0615423208772665709493edbb4b330000',
    signType: 'RSA',
    paySign: 'JnFXsT4VNzlcamtmgOHhziw7JqdnUS9qJ5W6vmAluk3Q2nska7rxYB4hvcl0BTFAB1PBEnHEhCsUbs5zKPEig==
}

我们将这个结果使用express中的路由监听res.send()函数发送给前端就可以了。

然后我们就在前端解析这些数据,放到wx.requestPayment这个微信小程序的api中正式发起支付。

如果不出意外的话,在微信小程序发起支付这个功能我们就正式实现了

处理业务逻辑

上面提到了,回调url就是一个处理支付成功之后的业务逻辑的接口。

当支付成功之后,微信服务器会向我们这个接口发送一个post请求,这个post请求携带了一些有关支付结果的参数

支付结果通知是以POST 方法访问商户设置的通知url,通知的数据以JSON 格式通过请求主体(BODY)传输。通知的数据包括了加密的支付结果详情。

通过官方微信支付文档的上面这个话可知,微信服务器向我们发送的是一段加密的数据,但别担心,这个模块的作者都帮我们解决了。

我们先来看一下微信服务器都给我们发送了什么数据:

{
 "id": "091541fc-6sca-55v8-ab24-653a9v313500",
 "create_time": "2022-08-07T16:39:06+08:00",
 "resource_type": "encrypt-resource",
 "event_type": "TRANSACTION.SUCCESS",
 "summary": "支付成功",
 "resource": {
  "original_type": "transaction",
  "algorithm": "AEAD_AES_256_GCM",
  "ciphertext": "tMqPpq3VCxwt56hU2gfsPDJfcfESQ/kzPNmi2xYF0KqMV9ChIWu+n5iVXSVqwgsU9gYSSXeThhp3jm8i9pcrTiOagMxEM/IbJ+MfnN7fkr8Jy2tWOg49N4wy3vB2Qd/nJvD+Jz8K6c4rF8MOasgN+XEriut23sd6EqGUY5zTaKQ+yZC7Q5R+Q6UXa4HlsvHH7+wL6Uz71ZqNyawJ7BYGGh2aXwTu3DHMOullL/IoG3E1nRq1xQRmJsn0li4okegLRuTmlp3vvxZcNgHLOZSCmtdYcRYsZezB2wYdqsT5cCUmRgO8CdgctkGGQIOTjlgaKT8gogP7XUvw1bcFMAC4HqUJv2v28mfMTjFzhLNXXWCFDKJDWhCQg2ZTXw0pRJSYe/IiNBpuVsKX7DGahOyYly/Hn321fryiH7mpI5orC6Wb03Mc77hcnL9ALDV0jT8mrmYuB8pAMkxsFNcGcgnp5FrtKcA59CEYc4ccNU26wIiIszB0YIwvirvCEGys3eGStQaytFLvGw5qCmnZ6N5X3GPBOPEQXJa19CrVndWMjBm1PaeyJ/fgfN9mGrsChrToxDg==",
  "associated_data": "transaction",
  "nonce": "iOO0tvICpQFb"
 }
}

我们可以看到其中有段信息是被加密了,我们需要解密其中的信息才能进一步的进行我们业务处理。

解密回调结果

我们需要通过在回调的路由监听的req.body拿到发送的数据,即上面那一段的json数据,把对应的ciphertext, associated_data, nonce参数传入下面的函数:

# key 用商户平台上设置的APIv3密钥【微信商户平台—>账户设置—>API安全—>设置APIv3密钥】,记为key;
const result = pay.decipher_gcm(ciphertext, associated_data, nonce, key);

其中的key是APIv3密钥,需要我们去另外申请,具体申请流程请看下面的官方文档:什么是APIv3密钥?如何设置? (qq.com)

解密成功之后我们就拿到一个新的结果result,打印出来如下:

{
 "mchid": "3526524578",
 "appid": "wxc2n10fbb6065d4f0",
 "out_trade_no": "2022080711111111",
 "transaction_id": "8520001545602207282059123413",
 "trade_type": "JSAPI",
 "trade_state": "SUCCESS",
 "trade_state_desc": "支付成功",
 "bank_type": "OTHERS",
 "attach": "",
 "success_time": "2022-08-07T16:55:20+08:00",
 "payer": {
  "openid": "drEc8QfY"
 },
 "amount": {
  "total": 1,
  "payer_total": 1,
  "currency": "CNY",
  "payer_currency": "CNY"
 }
}

其中的out_trade_no就是我们一开始设置的订单号,我们可以在一开始的时候就把这个订单号与我们的用户进行关联,然后在这里就可以通过订单号进行业务处理,比如说充值会员,充值金币等等的操作。

关于回调通知的具体参数说明可看文档:微信支付-开发者文档 (qq.com)

到这里,我们已经完成了整个微信小程序支付的流程,不出意外的话你应该可以正常拿到支付的结果

剩下的就是你的业务逻辑了!

完整代码

/*
 * Created by Asnull.
 * Website:https://lipux.cn/
 */

const WxPay = require('wechatpay-node-v3');
const fs = require('fs');
const request = require('superagent');
const express = require('express');

// 创建服务器实例
const app = express();
// 配置解析表单数据的中间件
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
// 监听端口
app.listen(3031, () => {
    console.log('服务器启动成功!')
})

// 创建支付实例
const pay = new WxPay({
    appid: '你的微信小程序appid',
    mchid: '商户号',
    publicKey: fs.readFileSync('./apiclient_cert.pem'), // 公钥
    privateKey: fs.readFileSync('./apiclient_key.pem'), // 秘钥
});

// 定义一个获取支付参数路由(get请求)
app.get('/pay', payInfo);

// 拿到支付所需参数
async function payInfo(req, res) {
    // 接收前端传过来的openid
    let openid = req.params.openid;
    const params = {
        description: 'Asnull的支付测试', // 订单描述
        out_trade_no: randomNumber(), // 订单号,一般每次发起支付都要不一样,可使用随机数生成
        notify_url: 'https://pay.lipux.cn/notify_url',
        amount: {
            total: 1, // 支付金额,单位为分
        },
        payer: {
            openid: openid, // 微信小程序用户的openid,一般需要前端发送过来
        },
        scene_info: {
            payer_client_ip: 'ip', // 支付者ip,这个不用理会也没有问题
        },
    };
    const result = await pay.transactions_jsapi(params);
    console.log(result);
    // 将结果响应给微信小程序前端
    res.send(result);
}

// 回调路由
app.post('/notify_url', async(req, res) => {
    // 申请的APIv3
    let key = '45c18fdfdgd45f5bc5321201dfdf453f';
    let { ciphertext, associated_data, nonce } = req.body.resource;
    // 解密回调信息
    const result = pay.decipher_gcm(ciphertext, associated_data, nonce, key);
    // 拿到订单号
    let { out_trade_no } = result;
    if (result.trade_state == 'SUCCESS') {
        // 支付成功之后需要进行的业务逻辑
    }
})

// 订单号生成函数
function randomNumber() {
    const now = new Date()
    let month = now.getMonth() + 1
    let day = now.getDate()
    let hour = now.getHours()
    let minutes = now.getMinutes()
    let seconds = now.getSeconds()
    month = month < 10 ? "0" + month : month;
    day = day < 10 ? "0" + day : day;
    hour = hour < 10 ? "0" + hour : hour;
    minutes = minutes < 10 ? "0" + minutes : minutes;
    seconds = seconds < 10 ? "0" + seconds : seconds;
    let orderCode = now.getFullYear().toString() + month.toString() + day + hour + minutes + seconds + (Math.round(Math.random() * 1000000)).toString();
    return orderCode;
}

最后

nodejs项目成功部署到服务器之后,我们只需要在微信小程序先对https://域名/pay 发起get请求

拿到数据后再调用wx.requestPayment即可发起支付。

最后,祝您玩的愉快!

参考

wechatpay-node-v3 - npm (npmjs.com)

到此这篇关于使用nodejs搭建微信小程序支付接口的文章就介绍到这了,更多相关nodejs搭建微信小程序支付接口内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序JSON配置文件详细讲解作用

    目录 前言 一.项目根目录中的app.json配置文件 二.项目根目录中的project.config.json配置文件 三.项目根目录中的sitemap.json配置文件 四.每个页面文件夹中的.json配置文件 前言 小程序项目中有4种json配置文件,分别是: 1.项目根目录中的app.json配置文件 2.项目根目录中的project.config.json 配置文件 3.项目根目录中的sitemap.json配置文件 4.每个页面文件夹中的.json配置文件 一.项目根目录中的app.

  • 微信公众号weixin-js-sdk使用方法总结

    目录 1.安装weixin-js-sdk 2.封装wechat.js 3.main.js 4.页面调用方式 5.如果你需要用到其他功能,在这里按照这种方式接着定义新的方法: 总结 JS-SDK说明文档 网页授权说明文档 微信公众号授权登录参考方案 http接口请求封装参考方案 记录微信公众号开发过程中遇到的问题以及解决方案: 1.安装weixin-js-sdk npm install weixin-js-sdk 2.封装wechat.js import wx from 'weixin-js-sd

  • JS实现微信播音效果示例详解

    目录 需要实现的效果 图片切换轮播法 CSS实现 需要实现的效果 图片切换轮播法 这个功能其实是我刚毕业的时候实现的,那也是5年前的事情了,受限于当时的水平,仅仅是实现了,其他啥都不是.相当简单. 当初微信的声音条还是竖状的,所以依旧按照但是的样子来实现. 看下面的这个图片就知道了,甚至于代码都不用贴

  • 微信小程序怎么加入JavaScript脚本,做出动态效果

    目录 一.数据绑定 二.全局数据 三.事件 四.动态提示 Toast 五.对话框 Modal 这篇文章主要介绍了教大家为小程序加入 JavaScript 脚本,做出动态效果,以及如何跟用户互动.学会了脚本,就能做出复杂的页面了. 一.数据绑定 前面的所有示例,小程序的页面都是写死的,也就是页面内容不会变.但是,页面数据其实可以通过脚本传入,通过脚本改变页面,实现动态效果. 小程序提供了一种特别的方法,让页面可以更方便地使用脚本数据,叫做"数据绑定"(data binding). 所谓&

  • 微信小程序 支付简单实例及注意事项

    微信小程序 支付 微信小程序的支付和微信公众号的支付是类似的,对比起来还比公众号支付简单了一些,我们只需要调用微信的统一下单接口获取prepay_id之后我们在调用微信的支付即可. 今天我们来封装一般node的支付接口!!! 首先调用统一下单接口我们需要知道一些信息 var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp() var deferred = Q.defer() var appid = conf

  • 微信小程序 支付功能开发错误总结

    微信小程序 支付功能开发错误总结 微信小程序支付终于踩完坑了,发现里面坑挺大的,现在发个贴,希望以后入坑的同学可以看一下 : https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=2 业务流程在这里大家看文档的时候可以看到.第一个坑,获取用户的openid,参数一定要拼在url连接上,否则会报{"errcode":40013,"errmsg":"invali

  • 微信小程序 支付后台java实现实例

    微信小程序 支付后台java实现实例 前言: 前些天使用 LeanCloud 云引擎写了个小程序的支付相关 以前只做过 APP 支付 这次在小程序支付爬了两天的坑 把代码也分享出来 支付流程: 1.小程序前端获取微信 openId 以及订单号 传给后台 2,后台根据 openId 和订单号进行签名 post 微信统一下单接口 3.后台获取微信返回的xml字符串 解析 二次签名以后返回给前端 4.前端调起支付微信支付 API 先看支付函数: //获取支付信息 @EngineFunction("ge

  • 微信小程序 支付功能实现PHP实例详解

    微信小程序 支付功能实现PHP实例详解 前端代码: wx.request({ url: 'https://www.yourhost.com/weixin/WeiActivity/payJoinfee',//改成你自己的链接 header: { 'Content-Type': 'application/x-www-form-urlencoded' }, method:'POST', success: function(res) { console.log(res.data); console.lo

  • 微信小程序支付及退款流程详解

    首先说明一下,微信小程序支付的主要逻辑集中在后端,前端只需携带支付所需的数据请求后端接口然后根据返回结果做相应成功失败处理即可.我在后端使用的是php,当然在这篇博客里我不打算贴一堆代码来说明支付的具体实现,而主要会侧重于整个支付的流程和一些细节方面的东西.所以使用其他后端语言的朋友有需要也是可以看一下的.很多时候开发的需求和相应问题的解决真的要跳出语言语法层面,去从系统和流程的角度考虑.好的,也不说什么废话了.进入正题. 一. 支付 支付主要分为几个步骤: 前端携带支付需要的数据(商品id,购

  • 基于mpvue搭建微信小程序项目框架的教程详解

    简介: mpvue框架对于从没有接触过小程序又要尝试小程序开发的人员来说,无疑是目前最好的选择.mpvue从底层支持 Vue.js 语法和构建工具体系,同时再结合相关UI组件库,便可以高效的实现小程序开发 前言: 本文讲述如何搭建完整的小程序项目框架,因为是第一次使用,有不完善的地方请大佬指正. 搭建内容包括: 1.使用scss语法:依赖插件sass-loader .node-sass 2.像vue一样使用路由:依赖插件 mpvue-entry 和 mpvue-router-patch 3.使用

  • Python实现微信小程序支付功能

    正文 由于最近自己在做小程序的支付,就在这里简单介绍一下讲一下用python做小程序支付这个流程.当然在进行开发之前还是建议读一下具体的流程,清楚支付的过程. 1.支付交互流程 当然具体的参数配置可以参考官方文档https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_3&index=1 2.获取openid(微信用户标识) import requests from config import APPID, SECRET c

  • .NET Core 实现微信小程序支付功能(统一下单)

    最近公司研发了几个电商小程序,还有一个核心的电商直播,只要是电商一般都会涉及到交易信息,离不开支付系统,这里我们统一实现小程序的支付流程(与服务号实现步骤一样). 开通小程序的支付能力 开通小程序支付功能比较简单,基本上按微信文档一步一步的申请就好,如图 以上三个步骤就申请完成 1.提交资料给微信 2.微信审核并签署协议 3.商户后台绑定同主体的APPID 商户后台绑定同一主体的APPID并授权 1.登录商户后台https://pay.weixin.qq.com,进入产品中心-APPID授权管理

  • 微信小程序支付功能 php后台对接完整代码分享

    微信小程序支付,php后台对接完整代码,全是干货呀,拿过来可以直接使用.小程序在调起微信支付之前需要5个参数,这时候就需要携带code向后台请求,然后后台根据code获取openid 再进行服务器之间的. 一.准备工作 1.小程序注册,要以公司的以身份去注册一个小程序,才有微信支付权限: 2.绑定商户号. 3.在小程序填写合法域  二.完成以上条件,你可以得到      小程序appid 小程序秘钥    这两个用于获取用户openid: 商户号id ,商户号秘钥     支付接口必须的: 三.

  • 微信小程序支付PHP代码

    本文实例为大家分享了微信小程序支付PHP具体代码,供大家参考,具体内容如下 服务器端获取 openid Getopenid.php <?php header('Content-type: application/json; charset=UTF-8'); $APPID="";//填写小程序appid $SECRET="";//填写小程序secret $JSCODE=""; if(isset($_GET['js_code'])){ $JSC

随机推荐