日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

微信支付小程序版

發(fā)布時間:2024/4/14 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信支付小程序版 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

近日,因工作需要開始研究在小程序上面實現(xiàn)微信支付功能,經(jīng)過自己研究加上參考網(wǎng)上前輩的部分代碼,終于實現(xiàn)了。期間遇到過很多坑,故在此筆記供自己和有需要的朋友參考。

開發(fā)環(huán)境: ?微信小程序+nodejs(eggjs框架)

參數(shù)準備: ?微信商戶平臺申請支付功能,獲得商戶ID(商戶號)、商戶key(API KEY)、獲得openId、Appsecret()AppSecret是APPID對應的接口密碼)

請求流程: ?

      1.?小程序調(diào)用wx.request請求到后臺(含一些支付信息,如金額、交易名稱等)

      2.后臺在收到前臺小程序請求后,按微信支付開發(fā)文檔的要求進行拼接,然后調(diào)用統(tǒng)一下單API發(fā)送請求到微信獲取簽名(這個簽名個人理解主要是為了驗證報文信息是否被篡改)

      3.連同生成的簽名及一些重要信息在后臺加密后生成一個簽名(后文稱第二次簽名),連同第二次簽名已經(jīng)信息返回給 1 中的小程序request請求。

      4.小程序前臺收到返回的成功信息后,調(diào)用API?wx.requestPayment發(fā)送請求,成功后會條用微信的支付,讓輸入密碼。(開發(fā)環(huán)境會生成一個二維碼,然開發(fā)者微信掃描后才會調(diào)用微信支付輸入密碼界面),最后更新請求結(jié)果反饋給頁面。

跳坑指南:

    兩次簽名時候都需要輸入小程序ID(appId),但是兩次簽名參數(shù)中小程序ID變量名不一樣,第一次是全部小寫,第二次是第二個單詞的首字母大寫appId。如此處寫錯,會提示“支付驗證簽名失敗”{因為簽名的目的就是為了驗證信息是否被篡改,此處變量名稱變了,自然就對不上了}

以下為代碼,供參考:(為了測試,交易金額信息直接在后臺寫死了)

//小程序前臺事件函數(shù) xx.jswxPay:function(){//發(fā)送請求到后臺,獲取prepay_idconsole.log("&&&&&", app.gData.userInfo.openId);wx.request({url: app.gData.iServerUrl + '/getPrepayId',method: 'GET',data: { openId: app.gData.userInfo.openId},header: { 'content-type': 'application/json' },success: function (res) {console.log("payment:",res);if (res.data.status == 100) {var payModel = res.data;wx.requestPayment({'timeStamp': payModel.timestamp,'nonceStr': payModel.nonceStr,'package': payModel.package,'signType': 'MD5','paySign': payModel.paySign,success: function (res) {console.log("success+++",res);wx.showToast({title: '支付成功',icon: 'success',duration: 2000})},fail: function (res) {console.log("fail+++", res);}})}}})}

  

?

//后臺eggjs xxservice.js 中的方法 async getPrepayId(parm) {var {ctx,res }= this;var openid = parm.openId;var str = app.config.getWxPayOrdrID();var spbill_create_ip = '192.168.3.11'//ctx.header.host.replace(/::ffff:/, ''); // 獲取客戶端ipvar body = '測試支付'; // 商品描述var notify_url = 'https://localhost:7001/api/v1/getPrepayId' // 支付成功的回調(diào)地址 可訪問 不帶參數(shù)var nonce_str = str; // 隨機字符串var out_trade_no = str; // 商戶訂單號var total_fee = '1'; // 訂單價格 單位是 分var timestamp = Math.round(new Date().getTime()/1000); // 當前時間console.log("nonce_str",str);var ret ={appid:app.config.wx.appid,mch_id:app.config.wx.Mch_id,nonce_str:nonce_str,body:body,out_trade_no:out_trade_no,total_fee:total_fee,spbill_create_ip:spbill_create_ip,notify_url:notify_url,openid:openid,trade_type: 'JSAPI',key:app.config.wx.Mch_key}// 簽名var sign = paysign.paysignjsapi(ret);var bodyData = '<xml>';bodyData += '<appid>' + app.config.wx.appid + '</appid>'; // 小程序IDbodyData += '<body>' + body + '</body>'; // 商品描述bodyData += '<mch_id>' + app.config.wx.Mch_id + '</mch_id>'; // 商戶號bodyData += '<nonce_str>' + nonce_str + '</nonce_str>'; // 隨機字符串bodyData += '<notify_url>' + notify_url + '</notify_url>'; // 支付成功的回調(diào)地址bodyData += '<openid>' + openid + '</openid>'; // 用戶標識bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>'; // 商戶訂單號bodyData += '<spbill_create_ip>' + spbill_create_ip + '</spbill_create_ip>'; // 終端IPbodyData += '<total_fee>' + total_fee + '</total_fee>'; // 總金額 單位為分bodyData += '<trade_type>JSAPI</trade_type>'; // 交易類型 小程序取值如下:JSAPIbodyData += '<sign>' + sign + '</sign>';bodyData += '</xml>';// 微信小程序統(tǒng)一下單接口var returnValue = {};var urlStr = 'https://api.mch.weixin.qq.com/pay/unifiedorder';const rst = await ctx.curl(urlStr, {// 必須指定 methodmethod: 'POST',data: bodyData});let signBody = rst.data.toString();if (!rst.error && rst.status == 200) {console.log("test1 &&&&");parseString(signBody, function (err, result) {if (result.xml.return_code[0] == 'SUCCESS') {returnValue.msg = '操作成功';returnValue.status = '100';returnValue.out_trade_no = out_trade_no; // 商戶訂單號// 小程序 客戶端支付需要 nonceStr,timestamp,package,paySign 這四個參數(shù)returnValue.nonceStr = result.xml.nonce_str[0]; // 隨機字符串returnValue.timestamp = timestamp.toString(); // 時間戳returnValue.package = 'prepay_id=' + result.xml.prepay_id[0]; // 統(tǒng)一下單接口返回的 prepay_id 參數(shù)值var wxSign = {appId: app.config.wx.appid, //小程序IDnonceStr: returnValue.nonceStr, //隨機串package: returnValue.package, //數(shù)據(jù)包signType: 'MD5', //簽名方式timeStamp: returnValue.timestamp, //時間戳key:app.config.wx.Mch_key}returnValue.paySign = paysign.paysignjsapi(wxSign); // 簽名} else{returnValue.msg = result.xml.return_msg[0];returnValue.status = '102';}});}return returnValue;}

  

//自己寫的拼報文及md5加密,兩次生成簽名時都會調(diào)用,所有寫成了一個獨立的方法 paysign.js 'use strict'; const crypto = require('crypto'); //const request = require('axios'); function paysignjsapi(params) { let param = params; var key=''; var ret ={}; // console.log("param.key",param.key); if(param.key){ key = param.key; delete param.key; ret = param; }else{ ret = param; } var str = raw(ret); //將參數(shù)拼接成字符串 str = str + '&key='+key; console.log("MD5Str:",str); var md5Str = crypto.createHash('md5').update(str).digest('hex'); md5Str = md5Str.toUpperCase(); ; return md5Str; }; //字符排序連接 function raw(args) { var keys = Object.keys(args); keys = keys.sort(); var newArgs = {}; keys.forEach(function(key) { // newArgs[key.toLowerCase()] = args[key]; newArgs[key] = args[key]; }); var str = ''; for(var k in newArgs) { str += '&' + k + '=' + newArgs[k]; } str = str.substr(1); return str; }; module.exports={ paysignjsapi }

  

轉(zhuǎn)載于:https://www.cnblogs.com/chaichai/p/8353601.html

總結(jié)

以上是生活随笔為你收集整理的微信支付小程序版的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。