微信支付里的 Nodejs 那些事

2016-02-04 09:21:36

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

你打算打赏多少钱呢?

打赏
(微信扫一扫)