NODEJS微信支付V3接口调用

v3Pay.js

/**
 * 作者:TitanPan
 * 日期:2022-07-25
 * 备注:只做了下单和退款两个接口,但是做完了数据结构,其他接口只需要按需增加即可。需要安装jsrsasign
 */



const request = require('request');
const rsa = require("./rsa")
const host = "https://api.mch.weixin.qq.com"
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
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
关于Node.js中微信支付V3的使用,你可以按照以下步骤进行操作: 1. 首先,你需要在微信商户平台上注册账号,并获取到商户号和API密钥。确保你已经完成了微信支付的相关申请和配置。 2. 在你的Node.js项目中,可以使用第三方库来简化微信支付的集成。一个常用的选择是 `wechatpay-axios-plugin`,它提供了对微信支付API的封装和请求发送功能。 你可以通过 `npm` 安装该库: ```shell npm install wechatpay-axios-plugin ``` 3. 在你的代码中引入必要的模块,并初始化一个微信支付实例: ```javascript const { WechatPay } = require('wechatpay-axios-plugin'); // 使用你的商户号和API密钥初始化支付实例 const wechatPay = new WechatPay({ mchid: 'YOUR_MCHID', privateKey: 'YOUR_API_PRIVATE_KEY', }); ``` 4. 创建一个预支付订单并发起支付请求: ```javascript // 构建订单信息 const order = { appid: 'YOUR_APPID', description: '订单描述', outTradeNo: '订单号', notifyUrl: '回调通知URL', amount: { total: 100, // 订单总金额(单位:分) currency: 'CNY', // 货币类型 }, }; // 发起预支付请求 const prepayResult = await wechatPay.createPrepay(order); ``` 上述代码中的 `prepayResult` 将包含预支付订单的相关信息,如预支付ID等。 5. 使用预支付订单的信息,生成支付参数并在前端发起支付: ```javascript // 从预支付结果中提取预支付ID const prepayId = prepayResult.prepayId; // 根据预支付ID生成前端支付参数 const payParams = await wechatPay.getPayParams(prepayId); ``` `payParams` 将包含用于前端发起支付的参数,你可以将它传递给前端页面进行支付。 6. 在收到微信支付通知后,可以使用 `wechatPay.verifyNotify` 方法验证通知的合法性并处理订单状态。 以上是使用Node.js进行微信支付V3的基本流程。请注意,这只是一个简单的示例,实际使用时可能需要根据具体业务需求进行调整和扩展。同时,确保你已经阅读了微信支付V3的官方文档,并了解了相关的安全和业务规范。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值