最近碰到好几个搞nodejs的朋友问 微信支付应该怎么搞呢 博主就把项目中实际用的 简略的例子共享下 有问题可以通过emal联系我mac@niefengjun.cn
先下载包
npm install wechat-pay --save
初始化
var Payment = require('wechat-pay').Payment;var initConfig = { partnerKey: "<partnerkey>", appId: "<appid>", mchId: "<mchid>", notifyUrl: "<notifyurl>", pfx: fs.readFileSync("<location-of-your-apiclient-cert.p12>") };var payment = new Payment(initConfig);
所有参数都不是必须的,不过这样配置最省事。实际调用时候的参数若有同名会覆盖。
付个钱
var order = { body: '吮指原味鸡 * 1', attach: '{"部位":"三角"}', out_trade_no: 'kfc' ( new Date), total_fee: 10 * 100, spbill_create_ip: req.ip, openid: req.user.openid, trade_type: 'JSAPI'};payment.getBrandWCPayRequestParams(order, function(err, payargs){ res.json(payargs); });
注:
1. 页面的路径需要位于支付授权目录
下
2. 由于每次呼出支付界面,无论用户是否支付成功,out_trade_no 都会失效(OUT_TRADE_NO_USED),所以这里使用timestamp保证每次的id不同。业务逻辑中应该自行维护之
前端通过
WeixinJSBridge.invoke('getBrandWCPayRequest', payargs, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok"){ alert("支付成功"); // 这里可以跳转到订单完成页面向用户展示 }else{ alert("支付失败,请重试"); } });
来呼出微信的支付界面
接收微信付款确认请求
var middleware = require('wechat-pay').middleware; app.use('<notifyUrl>', middleware(initConfig).getNotify() .done(function(message, req, res, next) { var openid = message.openid; var order_id = message.out_trade_no; var attach = {}; try{ attach = JSON.parse(message.attach); }catch(e){} /** * 查询订单,在自己系统里把订单标为已处理 * 如果订单之前已经处理过了直接返回成功 */ res.reply('success'); /** * 有错误返回错误,不然微信会在一段时间里以一定频次请求你 * res.reply(new Error('...')) */}));
退个款
payment.refund({ out_trade_no: "kfc001", out_refund_no: 'kfc001_refund', total_fee: 10 * 100, refund_fee: 10 * 100}, function(err, result) { /** * 微信收到正确的请求后会给用户退款提醒 * 这里一般不用处理,有需要的话有err的时候记录一下以便排查 */ });
查询历史订单
payment.downloadBill({ bill_date: "20140913", bill_type: "ALL"}, function(err, data){ // 账单列表 var list = data.list; // 账单统计信息 var stat = data.stat; });
错误处理
在回调的Error上的以name做了区分,有需要可以拿来做判断
ProtocolError 协议错误,看看有没有必须要传的参数没传
BusinessError 业务错误,可以从返回的data里面看看错误细节
微信发起请求实例:
var Payment = require('wechat-pay').Payment; var wxpayconfig = require('../config').wxpayconfig; /* trade_type 支付类型 body 商品描述 attach 附加信息 out_trade_no 订单号 total_fee 金额 单位分 spbill_create_ip ip地址 openid openid */ function weixinorderpayment(trade_type, body, attach, out_trade_no, total_fee, spbill_create_ip, openid, callback) { var initConfig = { partnerKey: wxpayconfig.partnerKey, appId: wxpayconfig.appId, mchId: wxpayconfig.mchId, notifyUrl: wxpayconfig.notifyUrl, pfx: wxpayconfig.pfx }; var payment = new Payment(initConfig); //console.log('初始化',initConfig) ; var order = { body: body, attach: attach, out_trade_no: out_trade_no, total_fee: total_fee, spbill_create_ip: spbill_create_ip, openid: openid, trade_type: trade_type }; //console.log('order',JSON.stringify(order)) ; payment.getBrandWCPayRequestParams(order, function (err, payargs) { if (!err) { console.log('发起微信支付成功', order, err, payargs); callback(err, payargs) } else { console.log('发起支付出错', order, err, payargs); callback(err, payargs) } }); } exports.weixinorderpayment = weixinorderpayment;
微信相关配置
//微信支付配置 wxpayconfig exports.wxpayconfig = { partnerKey: "", appId: "", mchId: "", notifyUrl: “”, pfx: fs.readFileSync(process.cwd() "/cert/apiclient_cert.p12") }
微信收款实例
博主自己写的验证方法
/* 订单生成 sign //签名 trade_mode 交易类型 trade_state 交易状态 partner 商户号 bank_type 付款银行 bank_billno 银行订单号 total_fee 订单总金额 fee_type 币种 notify_id 通知id transaction_id 交易号 out_trade_no 商户订单号 time_end 支付完成时间 product_fee */ function notify_url(body) { if (body.xml) { var sign = body.xml.sign[0]; var sign1=body.xml; delete sign1.sign; var url= _toQueryString(sign1) "&key=" config.wxpayconfig.partnerKey ; var ret =md5(url).toUpperCase();//tool.getMd5(url).toUpperCase(); if (ret == sign) { return true; } else { return false; } } else { return false; } }
其实最关键的 就是根据微信支付提供xml验证合法性
其他的逻辑处理就显得很简单 当然了那个包也提供了方法 也可以用 博主还是愿意用自己的方式去处理 这样省心
你打算打赏多少钱呢?
(微信扫一扫)