无营业执照, 其实也可以实现,就是比较麻烦,走的是黑科技路线, 参考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--