当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 微信JSAPI支付操作需要注意的细节

微信JSAPI支付操作需要注意的细节

2019年03月31日  | 移动技术网IT编程  | 我要评论

首先介绍一下我在调用微信支付接口使用的是 weixin.senparc sdk,非常方便好用开源的一个微信开发sdk。

weixin.senparc sdk 官网:

先去下载下来senparc.weixin sdk。

在调起支付接口之前,需要先要调用统一下单接口,商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易回话标识后再在app里面调起支付。

 微信 jsapi支付 在这个目录下 senparc.weixin.mp.sample.controllers 找到jsapi支付。

public actionresult jsapi(string code, string state)
  {
   if (string.isnullorempty(code))
   {
    return content("您拒绝了授权!");
   }

   if (!state.contains("|"))
   {
    //这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下
    //实际上可以存任何想传递的数据,比如用户id,并且需要结合例如下面的session["oauthaccesstoken"]进行验证
    return content("验证失败!请从正规途径进入!1001");
   }
   try
   {


    //获取产品信息
    var statedata = state.split('|');
    int productid = 0;
    productmodel product = null;
    if (int.tryparse(statedata[0], out productid))
    {
     int hc = 0;
     if (int.tryparse(statedata[1], out hc))
     {
      var products = productmodel.getfakeproductlist();
      product = products.firstordefault(z => z.id == productid);
      if (product == null || product.gethashcode() != hc)
      {
       return content("商品信息不存在,或非法进入!1002");
      }
      viewdata["product"] = product;
     }
    }

    //通过,用code换取access_token
    var openidresult = oauthapi.getaccesstoken(tenpayv3info.appid, tenpayv3info.appsecret, code);
    if (openidresult.errcode != returncode.请求成功)
    {
     return content("错误:" + openidresult.errmsg);
    }

    string sp_billno = request["order_no"];
    if (string.isnullorempty(sp_billno))
    {
     //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
     sp_billno = string.format("{0}{1}{2}", tenpayv3info.mchid, datetime.now.tostring("yyyymmdd"),
      tenpayv3util.buildrandomstr(10));
    }
    else
    {
     sp_billno = request["order_no"];
    }

    var timestamp = tenpayv3util.gettimestamp();
    var noncestr = tenpayv3util.getnoncestr();

    var body = product == null ? "test" : product.name;
    var price = product == null ? 100 : product.price * 100;
    var xmldatainfo = new tenpayv3unifiedorderrequestdata(tenpayv3info.appid, tenpayv3info.mchid, body, sp_billno, price, request.userhostaddress, tenpayv3info.tenpayv3notify, tenpayv3type.jsapi, openidresult.openid, tenpayv3info.key, noncestr);
    var result = tenpayv3.unifiedorder(xmldatainfo);//调用统一订单接口

    //jssdkuipackage jspackage = new jssdkuipackage(tenpayv3info.appid, timestamp, noncestr,);
    var package = string.format("prepay_id={0}", result.prepay_id);

    viewdata["appid"] = tenpayv3info.appid;
    viewdata["timestamp"] = timestamp;
    viewdata["noncestr"] = noncestr;
    viewdata["package"] = package;
    viewdata["paysign"] = tenpayv3.getjspaysign(tenpayv3info.appid, timestamp, noncestr, package, tenpayv3info.key);

    return view();
   }
   catch (exception ex)
   {
    var msg = ex.message;
    msg += "<br>" + ex.stacktrace;
    msg += "<br>==source==<br>" + ex.source;

    if (ex.innerexception != null)
    {
     msg += "<br>===innerexception===<br>" + ex.innerexception.message;
    }
    return content(msg);
   }
  }

先在微信服务后台生成预支付交易单,获得预支付订单号。

先说说在统一下单这里遇到的坑。 

1.在统一下单的时候解析返回结果,一直出现以下问题:您没有jsapi支付权限

<xml>
<return_code><![cdata[fail]]></return_code>
<return_msg><![cdata[您没有jsapi支付权限]]></return_msg>
</xml>

1)先看看你的公众号微信支付设置是否正确。

关于如何配置微信支付:可以参考这个

2)检查你的授权目录是否正确,格式要这样,后面记得别漏了一个/   例如:http://test.cn/u/

3)检查需要传过去的账户参数,上公众号还有商户号检查你的账户参数是否正确。我在开发当中就出现,微信公众号商户号,appid 是分别不同两个公众号的,坑啊,找了好久,觉得不对劲,原来是给的配置参数密钥不对。

 这里详细说一下对应的参数:

mchid:商户号(必须配置,开户邮件中可查看),商户申请微信支付后,由微信支付分配的商户收款账号。
appid:微信开放平台审核通过的应用appid,appid是微信公众账号或开放平台app的唯一标识,在公众平台申请公众账号或者在开放平台申请app账号后,微信会自动分配对应的appid用于标识该应用。可在微信公众平台-->开发者中心查看,商户的微信支付审核通过邮件中也会包含该字段值.

key:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置),交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)-->账户设置-->api安全-->密钥设置.
appsecret:公众帐号secert(仅jsapi支付的时候需要配置, 登录公众平台,进入开发者中心可设置)

 2.在统一下单,解析返回来的结果我出现了商户号mch_id与appid不匹配这个问题

<xml>
<return_code><![cdata[fail]]></return_code>
<return_msg><![cdata[商户号mch_id与appid不匹配]]></return_msg>
</xml>

原因是我拿到的商户号不是这个公众号的。一定要检查是不是这个公众号的商户号。

 3.在统一下单,解析返回来的结果出现 appid and openid not match,appid和openid不匹配。

<xml>
<return_code><![cdata[fail]]></return_code>
<return_msg><![cdata[appid and openid not match]]></return_msg>
</xml>

原因是我这个用户的openid 不是这个公众号的 

4.在统一下单,解析返回来的结果出现 cdata[openid is invalid],openid无效

<xml>
<return_code><![cdata[fail]]></return_code>
<return_msg><![cdata[openid is invalid]]></return_msg>
</xml>

原因是,传过去不是有效的opendid。不小心看错了,把用户id 当做openid传过去了。

当统一下单成功,会返回以下格式的参数

<xml>
 <return_code><![cdata[success]]></return_code>
 <return_msg><![cdata[ok]]></return_msg>
 <appid><![cdata[wx2421b1c4370ec43b]]></appid>
 <mch_id><![cdata[10000100]]></mch_id>
 <nonce_str><![cdata[iitri8iabbblz1jc]]></nonce_str>
 <sign><![cdata[7921e432f65eb8ed0ce9755f0e86d72f]]></sign>
 <result_code><![cdata[success]]></result_code>
 <prepay_id><![cdata[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>
 <trade_type><![cdata[app]]></trade_type>
</xml>

解析获得预支付单号:

string prepayid = res.element("xml").element("prepay_id").value; //获取预支付订单号

给页面对应地参数

 viewdata["appid"] = tenpayv3info.appid;
    viewdata["timestamp"] = timestamp;
    viewdata["noncestr"] = noncestr;
    viewdata["package"] = package;
    viewdata["paysign"] = tenpayv3.getjspaysign(tenpayv3info.appid, timestamp, noncestr, package, tenpayv3info.key);

静态页面js调用:

wx.choosewxpay({
 timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timestamp字段名需大写其中的s字符
 noncestr: '', // 支付签名随机串,不长于 32 位
 package: '', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
 signtype: '', // 签名方式,默认为'sha1',使用新版支付需传入'md5'
 paysign: '', // 支付签名
 success: function (res) {
  if (res.err_msg == "get_brand_wcpay_request:ok") {//支付成功
 
  } else {
   //支付失败

  }
  // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
 }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网