详解用Nodejs搭建微信小程序支付接口的操作流程及参数要点

2025-07-17
来源:万象资讯

本文重点阐述“如何构建微信小程序支付功能”的相关技巧,编者借助具体实例向读者呈现了实施步骤,其操作步骤简便高效,实用性显著,期望本篇关于“如何构建微信小程序支付功能”的文章能为大家解决实际问题。

支付流程

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

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

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

在微信小程序发起支付

查阅微信小程序的官方资料,我们能够了解到微信小程序中用于发起支付的相关接口。

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

为了顺利完成支付流程,我们必须携带包括但不限于以下五个必要参数:(参数一,参数二,参数三,参数四,参数五)。

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

支付模块

使用npm安装

npm i wechatpay-node-v3

本包整合了H5与App端支付功能,欲了解更详尽的说明,请查阅该包的官方文档;在此仅对微信小程序中的应用进行介绍。

引入依赖包

引入模块WxPay,该模块基于微信支付Node.js V3版本。 引入文件系统模块,执行如下操作:fs。 引入了superagent模块,并通过require函数进行了调用,从而创建了一个名为request的变量。 引入了Express框架,通过require函数实现了对它的调用。

fs是文件处理的内置组件,它负责发起请求。若此组件未安装,需通过npm预先进行安装,此处不予详述。鉴于我们需要构建一个便于前端调用的接口,这就要求我们利用服务器构建框架,同样地,这也需要提前通过npm进行安装。

创建支付实例

const pay = new WxPay({ appid:指定为“您的微信小程序唯一标识码”。   mchid: '商户号', 读取文件“apiclient_cert.pem”内容,获取公钥,存储于变量publicKey中。 privateKey:通过读取文件系统中的'./apiclient_key.pem'文件内容获取,//该内容代表私钥 });

商户在申请时必须出示营业执照,而个人用户则无法接入微信支付系统。

获取商户号后,还需在微信小程序的管理界面进行商户号的绑定操作。

接下来,必须进行公钥与私钥证书的申请。具体申请步骤,请参考下方的微信官方文档:微信支付接入前的准备工作。

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

获取支付参数

定义一个异步函数名为“payInfo”,其参数包括请求对象“req”和响应对象“res”。 const params = { 订单描述为:“Asnull的支付测试”。 订单编号为:2022080711111111,此编号在每次支付请求时均需保持唯一性,通常建议采用随机数来生成。 通知链接:'https://pay.lipux.cn/notify_url',         amount: { 总计:1元整,表示支付金额,计价单位为分。         },         payer: { openid标识为'drEc8QfY',代表微信小程序用户的唯一标识,通常情况下,该信息应由前端传递至后端。         },         scene_info: {

个人开发微信小程序支付接口_nodejs 微信小程序支付接口搭建 _ 微信小程序支付接口 nodejs 实现步骤

支付者的IP地址为“ip”,对此无需关注,不影响使用。         },     };       console.log(result);    }

用户支付成功后,微信服务器会将支付结果信息发送至指定的回调地址,我们通常会在该地址上进行支付成功后的相关业务处理。需要注意的是,该回调地址必须通过SSL证书进行验证,且在URL链接末尾不得附加任何参数。例如:

请确保这个回调地址能够被公开网络访问,切勿使用仅限于本地环境的链接。

鉴于pay函数的输出是一个对象,所以我们采用函数来获取其结果,该结果正是微信小程序API进行支付所需的关键参数。

的打印结果:

: '',

: '',

: '',

: '=',

: 'RSA',

: '==

我们将通过使用路由监听功能,调用res.send()函数,将此结果传递至前端。

接下来,我们便在前端对这些信息进行解析,并将它们输入到wx.这个微信小程序的API中,从而正式启动支付流程。

若一切顺利,我们便已成功在微信小程序中推出了支付功能。

处理业务逻辑

如前所述,所谓的回调url,实际上是指用于处理支付成功后相关业务逻辑的接口。

支付操作一旦完成,微信的服务器便会向我们的接口发送一条post请求,该请求中包含了与支付结果相关的多个参数信息。

支付结果通知通过POST方式对商户设定的通知链接进行访问,该通知中的数据以JSON格式嵌入在请求主体(即BODY部分)中传递。这些数据涵盖了经过加密的支付详细信息。

从官方微信支付的相关文档中可以了解到,微信服务器向我们的系统传输的是经过加密的数据流,然而无需忧虑,该模块的开发者已经为我们妥善处理了这一问题。

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

{ 该标识符为“091541fc-6sca-55v8-ab24-653a9v313500”,属于唯一识别代码。 创建时间:2022年8月7日16点39分06秒,北京时间。 资源类型:加密资源 "事件类型":"交易成功"  "summary": "支付成功",  "resource": { 原始类型为交易。 算法类型为AEAD_AES_256_GCM。 该密文内容为:"tMqPpq3VCxwt56hU2gfsPDJfcfESQ/kzPNmi2xYF0KqMV9ChIWu+n5iVXSVqwgsU9gYSSXeThhp3jm8i9pcrTiOagMxEM/IbJ+MfnN7fkr8Jy2tWOg49N4wy3vB2Qd/nJvD+Jz8K6c4rF8MOasgN+XEriut23sd6EqGUY5zTaKQ+yZC7Q5R+Q6UXa4HlsvHH7+wL6Uz71ZqNyawJ7BYGGh3aXwTu3DHMOullL/IoG3E1nRq1xQRmJsn0li4okegLRuTmlp3vvxZcNgHLOZSCmtdYcRYsZezB2wYdqsT5cCUmRgO8CdgctkGGQIOTjlgaKT8gogP7XUvw1bcFMAC4HqUJv2v28mfMTjFzhLNXXWCFDKJDWhCQg2ZTXw0pRJSYe/IiNBpuVsKX7DGahOyYly/Hn321fryiH7mpI5orC6Wb03Mc77hcnL9ALDV0jT8mrmYuB8pAMkxsFNcGcgnp5FrtKcA59CEYc4ccNU26wIiIszB0YIwvirvCEGys3eGStQaytFLvGw5qCmnZ6N5X3GPBOPEQXJa19CrVndWMjBm1PaeyJ/fgfN9mGrsChrToxDg=="。 "相关数据类型":"交易信息"   "nonce": "iOO0tvICpQFb"  } }

观察之下,我们发现信息中存在部分内容已加密,我们必须对这些加密信息进行解密,以便能够继续执行我们的业务操作。

解密回调结果

为了获取发送的数据,我们需在回调的路径监听中提取req.body中的内容,这即是之前提及的json格式数据,然后,将相应的参数传递至后续的函数处理。

商户平台中配置的APIv3密钥,需在微信商户平台账户设置项下的API安全部分进行设置,该密钥命名为key。

该密钥至关重要,我们必须另行申请获取,有关详细的申请步骤,请参阅下方的官方文件:密钥究竟是什么?如何进行配置?( )

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

{  "mchid": "3526524578", appid标识为wxc2n10fbb6065d4f0。 交易编号为"2022080711111111",不得进行修改。 交易标识码为:8520001545602207282059123413。  "trade_type": "JSAPI",  "trade_state": "SUCCESS",

nodejs 微信小程序支付接口搭建 _ 微信小程序支付接口 nodejs 实现步骤_个人开发微信小程序支付接口

 "trade_state_desc": "支付成功",  "bank_type": "OTHERS",  "attach": "", 成功时间点为:2022年8月7日16时55分20秒,北京时间。  "payer": {   "openid": "drEc8QfY"  },  "amount": {   "total": 1,   "payer_total": 1,   "currency": "CNY",   "payer_currency": "CNY"  } }

这就是我们最初设定的订单编号,我们可以在最初阶段就将此编号与客户信息相连接,之后便能够利用订单编号执行各种业务操作,例如进行会员充值、金币充值等。

关于回调通知的详细参数信息,请查阅相关文档:请访问微信支付的开发者指南。

截至目前,我们已顺利走完了微信小程序支付的全部步骤,若一切顺利,你应该能够顺利获取到支付的相关信息。

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

完整代码

/*   * Created by Asnull.  * Website:https://lipux.cn/  */ const WxPay = require('wechatpay-node-v3'); const fs = require('fs'); const request = require('superagent'); 引入了Express框架,通过使用require函数调用了模块。 // 创建服务器实例 const app = express(); // 配置解析表单数据的中间件 应用中引入express.urlencoded中间件,并设置其扩展属性为false。 app.use(express.json()) // 监听端口 app.listen(3031, () => { 控制台输出:“服务器启动顺利完成。” }) // 创建支付实例 const pay = new WxPay({ appid:代表您微信小程序的唯一标识符,不可更改。     mchid: '商户号', publicKey:读取文件“./apiclient_cert.pem”后得到的公钥,,使用fs.readFileSync函数实现读取操作,,文件路径为当前目录下的apiclient_cert.pem文件。 privateKey:读取文件“./apiclient_key.pem”所获取的内容,//秘钥 }); // 定义一个获取支付参数路由(get请求) app对路径“/pay”进行了配置,指定了处理该路径请求的函数为payInfo。 // 拿到支付所需参数 定义一个异步函数,名为payInfo,其参数包括请求对象req和响应对象res。     // 接收前端传过来的openid

 微信小程序支付接口 nodejs 实现步骤_个人开发微信小程序支付接口_nodejs 微信小程序支付接口搭建

获取openid值,将其赋值给变量,openid来源于请求参数中的openid部分。     const params = {         description: 'Asnull的支付测试', // 订单描述 订单号采用randomNumber()函数生成,通常情况下,每次进行支付操作时,订单号均应保持唯一性,随机数生成器是常用的方法之一。 通知地址为:https://pay.lipux.cn/notify_url,该链接用于接收支付通知。         amount: { 总计:1元整,即支付金额,其计量单位为分。         },         payer: { openid标识:openid,系微信小程序用户的唯一标识,通常由前端传递至后端。         },         scene_info: { 支付者IP地址为“ip”,对此无需关注,即便忽略也不会产生问题。         },     };     console.log(result);     // 将结果响应给微信小程序前端     res.send(result); } // 回调路由 app在接收到针对'/notify_url'路径的POST请求时,将执行一个异步函数,该函数接收两个参数:req(请求对象)和res(响应对象)。     // 申请的APIv3 定义一个变量key,其值为字符串'45c18fdfdgd45f5bc5321201dfdf453f'。 从请求体中提取密文、关联数据和随机数,分别赋值给变量ciphertext、associated_data和nonce。     // 解密回调信息 result等于pay对象调用decipher_gcm方法,该方法需要四个参数:密文、关联数据、nonce和key。     // 拿到订单号 将result中的订单号赋值给变量out_trade_no。 若结果交易状态显示为“成功”,则执行以下操作:{         // 支付成功之后需要进行的业务逻辑     } }) // 订单号生成函数 function randomNumber() {     const now = new Date() now对象的getMonth方法返回的月份值加1,即为当前月份。     let day = now.getDate()     let hour = now.getHours() 获取当前时间的分钟数,通过调用now对象的getMinutes()方法。 获取当前时间的秒数,使用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; }

在转发时,请务必标明:关于如何操作构建微信小程序支付功能的教程 | 来自李雷的PHP博客

分享