【全网唯一】全网唯一能够跑通的,跑不通你来找我~用node.js完成微信支付下单功能,且只需要一个文件wxpay.js就解决业务流程的node.js程序
生活随笔
收集整理的這篇文章主要介紹了
【全网唯一】全网唯一能够跑通的,跑不通你来找我~用node.js完成微信支付下单功能,且只需要一个文件wxpay.js就解决业务流程的node.js程序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
?
先吐為敬!
?
最近心血來潮研究nodejs如何完成微信支付功能,結果網上一搜索,一大堆“代碼拷貝黨”、“留一手”、“缺斤少兩”、“不說人話”、“自己都沒跑通還出來發blog”、“各種缺少依賴包”、“各種注釋都沒有”、“自己都不知道在寫什么”的程序大神紛紛為了增加自己博客一個帖子的名額而發布了各種千奇百怪的文章,強哥飽受煎熬,浪費了流量和時間居然沒有一個教程能夠跑通
叔可忍嬸不可忍,我必須要發布一篇真正能夠用nodejs跑通微信支付功能的干貨文章,由于時間關系,錯別字大家就諒解,反正程序能夠跑通,跑不通你來找我!!!
注意,前情提示:
本代碼基于《Node.js(nodejs)對本地JSON文件進行增、刪、改、查操作(輕車熟路)》
傳送門Node.js(nodejs)對本地JSON文件進行增、刪、改、查操作(輕車熟路)_你摯愛的強哥?給你發來1條消息?-CSDN博客
首先要去package.json加入依賴包
"dependencies": {"crypto": "^1.0.1","express": "^4.16.3","request": "^2.85.0","xmlreader": "^0.2.3"},
在/api/文件夾下面創建wxpay.js?
代碼內容
/**做微信支付開發之前一定要修改的配置,各位看官看清楚了◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆*/
const appid = "wx你摯愛的強哥";//公眾號開發者ID[必填,公眾號后臺去拿https://mp.weixin.qq.com/ 開發-基本配置-公眾號開發信息-開發者ID(AppID)]
const appsecret = "a071e61你摯愛的強哥9efc7a";//公眾號開發者密碼[必填,公眾號后臺去拿https://mp.weixin.qq.com/ 開發-基本配置-公眾號開發信息-開發者密碼(AppSecret)]
const mchid = "16你摯愛的強哥3";//微信商戶號[必填,微信商戶平臺去拿https://pay.weixin.qq.com/ 個人信息-賬號信息-登錄賬號]
const mchkey = "你摯愛的強哥32位秘鑰";//微信支付安全密鑰[必填, 在微信商戶平臺-賬戶中心-API安全-API密鑰-安裝操作證書(首次設置才需要)-設置API密鑰(注意這個密鑰自己保存好勿外傳!!!)]
const notify_url = "http://你摯愛的強哥.com";//異步接收微信支付結果通知的回調地址,通知url必須為外網可訪問的url,不能攜帶參數。
/**◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆*///下面的代碼幾乎不用修改----------------------------------------------------------------
//如果運行過程提示你“商戶號該產品權限未開通,請前往商戶平臺>產品中心檢查后重試”,請你去這里https://pay.weixin.qq.com/index.php/public/product/detail?pid=32&productType=0開通微信H5支付(這個一般審核要幾個工作日,如果你的項目很急,建議早點來開通審核)
const $g = global.SG.$g, fs = global.SG.fs, router = global.SG.router, request = global.SG.request, xmlreader = global.SG.xmlreader;
module.exports = global.SG.router;
/*微信支付干貨,微信統一下單幫助文檔
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1*/
//強哥為你量身打造的微信支付方法工具包
let sgWxpay = {signType: "MD5",//簽名類型,默認為MD5,支持HMAC-SHA256和MD5。注意此處需與統一下單的簽名類型一致raw(args) {let keys = Object.keys(args);keys = keys.sort();let newArgs = {};keys.forEach(key => {newArgs[key] = args[key];});let string = "";for (let k in newArgs) {string += "&" + k + "=" + newArgs[k];}string = string.substr(1);return string;},//把金額轉為分getmoney(money) {return parseFloat(money) * 100;},// 隨機字符串產生函數createNonceStr() {return Math.random().toString(36).substr(2, 15);},// 時間戳產生函數createTimeStamp() {return parseInt(new Date().getTime() / 1000) + "";},//簽名加密算法paysignjsapi(appid, body, mch_id, nonce_str, notify_url, out_trade_no, spbill_create_ip, total_fee, trade_type, mchkey) {let ret = {appid: appid,mch_id: mch_id,nonce_str: nonce_str,body: body,notify_url: notify_url,out_trade_no: out_trade_no,spbill_create_ip: spbill_create_ip,total_fee: total_fee,trade_type: trade_type};let string = this.raw(ret);let key = mchkey;string = string + "&key=" + key;return global.SG.crypto.createHash(this.signType).update(string, "utf8").digest("hex").toUpperCase();},//簽名加密算法,第二次的簽名paysignjsapifinal(appid, mch_id, prepayid, noncestr, timestamp, mchkey) {let ret = {appid: appid,partnerid: mch_id,prepayid: prepayid,package: "Sign=WXPay",noncestr: noncestr,timestamp: timestamp};let string = this.raw(ret), key = mchkey;string = string + "&key=" + key;return global.SG.crypto.createHash(this.signType).update(string, "utf8").digest("hex").toUpperCase();},getXMLNodeValue(xml) {// let tmp = xml.split("<"+node_name+">");// console.log('tmp',tmp);// let _tmp = tmp[1].split("</"+node_name+">");// console.log('_tmp',_tmp);// return _tmp[0];xmlreader.read(xml, (errors, res) => {if (null !== errors) {console.log(errors);return;}console.log("長度===", res.xml.prepay_id.text().length);let prepay_id = res.xml.prepay_id.text();console.log("解析后的prepay_id==", prepay_id);return prepay_id;});}
};
//微信支付(all方法支持POST、GET、PUT、PATCH、DELETE傳參方式)
router.all("/demo/wx/wxpay", (req, res) => {//首先拿到前端傳過來的參數let out_trade_no = req.body.out_trade_no || req.query.out_trade_no;//商戶系統內部訂單號,要求32個字符內,只能是數字、大小寫字母_-|* 且在同一個商戶號下唯一。詳見商戶訂單號let body = req.body.body || req.query.body;//商品簡單描述,該字段請按照規范傳遞,具體請見參數規定https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2let total_fee = req.body.total_fee || req.query.total_fee;//準備付款多少錢呀大哥?金額單位分(但是你的前端請傳元為單位,因為這里強哥幫你轉成了分)console.log($g.date.nowtime() + "\n", `商戶系統內部訂單號:${out_trade_no}\n商品描述:${body}\n標價金額:${total_fee}\n${appid}\n${appsecret}\n${mchid}\n${mchkey}`);let msg = null;out_trade_no || (msg = "強哥對你說:你為什么不提供商品訂單號?");body || (msg = "強哥對你說:你為什么不提供商品描述?");total_fee || (msg = "強哥對你說:你為什么不提供商品訂單號?");if (msg) return $g.json.res(req, res, msg, req.body || req.query, false);//首先生成簽名signlet mch_id = mchid;let nonce_str = sgWxpay.createNonceStr();let timestamp = sgWxpay.createTimeStamp();total_fee = sgWxpay.getmoney(total_fee);//強哥為你轉換為分let spbill_create_ip = req.connection.remoteAddress;let trade_type = "APP";let sign = sgWxpay.paysignjsapi(appid, body, mch_id, nonce_str, notify_url, out_trade_no, spbill_create_ip, total_fee, trade_type, mchkey);// console.log("sign:", sign);//組裝xml數據body = "<xml>";body += "<appid>" + appid + "</appid>";//appidbody += "<body><![CDATA[" + "測試微信支付" + "]]></body>";body += "<mch_id>" + mch_id + "</mch_id>";//商戶號body += "<nonce_str>" + nonce_str + "</nonce_str>"; //隨機字符串,不長于32位。body += "<notify_url>" + notify_url + "</notify_url>";body += "<out_trade_no>" + out_trade_no + "</out_trade_no>";body += "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>";body += "<total_fee>" + total_fee + "</total_fee>";body += "<trade_type>" + trade_type + "</trade_type>";body += "<sign>" + sign + "</sign>";body += "</xml>";const url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//下單地址// const url = "https://api2.mch.weixin.qq.com/pay/unifiedorder";//冗災備用域名,正常使用主域名調用,備域名需有流量,保證業務能實時切換。當域名出現請求超時、讀寫超時,自動換備域名重試。request.post({url, body}, (err, r, body) => {if (!err && r.statusCode == 200) {console.log("body:", body);xmlreader.read(body.toString("utf-8"), (err, r) => {if (err) return $g.json.res(req, res, "微信下單報錯", err, false);let prepay_id = r.xml.prepay_id;if (!prepay_id) return $g.json.res(req, res, r.xml.return_msg.text(), r.xml, false);prepay_id = prepay_id.prepay_id.text();console.log("解析后的prepay_id", prepay_id);let finalsign = sgWxpay.paysignjsapifinal(appid, mch_id, prepay_id, nonce_str, timestamp, mchkey);//將預支付訂單和其他信息一起簽名后返回給前端$g.json.res(req, res, "微信下單成功", {// mchid: mchid,//商戶ID(喚起支付貌似不需要這個)// prepayId: prepay_id,appId: appid,//商戶注冊具有支付權限的公眾號成功后即可獲得timeStamp: timestamp,//當前的時間,其他詳見時間戳規則https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2nonceStr: nonce_str,//隨機字符串,不長于32位。推薦隨機數生成算法https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3package: "prepay_id=sgWxPay",//統一下單接口返回的prepay_id參數值,提交格式如:prepay_id=***signType: sgWxpay.signType,//簽名類型,默認為MD5,支持HMAC-SHA256和MD5。注意此處需與統一下單的簽名類型一致paySign: finalsign//簽名,詳見簽名生成算法https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3}, true);});}});
});
在index.js最后一行加入
app.use(API_PATH, require(`.${API_PATH}/demo/wxpay`));//微信支付
運行
node index
?打完收工!
總結
以上是生活随笔為你收集整理的【全网唯一】全网唯一能够跑通的,跑不通你来找我~用node.js完成微信支付下单功能,且只需要一个文件wxpay.js就解决业务流程的node.js程序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IDEA设置单击左侧项目文件,自动在右侧
- 下一篇: 【绝对靠谱】Vue生成二维码Qrcode