Node——微信支付 V3接口

1. 新建v3PayApi.js

const fs = require("fs")
const request = require('request')
const rsa = require("./rsa")

/* 微信支付 V3接口请求 */
module.exports = class V3PayApi {
  /* 接口地址 */
  host = "https://api.mch.weixin.qq.com"
  /* 证书私钥 pem文件 */
  privateKey = fs.readFileSync(`${__dirname}/cert/apiclient_key.pem`, "utf-8")
  /* 商户号 */
  mchid = ""
  /* 证书序列号 */
  serial_no = ""

  /* 请求
    @param api 接口短地址
    @param data 接口参数
    @param query 地址携带的参数,如:?key=value
  */
  http(api, data, query) {
    return new Promise((r, j) => {
      const requestParams = this.makeReqParams(api, data, query)
      request(requestParams, function (error, resp, body) {
        if(error)return j(error)
        return r(body)
      })
    })
  }

  /* 组装参数 */
  makeReqParams(api, _body = "", query = "") {
    const body = JSON.stringify(_body)
    let method = "POST"
    let url = api + query
    let timeStamp = parseInt(Date.now() / 1000)
    let nocStr = this.getNonceStr()
    let signStr = method + "\n" + url + "\n" + timeStamp + "\n" + nocStr + "\n" + body + "\n"
    let sign_base64 = rsa.SignUtil.rsaSign(signStr, this.privateKey)
    let authorStr = 'mchid="' + this.mchid + '",nonce_str="' + nocStr + '",signature="' + sign_base64 + '",timestamp="' + timeStamp + '",serial_no="' + this.serial_no + '"'
    let params = {
      url: this.host + url,
      method: method,
      headers: {
        "Content-type": "application/json",
        'Accept': 'application/json',
        "User-Agent": "TitanPan/5.0",
        "Authorization": "WECHATPAY2-SHA256-RSA2048 " + authorStr
      },
    }
    if (method == "POST") {
      params["json"] = true
      params["body"] = _body
    }
    return params
  }

  /* 随机字符串 */
  getNonceStr(len) {
    len = len || 32;
    var $chars =
      "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678"; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
    var maxPos = $chars.length;
    var pwd = "";
    for (let i = 0; i < len; i++) {
      pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
    }
    return pwd;
  }
}

2. 新建rsa.js

const {KJUR, hextob64} = require('jsrsasign')

const HashMap = {
    SHA256withRSA: 'SHA256withRSA',
    SHA1withRSA: 'SHA1withRSA'
}

const PEM_BEGIN = '-----BEGIN PRIVATE KEY-----\n'
const PEM_END = '\n-----END PRIVATE KEY-----'

/**
 * rsa签名参考:https://www.jianshu.com/p/145eab95322c
 */
exports.SignUtil = {
    /**
     * rsa签名
     * @param content 签名内容
     * @param privateKey 私钥,PKCS#1
     * @param hash hash算法,SHA256withRSA,SHA1withRSA
     * @returns 返回签名字符串,base64
     */
    rsaSign: function (content, privateKey, hash = "SHA256withRSA") {
        privateKey = this._formatKey(privateKey)
        // 创建 Signature 对象
        const signature = new KJUR.crypto.Signature({
            alg: hash,
            //!这里指定 私钥 pem!
            prvkeypem: privateKey
        })
        signature.updateString(content)
        const signData = signature.sign()
        // 将内容转成base64
        return hextob64(signData)
    },
    _formatKey: function (key) {
        if (!key.startsWith(PEM_BEGIN)) {
            key = PEM_BEGIN + key
        }
        if (!key.endsWith(PEM_END)) {
            key = key + PEM_END
        }
        return key
    }
}

3. 使用示例

当前示例用的是发起商家转账API,具体参数参考微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_1.shtml

const V3PayApi = require("./v3PayApi.js")

let data = {
  "appid": 'appid',
  "out_batch_no": '20220930231828852',
  "batch_name": '1664551108852测试提现单',
  "batch_remark": '1664551108852测试提现单',
  "total_amount": 1 * 100,
  "total_num": 1,
  "transfer_detail_list": [
    {
      "out_detail_no": '20220930231828852',
      "transfer_amount": 1 * 100,
      "transfer_remark": '测试用户提现',
      "openid": 'openid'
    }
  ]
}

new V3PayApi().http("/v3/transfer/batches",data).then(r=>{
  console.log("suc",r)
}).catch(e=>{
  console.log("err",e)
})
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值