论微信公众号支付到底有多坑

先吐个嘈,接个微信支付,断断续续一个多星期。。。。。。要是赶着上线的话,黄花菜都凉了,哪里错了根本不给提示。。。

好了,我们来梳理一下介入流程,其实极其简单!

首先要区分的是你接的是不是公众号支付:公众号支付指的是在微信公众号或者微信浏览器内调起H5支付,不要跟其他浏览器的H5支付混淆了。

流程:申请公众号---服务号-----申请支付商户----在线签署协议,这个时商家自己搞,不过需要强调的是,有些商家有开发者商户和运营商户,一定要用跟服务号进行绑定的商户。

开发步骤:

商户:在商户平台设置公众号支付目录, 在产品中心----开发配置

公众号:业务域名,请自行查看对域名的要求。     JS 安全域名    授权回调页面域名  如果没有特殊要求,都写备案域名就好了。

以上就把开发配置做完了。

下面就是代码开发了。

第一步:获取code。这个需要将当前页面跳转到微信的授权页面

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe????????&redirect_uri=http%3a%2f%2f???????.com%2fchargeforcards&response_type=code&scope=snsapi_base&state=123#wechat_redirect

,有两种,一种是弹出一个确认框的,大家在登录第三方平台时,给授权权限的那个就是。另外一种是 微信直接给你授权,但是不能给你提供用户多余的信息。支付我们直接用简单的直接授权方式。 上边的地址 appid为服务号appid ,redirect_uri就是你想跳转到的地址,即前端的路由地址。response 就是code  scope选择base直接授权,state随便写就行。

这样,当页面跳转完之后,当前页面url中就有了code了,接下来就是从url中拿到code

function getQueryString(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
    var r = window.location.search.substr(1).match(reg);
    if (r != null) return unescape(r[2]); return null;
    }

拿到code之后,我们就时下一步的openid了,要在服务器端进行操作了,如果你是一个前端,学习下服务器后端~~~

这一步骤,需要code

https://api.weixin.qq.com/sns/oauth2/access_token?appid=wxedf69f9306bc876a&secret=9c7e8cf23f5735ba30e16e326baa9af2&code="+code+"&grant_type=authorization_code"

从response中得到openid

之后就是调起微信统一支付接口了,坑就来了。。。。。

里面需要好多参数,一定仔细读参数要求,否则,奇坑无比。

强调 type  JSAPI   还有opid 时必传参数,仔细看

ip通过ip = req.headers['x-real-ip'] ? req.headers['x-real-ip'] : req.ip.replace(/::ffff:/, ''); 这是nodejs的写法,其他语言,请自行查找写法。

之后,就时签名算法了,签名时区分大小写的,请注意!

首先,先将参数字典排序,排序完之后,拼接,拼接完之后进行签名算法,默认为MD5,下面时nodejs的签名算法,其他语言请自行书写:

function raw(args) {
  var keys = Object.keys(args);
  keys = keys.sort()
  var newArgs = {};
  keys.forEach(function(key) {
    // newArgs[key.toLowerCase()] = args[key];
    newArgs[key] = args[key];
  });


  var string = '';
  for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k];
  }
  string = string.substr(1);
  return string;
};


function paysign(appid1, attach1, body1, mch_id1, nonce_str1, notify_url1, openid1, out_trade_no1, spbill_create_ip1, total_fee1, trade_type1) {
  var ret = {
    appid: appid1,
    attach: attach1,
    body: body1,
    mch_id: mch_id1,
    nonce_str: nonce_str1,
    notify_url: notify_url1,
    openid: openid1,
    out_trade_no: out_trade_no1,
    spbill_create_ip: spbill_create_ip1,
    total_fee: total_fee1,
    trade_type: trade_type1
  };
  var string = raw(ret);
  var key = "Tuokengzhilu******666666"  //这个key在商户API设置,数字字母大小写,32位
  string = string + '&key=' + key; //key为在微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
  console.log(string + '--------1111111-------');
  var crypto = require('crypto');
  return crypto.createHash('md5').update(string).digest('hex').toUpperCase();
  // sign=MD5(stringSignTemp).toUpperCase()
};

签名签好之后,你就可以将内容填入xml中了,JS可以选择字符串拼接。

然后将XML   post  到https://api.mch.weixin.qq.com/pay/unifiedorder

在这个过程中,可能会出现一直是签名错误,如果你反复确认,什么都对,那就去重置一下APIkey,注意数字,字母大小写结合的32位

之后,奇迹就发生了,你获得了SUCCESS,得到了prepay_id,那么到这个时候,已经完成了一大半了,马上就成功了~~~

微信返回给我们的是xml格式,我nodejs express 将xml转化为json

xml2js.parseString(resorder.data, {

          explicitArray: false
        }, function(err, json) {})

这样我们得到了prepay_id

下边就是微信内调起H5支付了,不过这里还有一个小坑。。。这里传的sign并不是微信返回给我们的sign,而是我们根据前面sign生成规则,再来生成一次,是不是坑!!!!虽然,参数文档里也时那么写的,细想想,人家确实没说是微信返回的,那边还写了签名生成规则~~~~

怨自己吧,,,,

之后将例子给的调起函数放到前端适当位置,将参数填写正确,微信的公众号支付就完成了。。。。。。

庆祝一下吧!!!!!!!!!!


你可能感兴趣的:(微信,H5,node)