nodejs -- 從零開始對(duì)接微信支付(一無(wú)所有,只有執(zhí)業(yè)執(zhí)照開始)

無(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--

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容