微信支付 V3 RSA 加簽踩坑

you0509發表於2022-01-04

最近在做微信支付,根據微信官方文件上的要求 用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);
     }
   });
  }) 
 }

  

以上就是完整的涉及到支付的一些方法和取值過程。

 

 

相關文章