最近碰到好几个搞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验证合法性
其他的逻辑处理就显得很简单 当然了那个包也提供了方法 也可以用 博主还是愿意用自己的方式去处理 这样省心
