最近在做微信支付,根據微信官方文件上的要求 用RSA加簽去請求支付視窗的調起,下面詳細列舉支付開發過程;
當前專案的流程大概是,前端根據後端要求提交資料-------》拿到後臺返回的prepay_ID,和order_ID,-----》前端RSA加簽------》調起微信的支付視窗----》支付。
myOderData(options){ const that=this; let params={ datas:options,//提交訂單資料的引數 method:'POST' } let paycode,OrderNo; api.addorderData(params).then(res=>{ if(res.data.Success==false){ utils.msgtips(res.data.Msg); }else{ paycode=res.data.Data.prepay_id;//拿到後臺返回的prepay_id OrderNo=res.data.Data.OrderNo;//拿到後臺返回的訂單號 // console.log(paycode); let obj= utils.paysign(paycode); //RSA加簽,此處已封裝成paysign方法 utils.processPay(obj).then(res=>{//發起支付窗體的調起,已封裝成processPay方法 if(res.errMsg=="requestPayment:ok"){//支付成功時,要傳入訂單號到後臺改變訂單狀態 that.updateorderData(OrderNo) }else if(res.errMsg=="requestPayment:fail cancel"){//取消支付時的操作 utils.msgtips('您已取消支付'); wx.navigateTo({ url:'../mppaycancel/index' }) } }) } }).catch(err=>{ console.log(err) })
以上是整體使用的方法。
下面講解加簽:
根據騰訊官方文件上的要求,如圖:
文件原文地址: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_4.shtml
現在用的是v3 加簽,以前是v2 MD5
需要注意的是加密加簽的方式, 需要和後端保持一致。
1小程式ID獲取:
const accountInfo = wx.getAccountInfoSync(); let appId=accountInfo.miniProgram.appId;
2.時間戳:
function createTimeStamp(){ return parseInt(new Date().getTime() / 1000) + '' }
3.32位隨機數:
function randomString(){ const chars='ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; //預設去掉了容易混淆的字元oOLl,9gq,Vv,Uu,I1 const len=32; const maxPos=chars.length; let pwd=''; for(let i=0;i<len;i++){ pwd+=chars.charAt(Math.floor(Math.random()*maxPos)); } return pwd; }
4.訂單詳情擴充套件字元prepay_id:
即後端返回回來的prepay_id欄位資料。
5.加簽方式:
signType= 'RSA'
6.簽名 paysign,這裡要說明一下:
1).最好嚴格按照騰訊文件要求的順序來。使用欄位appId、timeStamp、nonceStr、package
2)要用‘\n’ 連線各欄位,並且結尾也要用‘\n’ 不要用等於號。
官方文件有說明:連結:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_4.shtml
如圖:
還有一個很重要的RSA加簽:
這個我搜到2個博主提供的:
1):
demo:https://blog.csdn.net/UFO00001/article/details/72822907
github:https://github.com/UFO0001/WX_RSA
2)
https://github.com/zhangzhaopds/WeixinApp_RSA_Signature
第二種需要用小程式npm構建,照著文件操作就可以了,
npm構建文件如下:
https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html
我用的是第一個,直接頁面引入了wx_rsa.js
如圖:
function signLong (data) { let sign_rsa = new RSA.RSAKey(); sign_rsa = RSA.KEYUTIL.getKey(privateKey); let hashAlg = 'sha256';//sha256//此處換成騰訊要求的方式 let Sig = sign_rsa.signString(data, hashAlg); Sig = RSA.hex2b64(Sig); // hex 轉 b64 return Sig; }
關於私鑰:
一定要下載證照:
下載後開啟此檔案複製私鑰貼上到編輯器中,不能TXT 中複製,會改變編碼方式,導致加簽不成功。
騰訊官網有一個加簽解籤的驗證工具,這個只能檢測是否符合規範,不能檢測值是否正確。地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml
function paysign(options){//發起支付籤的欄位準備 const accountInfo = wx.getAccountInfoSync(); let appId=accountInfo.miniProgram.appId,//小程式appid timeStamp=createTimeStamp(),//時間戳 nonceStr=randomString(),//32位隨機數 Ppackage= `prepay_id=${options}`,//prepay_id signType= 'RSA';//加簽方式 //appId、timeStamp、nonceStr、package let PpaySign=`${appId}\n${timeStamp}\n${nonceStr}\n${Ppackage}\n`;//需要加簽的欄位拼接 let cryptStr=Rsa.signLong(PpaySign);//生成簽名 let paySign=cryptStr; return obj={timeStamp,nonceStr,Ppackage,signType,paySign}; }
//發起支付 function processPay(options){ // console.log(options) let that=this; return new Promise((resolve,reject)=>{ wx.requestPayment({ package:options.Ppackage,...options, success: (res)=>{ resolve(res); }, fail: (err)=>{ resolve(err); } }); }) }
以上就是完整的涉及到支付的一些方法和取值過程。