無(wú)營(yíng)業(yè)執(zhí)照, 其實(shí)也可以實(shí)現(xiàn),就是比較麻煩,走的是黑科技路線, 參考payjs, 這個(gè)只要付三百塊錢就可以, 不需要自己去折騰, 灰產(chǎn)請(qǐng)繞道。
nodejs純?cè)樱?可以直接copy使用,沒(méi)有框架包袱。
nodejs微信支付最佳實(shí)踐
nodejs微信支付源碼
nodejs微信支付代碼、例子
因?yàn)槲抑Ц秾氁彩怯玫暮诳萍迹?所以無(wú)法透露, 我們講講如何nodejs如何實(shí)現(xiàn)微信支付, 從申請(qǐng)支付開始(無(wú)公眾號(hào)等)。
1: 微信支付申請(qǐng)
這一步是免費(fèi)的。
https://pay.weixin.qq.com 點(diǎn)擊進(jìn)入如下頁(yè)面

點(diǎn)擊成為商家
進(jìn)入如下鏈接
https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal
然后掃碼申請(qǐng)就可以了。
注意1, 如果是個(gè)體戶然后經(jīng)營(yíng)線上商城是沒(méi)有對(duì)應(yīng)欄目的, 隨便選一個(gè).6欄目的就可以。(為什么不選擇更低的?, 因?yàn)楸徊榈搅撕苈闊┡叮?其他的好說(shuō))
注意2: 遇到問(wèn)題別用微信客服, 因?yàn)槟愕纫惠呑铀麄冞€是再正在派對(duì)中。(我掛了兩天, 還在接入, 哦, 提示語(yǔ)一直時(shí)還有十個(gè)人排隊(duì))
申請(qǐng)成功后微信是沒(méi)有指導(dǎo)你怎么怎么搞得, 我看對(duì)接文檔說(shuō)需要上面需要公眾號(hào)id, 所以我們需要一個(gè)公眾號(hào)。
2: 注冊(cè)公眾號(hào)
https://mp.weixin.qq.com 進(jìn)入公眾號(hào)注冊(cè), 服務(wù)號(hào)和訂閱號(hào)都可以, 我推薦用服務(wù)號(hào), 權(quán)限多, 并且不會(huì)被收納起來(lái)(用戶尋找入口難)。
然后根據(jù)提示操作, 看運(yùn)氣多久審核完成
3: 復(fù)制appid跟申請(qǐng)appSecret
開發(fā)者中心->配置項(xiàng)
4:申請(qǐng)微信商戶平臺(tái)API密鑰、平臺(tái)證書
傳送門 https://pay.weixin.qq.com/index.php/core/cert/api_cert
平臺(tái)證書就是p12

5, 利用現(xiàn)成的輪子對(duì)接支付
tip: 順便復(fù)制下商戶號(hào)
npm install weixin-pay
去新建pay得公共文件導(dǎo)出這幾個(gè)對(duì)象
var wxpayInfo = {
appid: 'wx**打碼**8',
mch_id: '1**打碼**1',
}
var wxMp = {
appid: 'wx**打碼**8',
appSecret: '4567**打碼**8',
}
var wxpay = WXPay({
...wxpayInfo,
partner_key: 'uiiwx**打碼**8', //微信商戶平臺(tái)API密鑰
pfx: fs.readFileSync('./wx/**打碼**.p12'), //微信商戶平臺(tái)證書
})
假設(shè)配置得叫Config。
公眾號(hào)支付
Config.wxpay.getBrandWCPayRequestParams({
openid,
body,
detail,
out_trade_no,
// 微信金額是以分做單位
total_fee: amount * 100,
spbill_create_ip,
notify_url: 'http://**打碼**'
}, async (err, result) => {
// CODE
// **打碼**
})
但是我們發(fā)現(xiàn) 還有參數(shù)沒(méi)有, 對(duì)就是openid, 公眾號(hào)是不支持掃碼, 包括二維碼圖片展示都不可以,你都無(wú)法長(zhǎng)按掃碼(為了增加真實(shí)性,我做了親測(cè), 微信屏蔽了網(wǎng)頁(yè)得微信協(xié)議, 也就是你無(wú)法使用原生支付[原生支付跟掃碼可以跳過(guò)openid])
掃碼支付
wxpay.createUnifiedOrder({
body: '掃碼支付測(cè)試',
out_trade_no: '20140703'+Math.random().toString().substr(2, 10),
total_fee: 1,
spbill_create_ip: '192.168.2.210',
notify_url: 'http://wxpay_notify_url',
trade_type: 'NATIVE',
product_id: '1234567890'
}, function(err, result){
console.log(result);
})
但是我們肯定要做微信網(wǎng)頁(yè)支付,所以,公眾號(hào)支付是必須的。
6: 獲取CODE
先附上微信官方鏈接,理解能力好的不需要看下面的了
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
1: 先到公眾平臺(tái)官網(wǎng)中的“開發(fā) - 接口權(quán)限 - 網(wǎng)頁(yè)服務(wù) - 網(wǎng)頁(yè)帳號(hào) - 網(wǎng)頁(yè)授權(quán)獲取用戶基本信息”的配置選項(xiàng)中,修改授權(quán)回調(diào)域名。(不需要寫http、https協(xié)議)
注意: OAuth2.0鑒權(quán)的域名需要精確到具體路徑. # 也算,別以為hash模式就萬(wàn)事大吉。
2: 獲取code
在頁(yè)面進(jìn)行轉(zhuǎn)跳。
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_base &state=STATE#wechat_redirect
把redirect_uri跟appid改下就可以。如果需要xxxxx, 用戶信息(會(huì)彈出一個(gè)用戶確定窗口),把scope改成snsapi_userinfo
參考下我的代碼
// 微信環(huán)境,未授權(quán)的進(jìn)入靜默授權(quán),并記錄openid到數(shù)據(jù)庫(kù) (支付必須使用openid, 微信里面的網(wǎng)頁(yè)被微信封了二維碼和原生支付)
;(async () => {
// 用戶是否授權(quán)了微信
let wxOpenidInfo = await Config.wxOpenidGet()
// 分隔符,判斷回調(diào)
,state = 'gou_weixin_return_code__' + Config.wxBase.appid
// 獲取code url
,getCodeUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${Config.wxBase.appid}&redirect_uri=${Config.wxBase.redirect_uri |> encodeURI}&response_type=code&scope=snsapi_base&state=${state}#wechat_redirect`
// 獲取到的code
,codeParams = 'code' |> Config.getUrlParams
// 獲取openid結(jié)果
,openidResult
// --------------return 已授權(quán)的用戶
if(wxOpenidInfo)
return
//------------- 未授權(quán), 未收到code
if(location.href.indexOf(state) < 0){
// 去獲取code
location.href = getCodeUrl
return
}
// -----------未授權(quán), 已收到code
openidResult = await Http.user['wxGetOpenid']({code: codeParams})()
// 換取openid失敗
if(openidResult.code !== 0){
openidResult.code === 1 && xxy.toast(openidResult.msg)
return
}
// 換取成功, 儲(chǔ)存到openid本地一份, 此時(shí)完成后就是已授權(quán)了
openidResult.msg |> Config.wxSaveOpenid
}) |> Config.isWx
上面有xxy(這里用到了彈窗, 你改成你的), HTTP, 改成你的請(qǐng)求,Config,幾個(gè)基本配置改成你自己的。
附上兩個(gè)函數(shù)代碼,判斷是否在微信端跟是否授權(quán)
isWx(cb, err){
// 微信環(huán)境
if(ua.match(/MicroMessenger/i) == 'micromessenger'){
cb && cb()
}else{
err && err()
}
}
// 用戶是否授權(quán)了微信
wxOpenidGet(){
return new Promise((resolve) => {
if(localStorage.openid && localStorage.openid.length > 5){
resolve(true)
return
}
resolve(false)
})
}
7: 換取openid
廢話少說(shuō), 直接上代碼, 全是原生實(shí)現(xiàn), 直接copy就可以使用
var https = require('https')
exports.wxGetOpenid = (params) => new Promise(async (resolve, reject) => {
let {code} = params
var url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${Config.wxMp.appid}&secret=${Config.wxMp.appSecret}&code=${code}&grant_type=authorization_code`
https.get(url, (res) => {
var datas = ''
res.on('data', (d) => {
datas += d
})
res.on('end', (d) => {
var result = JSON.parse(datas)
if(result.errcode){
resolve({code: 1, msg: result.errmsg})
return
}
if(result.openid){
resolve({code: 0, msg: result.openid})
return
}
})
})
.on('error', (e) => {
resolve({code: 0, msg: '服務(wù)器異常'})
// ** 打碼 **
})
})
8: 對(duì)接回調(diào)處理, 退款處理
拿到openid后完成支付功能, 在第5步完成
回調(diào)
var util = require('weixin-pay/lib/util.js')
var xml = Object.keys(body)[0]
util.parseXML(xml, async (err, msg) => {
var pkg = JSON.parse(JSON.stringify(msg))
let sign = msg.sign
delete pkg.sign
if (sign !== Config.wxpay.sign(pkg)) {
// 簽名失敗,請(qǐng)求不是來(lái)自于微信服務(wù)器。
// **打碼**
return
}
// CODE
})
退款
var params = {
...Config.wxpayInfo,
op_user_id: Config.wxpayInfo.mch_id,
out_refund_no: '20140703'+Math.random().toString().substr(2, 10),
total_fee: '1', //原支付金額 (以分為單位)
refund_fee: '1', //退款金額
transaction_id: '微信訂單號(hào)'
};
wxpay.refund(params, function(err, result){
console.log('refund', arguments);
});
OK
參考鏈接:
https://github.com/tvrcgo/weixin-pay
http://mysy.vip
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
--END--