日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

微信JSAPI支付v3流程(uniapp和node版)

發(fā)布時(shí)間:2023/12/31 javascript 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信JSAPI支付v3流程(uniapp和node版) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、微信JSAPI支付

請(qǐng)?zhí)崆皽?zhǔn)備好接入前的準(zhǔn)備文檔獲取相關(guān)的配置數(shù)據(jù),否則下面需要的數(shù)據(jù)你可能會(huì)比較懵!
并且需要提前了解微信JSAPI支付文檔

二、獲取用戶openid

獲取openid方法例子

三、h5調(diào)起支付

1.第一種通過(guò)WeixinJSBridge調(diào)起微信支付服務(wù)

參數(shù)獲取請(qǐng)看本文JSAPI支付簽名

WeixinJSBridge.invoke('getBrandWCPayRequest', {appId:'xxxxxxxx',//公眾號(hào)ID,由商戶傳入timeStamp:'xxxxxxxx',//時(shí)間戳,自1970年以來(lái)的秒數(shù)nonceStr:'xxxxxxxx',//隨機(jī)串package:'xxxxxxxx', // 統(tǒng)一支付接口返回的prepay_id參數(shù)值signType:"RSA",//微信簽名方式:paySign:'xxxxxxxx',//微信簽名},(res) =>{if (res.err_msg == "get_brand_wcpay_request:ok") {//支付成功}} );

2.第二種通過(guò)js-sdk中的wx.chooseWXPay調(diào)起微信支付服務(wù)

首先需要閱讀js-sdk文檔,js-sdk文檔
通過(guò)js-sdk獲取支付的能力

npm install weixin-js-sdk

下文中的getJssdk獲取請(qǐng)看本文JS-SDK權(quán)限簽名的方法

import wx from 'weixin-js-sdk'; import {getJssdk} from "@/api/wx.js"; export const setJsSdk = async ()=>{let params = {url:location.href.split('#')[0]}//JS-SDK使用權(quán)限簽名let res = await getJssdk(params);let data = res.data;wx.config({debug: false,appId: appid, // 必填,公眾號(hào)的唯一標(biāo)識(shí)jsApiList:['chooseWXPay',//發(fā)起微信支付],timestamp:data.timestamp,//生成簽名的時(shí)間戳nonceStr:data.nonceStr,//生成簽名的隨機(jī)串signature:data.signature,//簽名});wx.error(e => {console.log('wx sdk errors:', e);}); }

調(diào)用wx.chooseWXPay進(jìn)行支付調(diào)起
參數(shù)獲取請(qǐng)看本文JSAPI支付簽名

wx.chooseWXPay({timestamp: xxxxxxxx, // 支付簽名時(shí)間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后臺(tái)生成簽名使用的timeStamp字段名需大寫其中的S字符nonceStr: 'xxxxxxxx', // 支付簽名隨機(jī)串,不長(zhǎng)于 32 位package: 'xxxxxxxx', // 統(tǒng)一支付接口返回的prepay_id參數(shù)值,提交格式如:prepay_id=\*\*\*)signType: 'xxxxxxxx', // 微信支付V3的傳入RSA,微信支付V2的傳入格式與V2統(tǒng)一下單的簽名格式保持一致paySign: 'xxxxxxxx', // 支付簽名success: function (res) {// 支付成功后的回調(diào)函數(shù)} });

四、node對(duì)接對(duì)應(yīng)的相關(guān)接口

1.JS-SDK權(quán)限簽名

對(duì)應(yīng)上面目錄三-2的getJssdk接口使用
需提前準(zhǔn)備
appid:appid憑證
appSecret:密鑰

const crypto = require("crypto"); const axios = require("axios"); const appid = "xxxxxxxx"; const appSecret = 'xxxxxxxx';//獲取js-sdk參數(shù) const getJssdk = (params)=>{//----------------------------------------------------------------------------- // 這兩個(gè)接口獲取的臨時(shí)數(shù)據(jù)必須進(jìn)行定時(shí)任務(wù)每個(gè)小時(shí)更新一次緩存起來(lái) // 由于獲取jsapi_ticket的api調(diào)用次數(shù)非常有限,頻繁刷新jsapi_ticket會(huì)導(dǎo)致api調(diào)用受限,影響自身業(yè)務(wù),開發(fā)者必須在自己的服務(wù)全局緩存jsapi_ticket 。//獲取access_tokenlet result1 = await axios(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${appSecret}`);let access_token = result1.data.access_token;//獲取jsapi_ticket 是公眾號(hào)用于調(diào)用微信JS接口的臨時(shí)票據(jù)let result2 = await axios(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`);let jsapi_ticket = result2.data.ticket; //-----------------------------------------------------------------------------let timestamp = new Date().getTime();//時(shí)間戳let url = params.url;//當(dāng)前網(wǎng)頁(yè)的URL,不包含#及其后面部分let nonceStr = 'xxxxxxxxxxxxxxxxxxxx';//隨機(jī)字符串let string1 = `jsapi_ticket=${jsapi_ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;let signature = jiamiSha1(string1);//sha1加密//返回?cái)?shù)據(jù)給客戶端return {code:0,message:'',data:{timestamp,nonceStr,signature}} } //sha1加密 function jiamiSha1(str){// 需要加密的字符串let sf = crypto.createHash('sha1');//使用加密算法sf.update(str);//進(jìn)行加密let content = sf.digest("hex");//以二進(jìn)制數(shù)據(jù)為字符串形式展示return content; }; module.exports = getJssdk;

2.JSAPI支付簽名

JSAPI支付簽名下單文檔-https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml
需提前準(zhǔn)備
appid:appid憑證
mchid:商戶號(hào)
serial_no:商戶序列號(hào)
pem:證書私鑰

const axios = require("axios"); const crypto = require("crypto"); const pem = require("./apiclient_key.js"); const appid = "xxxxxxxxxxxxx";//appid const mchid = 'xxxxxxxxxxxxx';//商戶號(hào) const serial_no = 'xxxxxxxxxxxxx';//商戶序列號(hào)// jsapi下單 /* data:{out_trade_no:'商戶訂單號(hào)',description:'說(shuō)明'attach:'攜帶回調(diào)參數(shù)'notify_url:'通知地址',total:'分',openid:'用戶openid', } */ function paysgin(data){return new Promise(async(resolve,reject)=>{let url = '/v3/pay/transactions/jsapi';let params = {"mchid": mchid,//直連商戶號(hào)"out_trade_no": data.out_trade_no,//商戶系統(tǒng)內(nèi)部訂單號(hào),只能是數(shù)字、大小寫字母_-*且在同一個(gè)商戶號(hào)下唯一"appid": appid,//應(yīng)用ID"description": data.description,//商品描述"attach":JSON.stringify(data.attach),//附加數(shù)據(jù)"notify_url": data.notify_url,//通知地址"amount": {"total": data.total,//總金額,單位為分"currency": "CNY"},"payer": {"openid": data.openid//用戶標(biāo)識(shí)}}//獲取prepay_idlet result = await axios({url:"https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi",method:"post",headers:{"Authorization":sgin('POST',url,params)},data:params });// 配置調(diào)起支付參數(shù)let prepay_id = result.data.prepay_id;let timestamp = parseInt(new Date().getTime()/1000).toString();let nonce_str = new Date().getTime().toString();let jiamiPaySign = appid + "\n" + timestamp + "\n" + nonce_str + "\n" + `prepay_id=${prepay_id}` + "\n";let signaturePaySign = sha256(jiamiPaySign);//-----------------------------------------------------// 保存支付參數(shù)到數(shù)據(jù)庫(kù)//-----------------------------------------------------resolve({code:0,msg:'',data:{appId:appid,//公眾號(hào)ID,由商戶傳入timeStamp:timestamp,//時(shí)間戳,自1970年以來(lái)的秒數(shù)nonceStr:nonce_str,//隨機(jī)串package:`prepay_id=${prepay_id}`,signType:"RSA",//微信簽名方式:paySign:signaturePaySign,//微信簽名}});}) } //RSA-SHA256加密 function sha256(str){let privateKey = pem;let sign = crypto.createSign('RSA-SHA256');sign.update(Buffer.from(str, 'utf-8'));let signature = sign.sign(privateKey, 'base64');return signature; } //簽名 function sgin(method,url,params=""){let timestamp = parseInt(new Date().getTime()/1000);let nonce_str = new Date().getTime();params = JSON.parse(JSON.stringify(params));let message = method + "\n"+ url + "\n"+ timestamp + "\n"+ nonce_str + "\n"+ JSON.stringify(params) + "\n";let signature = sha256(message);let auth = `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",serial_no="${serial_no}",nonce_str="${nonce_str}",timestamp="${timestamp}",signature="${signature}"`;return auth; } module.exports = paysgin

3.支付成功的回調(diào)

支付結(jié)果通知文檔-https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
在上面2.JSAPI支付簽名后把參數(shù)給前端,發(fā)起支付后,支付成功會(huì)通知調(diào)用notify_url地址進(jìn)行接收參數(shù)。
需要準(zhǔn)備
key:APIv3密鑰(微信商戶平臺(tái)—>賬戶設(shè)置—>API安全—>設(shè)置APIv3密鑰)

//event.body 是 回調(diào)回來(lái)的數(shù)據(jù) let body = JSON.parse(event.body); console.log('body : ', body.resource) const key = "xxxxxxxxxxxxxxx"; const ciphertext = body.resource.ciphertext; const nonce = body.resource.nonce; const associated_data = body.resource.associated_data; //解密 let data = JSON.parse(decodeByAES(ciphertext,key,nonce,associated_data)); data.attach = JSON.parse(decodeURIComponent(data.attach)); data.success_time = decodeURIComponent(data.success_time.replace(/\+/g, '%20').replace(/T/g,' ')); console.log("解密",data)//----------------------------------------------------- // 進(jìn)行相關(guān)回調(diào)通知,數(shù)據(jù)庫(kù)操作,消息提醒等等。。。 //-----------------------------------------------------

decodeByAES解密回調(diào)的加密參數(shù)

const crypto = require("crypto");function decodeByAES(cipherText,key,iv,add){let rst = '';cipherText = Buffer.from(cipherText, 'base64');let authTag = cipherText.slice(cipherText.length - 16);let data = cipherText.slice(0, cipherText.length - 16);let decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);decipher.setAuthTag(authTag);decipher.setAAD(Buffer.from(add));rst = decipher.update(data, 'binary', 'utf8');try {rst += decipher.final('utf-8');} catch (e) {think.logger.error(e.toString());}return rst; }

總結(jié)

以上是生活随笔為你收集整理的微信JSAPI支付v3流程(uniapp和node版)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。