• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Node.js微信支付V3版相关处理方法

武飞扬头像
袁代码
帮助2

学新通

今天给大家写一个关于Node.js接入微信支付V3接口时一些毕竟复杂的点,主要就是请求签名Authorization、调起支付签名、回调参数解密等。

  • 请求签名Authorization

在微信支付V3接口中,商户需要使用自身的私钥对API URL、消息体等关键数据的组合进行SHA-256 with RSA签名。请求的签名信息通过HTTP头Authorization传递,具体说明可以去看签名生成指南。没有携带签名或者签名验证不通过的请求,都不会被执行,并返回401 Unauthorized 。

那么如何生成这个Authorization呢,这个请求头,最麻烦的地方就是如何去生成

signature,其中我们使用jsrsasign模块来进行SHA256 with RSA加密,可以查看如下代码:

  1.  
    const {KJUR, hextob64} = require('jsrsasign')
  2.  
     
  3.  
     
  4.  
    rsaSign(content, privateKey, hash='SHA256withRSA'){
  5.  
    const signature = new KJUR.crypto.Signature({
  6.  
                alg: hash,
  7.  
    prvkeypem: privateKey
  8.  
    })
  9.  
    signature.updateString(content)
  10.  
    const signData = signature.sign()
  11.  
        // 将内容转成base64
  12.  
    return hextob64(signData)
  13.  
    }
  14.  
     
  15.  
     
  16.  
    //调用这个函数
  17.  
    let signature = this.rsaSign(`${method}\n${pathname}\n${timestamp}\n${onece_str}\n${bodyParamsStr}\n`,this.private_key,'SHA256withRSA')
  18.  
     
  19.  
     
  20.  
    //获取到signature后就可以获取到Authorization了
  21.  
     let Authorization = `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${onece_str}",timestamp="${timestamp}",signature="${signature}",serial_no="${serial_no}"`
学新通

其中mchid:商户号,onece_str:随机字符,timestamp:时间戳,serial_no:商户API证书序列号。这样在请求时在请求头里加入就可以了,如下:

  1.  
    headers:{
  2.  
    'Content-Type':'application/json',
  3.  
    'Accept':'application/json',
  4.  
    'Authorization':Authorization
  5.  
    }

调起支付签名

通过上述请求后可以得到预支付交易会话标识prepay_id,然后我们需要再次进行签名,用于调起微信支付,代码如下:

  1.  
    paysign(options) {
  2.  
         let timeStamp = this.createTimeStamp(), //时间戳
  3.  
             nonceStr = this.randomString(), //32位随机数
  4.  
             Ppackage = `prepay_id=${options}`//prepay_id
  5.  
             signType = 'RSA'//加签方式
  6.  
         let PpaySign = `${this.appId}\n${timeStamp}\n${nonceStr}\n${Ppackage}\n`//需要加签的字段拼接
  7.  
         let cryptStr = this.rsaSign(PpaySignthis.privateKey'SHA256withRSA'); //生成签名
  8.  
         let paySign = cryptStr;
  9.  
         return {
  10.  
             timeStamp,
  11.  
             nonceStr,
  12.  
             packagePpackage,
  13.  
             signType,
  14.  
             paySign
  15.  
         };
  16.  
    }
学新通

这里的rsaSign()函数就是上文提到的加密函数,只是这里的content参数有所不同而已,这样我们就可以直接调用起微信支付了。

回调参数解密

微信支付的回调都是需要验证解密之后才可以得到订单数据的,所以解密也是比较复杂的地方,这里我们使用crypto模块,对参数进行解密,代码如下:

  1.  
    const crypto = require("crypto");
  2.  
     
  3.  
     
  4.  
     decode(params) {
  5.  
    const AUTH_KEY_LENGTH = 16;
  6.  
    // ciphertext = 密文,associated_data = 填充内容, nonce = 位移
  7.  
    const { ciphertext, associated_data, nonce } = params;
  8.  
    // 密钥
  9.  
    const key_bytes = Buffer.from(this.apiv3_private_key, 'utf8');
  10.  
    // 位移
  11.  
    const nonce_bytes = Buffer.from(nonce, 'utf8');
  12.  
    // 填充内容
  13.  
    const associated_data_bytes = Buffer.from(associated_data, 'utf8');
  14.  
    // 密文Buffer
  15.  
    const ciphertext_bytes = Buffer.from(ciphertext, 'base64');
  16.  
    // 计算减去16位长度
  17.  
    const cipherdata_length = ciphertext_bytes.length - AUTH_KEY_LENGTH;
  18.  
    // upodata
  19.  
    const cipherdata_bytes = ciphertext_bytes.slice(0, cipherdata_length);
  20.  
    // tag
  21.  
    const auth_tag_bytes = ciphertext_bytes.slice(cipherdata_length, ciphertext_bytes.length);
  22.  
    const decipher = crypto.createDecipheriv(
  23.  
    'aes-256-gcm', key_bytes, nonce_bytes
  24.  
    );
  25.  
    decipher.setAuthTag(auth_tag_bytes);
  26.  
    decipher.setAAD(Buffer.from(associated_data_bytes));
  27.  
     
  28.  
     
  29.  
    const output = Buffer.concat([
  30.  
    decipher.update(cipherdata_bytes),
  31.  
    decipher.final(),
  32.  
    ]);
  33.  
    return output;
  34.  
    }
学新通

其中就是params回调返回值里的resource参数,这样就可以得到回调返回的信息了。

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgaajah
系列文章
更多 icon
同类精品
更多 icon
继续加载