nodejs -- 从零开始对接微信支付(一无所有,只有执业执照开始)

无营业执照, 其实也可以实现,就是比较麻烦,走的是黑科技路线, 参考payjs, 这个只要付三百块钱就可以, 不需要自己去折腾, 灰产请绕道。

nodejs纯原生例子, 可以直接copy使用,没有框架包袱。
nodejs微信支付最佳实践
nodejs微信支付源码
nodejs微信支付代码、例子
因为我支付宝也是用的黑科技, 所以无法透露, 我们讲讲如何nodejs如何实现微信支付, 从申请支付开始(无公众号等)。

1: 微信支付申请

这一步是免费的。

https://pay.weixin.qq.com 点击进入如下页面

点击成为商家
进入如下链接
https://pay.weixin.qq.com/index.php/apply/applyment_home/guide_normal
然后扫码申请就可以了。
注意1, 如果是个体户然后经营线上商城是没有对应栏目的, 随便选一个.6栏目的就可以。(为什么不选择更低的?, 因为被查到了很麻烦哦, 其他的好说)
注意2: 遇到问题别用微信客服, 因为你等一辈子他们还是再正在派对中。(我挂了两天, 还在接入, 哦, 提示语一直时还有十个人排队)

申请成功后微信是没有指导你怎么怎么搞得, 我看对接文档说需要上面需要公众号id, 所以我们需要一个公众号。

2: 注册公众号

https://mp.weixin.qq.com 进入公众号注册, 服务号和订阅号都可以, 我推荐用服务号, 权限多, 并且不会被收纳起来(用户寻找入口难)。
然后根据提示操作, 看运气多久审核完成

3: 复制appid跟申请appSecret

开发者中心->配置项

4:申请微信商户平台API密钥、平台证书

传送门 https://pay.weixin.qq.com/index.php/core/cert/api_cert
平台证书就是p12

5, 利用现成的轮子对接支付

tip: 顺便复制下商户号

npm install weixin-pay

去新建pay得公共文件导出这几个对象

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', //微信商户平台API密钥
    pfx: fs.readFileSync('./wx/**打码**.p12'), //微信商户平台证书
})

假设配置得叫Config。

公众号支付

Config.wxpay.getBrandWCPayRequestParams({
        openid,
        body,
        detail,
        out_trade_no,
        // 微信金额是以分做单位
        total_fee: amount * 100,
        spbill_create_ip,
        notify_url: 'http://**打码**'
    },  async (err, result) => {
        // CODE  
                // **打码**
    })

但是我们发现 还有参数没有, 对就是openid, 公众号是不支持扫码, 包括二维码图片展示都不可以,你都无法长按扫码(为了增加真实性,我做了亲测, 微信屏蔽了网页得微信协议, 也就是你无法使用原生支付[原生支付跟扫码可以跳过openid])
扫码支付

wxpay.createUnifiedOrder({
    body: '扫码支付测试',
    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);
})

但是我们肯定要做微信网页支付,所以,公众号支付是必须的。

6: 获取CODE

先附上微信官方链接,理解能力好的不需要看下面的了
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
1: 先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。(不需要写http、https协议)
注意: OAuth2.0鉴权的域名需要精确到具体路径. # 也算,别以为hash模式就万事大吉。
2: 获取code
在页面进行转跳。
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, 用户信息(会弹出一个用户确定窗口),把scope改成snsapi_userinfo

参考下我的代码

// 微信环境,未授权的进入静默授权,并记录openid到数据库 (支付必须使用openid, 微信里面的网页被微信封了二维码和原生支付)
;(async () => {
  // 用户是否授权了微信
  let wxOpenidInfo = await Config.wxOpenidGet()
  // 分隔符,判断回调
  ,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结果
  ,openidResult

  // --------------return 已授权的用户
  if(wxOpenidInfo)
    return
  //------------- 未授权, 未收到code
  if(location.href.indexOf(state) < 0){
    // 去获取code
    location.href = getCodeUrl
    return
  }
  // -----------未授权, 已收到code
  openidResult = await Http.user['wxGetOpenid']({code: codeParams})()
  // 换取openid失败
  if(openidResult.code !== 0){
    openidResult.code === 1 && xxy.toast(openidResult.msg)
    return
  }
  // 换取成功, 储存到openid本地一份, 此时完成后就是已授权了
  openidResult.msg |> Config.wxSaveOpenid
}) |> Config.isWx

上面有xxy(这里用到了弹窗, 你改成你的), HTTP, 改成你的请求,Config,几个基本配置改成你自己的。
附上两个函数代码,判断是否在微信端跟是否授权

  isWx(cb, err){
        // 微信环境
        if(ua.match(/MicroMessenger/i) == 'micromessenger'){
            cb && cb() 
        }else{
            err && err()
        }
    }
    // 用户是否授权了微信
    wxOpenidGet(){
        return new Promise((resolve) => {
            if(localStorage.openid && localStorage.openid.length > 5){
                resolve(true)
                return
            }
            resolve(false)
        })
    }

7: 换取openid

废话少说, 直接上代码, 全是原生实现, 直接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: '服务器异常'})
          // ** 打码 **
    })
})

8: 对接回调处理, 退款处理

拿到openid后完成支付功能, 在第5步完成

回调

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)) {
            // 签名失败,请求不是来自于微信服务器。
                        // **打码**
            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: '微信订单号'
};

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

你可能感兴趣的:(nodejs -- 从零开始对接微信支付(一无所有,只有执业执照开始))