admin管理员组文章数量:1558103
v3Pay.js
/**
* 作者:TitanPan
* 日期:2022-07-25
* 备注:只做了下单和退款两个接口,但是做完了数据结构,其他接口只需要按需增加即可。需要安装jsrsasign
*/
const request = require('request');
const rsa = require("./rsa")
const host = "https://api.mch.weixin.qq"
const apiKeyV3 = "" //微信商户 V3 key
const privateKey = `` //证书私钥key
const cert = `` //证书cert
const mchid= "" //商户号
const serial_no = "" //证书序列号
const appid = "" //支付端appid
//下单
function unionOrder(postData,callback){
let pay_params = new payParmas()
pay_params.setAppid(appid) //设置appid
pay_params.setMchid(mchid) //设置商户号
pay_params.setOutTradeNo(postData["orderid"]) //设置商家订单号
pay_params.setAmount(Math.round(postData["amount"] * 100)) //将支付金额从元变为分
pay_params.setAttach(postData["attach"]) //附加信息
pay_params.setNotifyUrl(postData["notify_url"]) //回调地址
pay_params.setPayer(postData["openid"]) //支付人openid
if(postData["Description"]){
pay_params.setDescription(postData["Description"]) //如果有商品描述,则加上
}
let paySdata = pay_params.getParams()
let requestParams = makeReqParams("/v3/pay/transactions/jsapi","",obj) //构建请求参数
request(requestParams,
function(error, resp, body) {
if (!error && resp.statusCode == 200) {
callback(body)
}else{
console.log("下单失败:"+error)
console.log(body)
callback(body)
}
})
}
//退款
function refund(postData,callback){
let params = new payParmas()
if(postData["transaction_id"]){
params.setTransactionId(postData["transaction_id"])
}else{
params.setOutTradeNo(postData["orderid"])
}
params.setOutRefundNo(postData["refund_orderid"])
if(postData["reason"]){
params.setReason(postData["reason"])
}
params.setReFundAccount(Math.round(postData["refund"] * 100),Math.round(postData["total"] * 100))
params.setNotifyUrl(postData["notify_url"])
let refundParams = params.getParams()
let requestParams = makeReqParams("/v3/refund/domestic/refunds","",refundParams)
request(requestParams,
function(error, resp, body) {
if (!error && resp.statusCode == 200) {
callback(body)
}else{
console.log("退款失败:"+error)
console.log(body)
callback(body)
}
})
}
//拼接请求参数
function makeReqParams(api,query,body){
if(!query){
query = ""
}
if(!body){
body = ""
}else{
body = JSON.stringify(body)
}
let method = signObj["method"]
//如果请求中有查询参数,URL末尾应附加有'?'和对应的查询字符串。
let url = api+query
let timeStamp = parseInt(Date.now()/1000)
let nocStr = randomString()
//组合签名字符串
let signStr = method+"\n"+url+"\n"+timeStamp+"\n"+nocStr+"\n"+body+"\n"
let sign_base64 = rsa.SignUtil.rsaSign(signStr,privateKey)
let authorStr = 'mchid="'+mchid+'",nonce_str="'+nocStr+'",signature="'+sign_base64+'",timestamp="'+timeStamp+'",serial_no="'+serial_no+'"'
let params = {
url: 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"){
body = JSON.parse(body)
params["json"] = true
params["body"] = body
}
return params
}
//============= 数据包封装 ================
class payParmas{
constructor() {
this.params = {}
}
setAppid(appid){
this.params["appid"] = appid
}
setMchid(mchid){
this.params["mchid"] = mchid
}
setOutTradeNo(out_trade_no){
this.params["out_trade_no"] = out_trade_no
}
setDescription(description){
this.params["description"] = description
}
setNotifyUrl(notify_url){
// notify_url = encodeURI(notify_url)
this.params["notify_url"] = notify_url
}
setAmount(amount){
this.params["amount"] = {
"total":amount,
"currency": "CNY"
}
}
setPayer(openid){
this.params["payer"] = {
"openid":openid
}
}
setAttach(attach){
this.params["attach"] = attach
}
setSettleInfo(profit_sharing){
this.params["settle_info"] = {
"profit_sharing":profit_sharing
}
}
//以下是退款用参数
setTransactionId(transaction_id){
this.params["transaction_id"] = transaction_id
}
setOutRefundNo(out_refund_no){
this.params["out_refund_no"] = out_refund_no
}
setReason(reason){
this.params["reason"] = reason
}
setReFundAccount(refund,total){
this.params["amount"] = {
"refund":refund,
"total":total,
"currency": "CNY"
}
}
//返回完整参数
getParams(){
return this.params
}
}
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-----'
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
}
}
版权声明:本文标题:NODEJS微信支付V3接口调用 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1727371755a1111256.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论