欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用nodejs搭建微信小程序支付接口的詳細過程

 更新時間:2022年12月27日 11:03:48   作者:Asnull  
前段時間做微信支付,遇到了很多坑,網(wǎng)上也沒有講解的特別明白的,通過借鑒各路人才的經(jīng)驗,最后也完成了,下面這篇文章主要給大家介紹了關(guān)于使用nodejs搭建微信小程序支付接口的詳細過程,需要的朋友可以參考下

前言

前段時間在開發(fā)一個微信小程序的時候需要用到支付功能,我就去看了下微信支付的官方文檔,好家伙,微信官方只提供了java、php還有Go語言的sdk。PHP我會點吧,但又不是很會,做為一個菜雞前端,java也不會更別說go了。恰好我最近剛學(xué)了下nodejs,我就想找找有沒有人做nodejs版的sdk開源,在微信開發(fā)者社區(qū)逛了逛沒想到還真有,又可借此機會再復(fù)習(xí)一下nodejs也挺好的。在這里我將大致記錄一下我的一些使用方法。

支付流程

一、向后端服務(wù)器獲取支付所需參數(shù)

二、用獲得的參數(shù)調(diào)用小程序內(nèi)置的的支付api

三、在回調(diào)的后端接口中處理業(yè)務(wù)邏輯

在微信小程序發(fā)起支付

查看微信小程序的官方文檔,我們可以查到微信小程序發(fā)起支付的api

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

可以看到這里需要我們攜帶五個參數(shù)( timeStamp, nonceStr,package,signType,,paySign)才能正常發(fā)起支付。

那我們要在哪里才能獲取到這些參數(shù)呢,這就需要我們的nodejs上場了。

支付模塊

使用npm安裝

npm i wechatpay-node-v3

這個包集成了H5、App端的支付能力,更多詳細的介紹可以去看一下這個包的官方文檔,這里就只介紹在微信小程序的應(yīng)用。

引入依賴包

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

其中fs是一個文件處理的內(nèi)置模塊模塊,superagent是一個發(fā)起請求的模塊,若沒有的話使用npm提前安裝一下,這里就不多做介紹了。因為我們需要搭建一個可供前端請求的接口,我們就需要用到express服務(wù)器搭建框架,同樣也是需要使用npm提前安裝一下的。

創(chuàng)建支付實例

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

其中商戶號需要憑營業(yè)執(zhí)照才能申請,個人是無法接入微信支付的。

申請到商戶號之后還需要在微信小程序的管理平臺關(guān)聯(lián)一下商戶號。

2022871606.png

然后還需要去申請公鑰和私鑰證書。具體的申請流程可看下方微信官方的文檔:微信支付接入前準(zhǔn)備

之后把申請的公鑰私鑰證書文件放到同級目錄下。

密鑰文件

獲取支付參數(shù)

async function payInfo(req,res){
	const params = {
        description: 'Asnull的支付測試', // 訂單描述
        out_trade_no: '2022080711111111', // 訂單號,一般每次發(fā)起支付都要不一樣,可使用隨機數(shù)生成
        notify_url: 'https://pay.lipux.cn/notify_url', 
        amount: {
          total: 1, // 支付金額,單位為分
        },
        payer: {
          openid: 'drEc8QfY', // 微信小程序用戶的openid,一般需要前端發(fā)送過來
        },
        scene_info: {
          payer_client_ip: 'ip', // 支付者ip,這個不用理會也沒有問題
        },
    };
      const result = await pay.transactions_jsapi(params);
      console.log(result);   
}

其中的回調(diào)url是當(dāng)用戶成功支付之后微信服務(wù)器就會向這個回調(diào)url發(fā)支付結(jié)果的信息,一般我們是在這個回調(diào)url里面進行一些支付成功之后的業(yè)務(wù)處理,而且這個回調(diào)url是需要ssl證書認(rèn)證的也就是https,且在鏈接后面不能攜帶參數(shù)。url示例:https://pay.lipux.cn/notify_url

注意:這個回調(diào)url必須能公網(wǎng)訪問的哦,不能是本地環(huán)境的鏈接

由于pay.transactions_jsapi返回的是一個promise對象,因此我們使用async和await函數(shù)進行接收結(jié)果,其中result就是微信小程序api發(fā)起支付所需要的參數(shù)。

result的打印結(jié)果:

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

我們將這個結(jié)果使用express中的路由監(jiān)聽res.send()函數(shù)發(fā)送給前端就可以了。

然后我們就在前端解析這些數(shù)據(jù),放到wx.requestPayment這個微信小程序的api中正式發(fā)起支付。

如果不出意外的話,在微信小程序發(fā)起支付這個功能我們就正式實現(xiàn)了。

處理業(yè)務(wù)邏輯

上面提到了,回調(diào)url就是一個處理支付成功之后的業(yè)務(wù)邏輯的接口。

當(dāng)支付成功之后,微信服務(wù)器會向我們這個接口發(fā)送一個post請求,這個post請求攜帶了一些有關(guān)支付結(jié)果的參數(shù)

支付結(jié)果通知是以POST 方法訪問商戶設(shè)置的通知url,通知的數(shù)據(jù)以JSON 格式通過請求主體(BODY)傳輸。通知的數(shù)據(jù)包括了加密的支付結(jié)果詳情。

通過官方微信支付文檔的上面這個話可知,微信服務(wù)器向我們發(fā)送的是一段加密的數(shù)據(jù),但別擔(dān)心,這個模塊的作者都幫我們解決了。

我們先來看一下微信服務(wù)器都給我們發(fā)送了什么數(shù)據(jù):

{
 "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"
 }
}

我們可以看到其中有段信息是被加密了,我們需要解密其中的信息才能進一步的進行我們業(yè)務(wù)處理。

解密回調(diào)結(jié)果

我們需要通過在回調(diào)的路由監(jiān)聽的req.body拿到發(fā)送的數(shù)據(jù),即上面那一段的json數(shù)據(jù),把對應(yīng)的ciphertext, associated_data, nonce參數(shù)傳入下面的函數(shù):

# key 用商戶平臺上設(shè)置的APIv3密鑰【微信商戶平臺—>賬戶設(shè)置—>API安全—>設(shè)置APIv3密鑰】,記為key;
const result = pay.decipher_gcm(ciphertext, associated_data, nonce, key);

其中的key是APIv3密鑰,需要我們?nèi)チ硗馍暾?,具體申請流程請看下面的官方文檔:什么是APIv3密鑰?如何設(shè)置? (qq.com)

解密成功之后我們就拿到一個新的結(jié)果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就是我們一開始設(shè)置的訂單號,我們可以在一開始的時候就把這個訂單號與我們的用戶進行關(guān)聯(lián),然后在這里就可以通過訂單號進行業(yè)務(wù)處理,比如說充值會員,充值金幣等等的操作。

關(guān)于回調(diào)通知的具體參數(shù)說明可看文檔:微信支付-開發(fā)者文檔 (qq.com)

到這里,我們已經(jīng)完成了整個微信小程序支付的流程,不出意外的話你應(yīng)該可以正常拿到支付的結(jié)果

剩下的就是你的業(yè)務(wù)邏輯了!

完整代碼

/* 
 * 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');

// 創(chuàng)建服務(wù)器實例
const app = express();
// 配置解析表單數(shù)據(jù)的中間件
app.use(express.urlencoded({ extended: false }))
app.use(express.json())
// 監(jiān)聽端口
app.listen(3031, () => {
    console.log('服務(wù)器啟動成功!')
})

// 創(chuàng)建支付實例
const pay = new WxPay({
    appid: '你的微信小程序appid',
    mchid: '商戶號',
    publicKey: fs.readFileSync('./apiclient_cert.pem'), // 公鑰
    privateKey: fs.readFileSync('./apiclient_key.pem'), // 秘鑰
});

// 定義一個獲取支付參數(shù)路由(get請求)
app.get('/pay', payInfo);

// 拿到支付所需參數(shù)
async function payInfo(req, res) {
    // 接收前端傳過來的openid
    let openid = req.params.openid;
    const params = {
        description: 'Asnull的支付測試', // 訂單描述
        out_trade_no: randomNumber(), // 訂單號,一般每次發(fā)起支付都要不一樣,可使用隨機數(shù)生成
        notify_url: 'https://pay.lipux.cn/notify_url',
        amount: {
            total: 1, // 支付金額,單位為分
        },
        payer: {
            openid: openid, // 微信小程序用戶的openid,一般需要前端發(fā)送過來
        },
        scene_info: {
            payer_client_ip: 'ip', // 支付者ip,這個不用理會也沒有問題
        },
    };
    const result = await pay.transactions_jsapi(params);
    console.log(result);
    // 將結(jié)果響應(yīng)給微信小程序前端
    res.send(result);
}

// 回調(diào)路由
app.post('/notify_url', async(req, res) => {
    // 申請的APIv3
    let key = '45c18fdfdgd45f5bc5321201dfdf453f';
    let { ciphertext, associated_data, nonce } = req.body.resource;
    // 解密回調(diào)信息
    const result = pay.decipher_gcm(ciphertext, associated_data, nonce, key);
    // 拿到訂單號
    let { out_trade_no } = result;
    if (result.trade_state == 'SUCCESS') {
        // 支付成功之后需要進行的業(yè)務(wù)邏輯
    }
})

// 訂單號生成函數(shù)
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項目成功部署到服務(wù)器之后,我們只需要在微信小程序先對https://域名/pay 發(fā)起get請求

拿到數(shù)據(jù)后再調(diào)用wx.requestPayment即可發(fā)起支付。

最后,祝您玩的愉快!

參考

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

到此這篇關(guān)于使用nodejs搭建微信小程序支付接口的文章就介紹到這了,更多相關(guān)nodejs搭建微信小程序支付接口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解npm與package.json之間的聯(lián)系

    詳解npm與package.json之間的聯(lián)系

    這篇文章主要為大家介紹了npm與package.json之間的聯(lián)系圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • Node.js 使用遞歸實現(xiàn)遍歷文件夾中所有文件

    Node.js 使用遞歸實現(xiàn)遍歷文件夾中所有文件

    這篇文章主要介紹了Node.js使用遞歸實現(xiàn)遍歷文件夾中所有文件,需要的朋友可以參考下
    2017-09-09
  • 詳解如何使用PM2將Node.js的集群變得更加容易

    詳解如何使用PM2將Node.js的集群變得更加容易

    本篇文章主要介紹了詳解如何使用PM2將Node.js的集群變得更加容易,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • pm2 部署 node的三種方法示例

    pm2 部署 node的三種方法示例

    本篇文章主要介紹了pm2 部署 node的三種方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 了解javascript中變量及函數(shù)的提升

    了解javascript中變量及函數(shù)的提升

    這篇文章主要介紹了關(guān)于javascript中變量及函數(shù)的提升,下面和小編來一起學(xué)習(xí)吧
    2019-05-05
  • autojs的Node.js正確退出腳本示例

    autojs的Node.js正確退出腳本示例

    這篇文章主要為大家介紹了autojs的Node.js正確退出腳本示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-01-01
  • Node文件操作匯總實例詳解

    Node文件操作匯總實例詳解

    這篇文章主要為大家介紹了Node文件操作匯總實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • Node版本升級和降級之node版本管理工具nvm詳解

    Node版本升級和降級之node版本管理工具nvm詳解

    nvm是管理node版本的工具,一個電腦中可以安裝多個node版本,當(dāng)我們想使用哪個版本就切換成哪個版本,而nvm則是提供切換node版本的工具,這篇文章主要給大家介紹了關(guān)于Node版本升級和降級之node版本管理工具nvm的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • Nodejs中fs文件系統(tǒng)模塊的路徑動態(tài)拼接的問題和解決方案

    Nodejs中fs文件系統(tǒng)模塊的路徑動態(tài)拼接的問題和解決方案

    在使用fs模塊操作文件時,如果提供的操作路徑是以./或../開頭的相對路徑時,很容易出現(xiàn)路徑動態(tài)拼接錯誤的問題,所以本文給大家介紹了Nodejs中fs文件系統(tǒng)模塊的路徑動態(tài)拼接的問題和解決方案,需要的朋友可以參考下
    2024-03-03
  • socket.io學(xué)習(xí)教程之基礎(chǔ)介紹(一)

    socket.io學(xué)習(xí)教程之基礎(chǔ)介紹(一)

    socket.io提供了基于事件的實時雙向通訊,所以下面這篇文章主要介紹了關(guān)于socket.io的相關(guān)資料,主要介紹了學(xué)習(xí)socket.io的基礎(chǔ)知識,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-04-04

最新評論