nodejs實現微信小程序支付功能及相關問題總結

最近使用nodejs做爲服務器,搭建了一個微信小程序。其中的微信支付功能是比較複雜的一部分。不過只要咱們能掌握微信支付的工做流程,那實現這個功能也不會很難的。下面分享這次微信支付的實現經歷。  

開發文檔學習

借圖一用,我的認爲這張圖包含了微信支付的架構理念(https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3)php


商戶系統和微信支付系統主要交互:前端

實現流程: node

=> 獲取微信用戶的openid (小程序端獲取傳到後臺)express

=> 預下單獲取prepay_id ,sign簽名(後臺根據相關參數進行簽名)npm

=> 小程序端發送支付請求(根據後臺返回的prepay_id和sign)json

2.實現代碼

  1. 小程序獲取openid

//小程序端
wx.login({
  success(res) {
    if (res.code) {
      // 發起網絡請求
      wx.request({
        url: 'https://test.com/onLogin',
        data: {
          code: res.code
        },
        success:function(res){
          let openId = res.data.openid//獲取後臺返回的openid
        }
      })
    } else {
      console.log('登陸失敗!' + res.errMsg)
    }
  }
})

//nodejs端
 var request = require('request')
 const JSCODE = ''(前端傳過來的值)
 let wxUrl = "https://api.weixin.qq.com/sns/jscode2session"//小程序appid,secret等信息存在後臺的配置文件中
var url = wxUrl + 'appid=' + Config.wxLogin.appid + '&secret=' + Config.wxLogin.secret
var js_code = req.query.js_code
url = url + '&js_code=' + js_code + '&grant_type=authorization_code'
request(url, function (error, response, body) {
    if (error) {
        var results = Util.formatErrorRes(error);
        res.json(results);
        return    }
    var results = Util.formatRes(body);
    res.json(results);
})複製代碼

2. 後臺根據相關參數獲取prepay_id,sign簽名小程序

   =>後端格式化參數(根據小程序統一下單文檔的須要)後端

   =>後臺帶參數請求微信統一下單地址(其中notify_url後端接受支付結果的接口地址)微信小程序

   =>請求成功解析小程序返回的xml格式數據(引入npm包xmlreader,主要獲取prepay_idapi

   =>根據返回的值進行二次簽名生成簽名字符串(與prepay_id一塊兒返回給前端)

   =>前端根據返回的簽名和prepay_id進行支付請求

   =>微信支付成功,微信服務器將支付結果發到以前設置的notify_url

   =>根據微信後臺返回的結果,更新用戶信息

    注:此部分代碼較多,近期會整理下放在GitHub,若是哪位道友着急須要可在下方評論中說明

3.問題總結

  1. 支付簽名錯誤 (主要看第二條)

微信官方回答
1) 使用微信的在線簽名工具檢查簽名是否和程序生成的一致
    https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1
    簽名工具用谷歌打開。選擇MD5,XML,而後把請求參數xml放進去,就能校驗簽名。
2)若是和微信的在線簽名工具一致,說明程序沒有錯誤,肯定是API密鑰錯誤
   (被別人改動或者記錯了)在商戶平臺的帳戶信息中更改API密鑰(帳戶設置-安全設置-API安全),
   15分鐘後生效
   2.1)統一下單用的是A商戶號,也必須是A商戶號登錄商戶平臺設置key纔對。
   2.2)要注意統一下單請求參數中total_fee參數的類型是int類型。
3) 若是和微信的在線簽名工具不一致,說明程序有錯誤,
    常見的錯誤多是:
    3.1) 編碼問題,確保全部的都是utf-8的. 若是有中文, 能夠先把中文改爲英文從新簽名,
    看是否簽名錯誤,若是英文不會錯中文才會錯,基本確定是編碼問題
    3.2:)消息中字段大小寫和文檔中徹底一致複製代碼

  按照上述需求進行配置就能夠解決支付簽名錯誤的問題了。 

 2.express微信支付回調值req.body爲空{}

     支付返回的格式是xml,查找到緣由是express4.x裏將body-parser分離出來,變成像其餘中間件的使用方式,

因此咱們須要在app.js中增長中間件

var bodyParser = require("body-parser");
require("body-parser-xml")(bodyParser);
// 解析支付回調的xml數據
app.use(bodyParser.xml({
    limit: "1MB",
   // Reject payload bigger than 1 MB
    xmlParseOptions: {
        normalize: true,
        normalizeTags: true, 
        explicitArray: false
    },
    verify: function(req, res, buf, encoding) {
        if(buf && buf.length) {
            // Store the raw XML
            req.rawBody = buf.toString(encoding || "utf8");
        }
    }}));複製代碼

3.二次簽名報缺乏參數或參數錯誤

  參數的格式必須嚴格按照文檔要求,參數須要用使用駝峯(以前用下劃線app_id這種類型一      直報參數錯誤...)

var ret = {
    appId: appid,
    package:'prepay_id='+prepayid,
    nonceStr: noncestr,
    signType:'MD5',
    timeStamp: timestamp,
};複製代碼

5.沒有支付權限

 檢查該小程序帳號是否已經獲取了支付資格。

相關文章
相關標籤/搜索