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


Posted in Javascript onJanuary 10, 2017

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

weixin.senparc SDK 官网:http://weixin.senparc.com/

先去下载下来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)先看看你的公众号微信支付设置是否正确。

关于如何配置微信支付:可以参考这个 http://jingyan.baidu.com/article/77b8dc7fef360d6174eab690.html

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,但并不保证它绝对可靠。
 }
});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
关于图片的预加载过程中隐藏未知的
Dec 19 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
Aug 14 Javascript
js对图片base64编码字符串进行解码并输出图像示例
Mar 17 Javascript
JS实现向表格行添加新单元格的方法
Mar 30 Javascript
学习JavaScript设计模式(接口)
Nov 26 Javascript
JQuery学习总结【二】
Dec 01 Javascript
JavaScript切换搜索引擎的导航网页搜索框实例代码
Jun 11 Javascript
JS 实现百度搜索功能
Feb 01 Javascript
基于React Native 0.52实现轮播图效果
Aug 25 Javascript
vue项目打包之开发环境和部署环境的实现
Apr 23 Javascript
vue监听浏览器原生返回按钮,进行路由转跳操作
Sep 09 Javascript
Vue如何实现变量表达式选择器
Feb 18 Vue.js
jQuery使用ajax方法解析返回的json数据功能示例
Jan 10 #Javascript
ajax实现动态下拉框示例
Jan 10 #Javascript
JavaScript三种绑定事件方式及相互之间的区别分析
Jan 10 #Javascript
详解使用Vue.Js结合Jquery Ajax加载数据的两种方式
Jan 10 #Javascript
JavaScript获取键盘按键的键码(参照表)
Jan 10 #Javascript
详解vue之页面缓存问题(基于2.0)
Jan 10 #Javascript
jQuery验证表单格式的使用方法
Jan 10 #Javascript
You might like
php daodb插入、更新与删除数据
2009/03/19 PHP
yii2利用自带UploadedFile实现上传图片的示例
2017/02/16 PHP
几个高效,简洁的字符处理函数
2007/04/12 Javascript
JavaScript表单常用验证集合
2008/01/16 Javascript
JQuery中$之选择器用法介绍
2011/04/05 Javascript
ajax 同步请求和异步请求的差异分析
2011/07/04 Javascript
Node.js开发指南中的简单实例(mysql版)
2013/09/17 Javascript
php显示当前文件所在的文件以及文件夹所有文件以树形展开
2013/12/13 Javascript
JavaScript中的eval()函数使用介绍
2014/12/31 Javascript
Uploadify上传文件方法
2016/03/16 Javascript
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
ES6记录异步函数的执行时间详解
2016/08/31 Javascript
JavaScript Drum Kit 指南(纯 JS 模拟敲鼓效果)
2017/07/23 Javascript
Vue+Flask实现简单的登录验证跳转的示例代码
2018/01/13 Javascript
使用p5.js临摹动态图形
2019/10/23 Javascript
JavaScript实现tab栏切换效果
2020/03/16 Javascript
Vue.js使用axios动态获取response里的data数据操作
2020/09/08 Javascript
Vue+Openlayers自定义轨迹动画
2020/09/24 Javascript
python中pygame模块用法实例
2014/10/09 Python
Python中的__SLOTS__属性使用示例
2015/02/18 Python
python实现简单ftp客户端的方法
2015/06/28 Python
python字典基本操作实例分析
2015/07/11 Python
Django Admin实现上传图片校验功能
2016/03/06 Python
Python RabbitMQ消息队列实现rpc
2018/05/30 Python
python开发实例之Python的Twisted框架中Deferred对象的详细用法与实例
2020/03/19 Python
Python列表去重复项的N种方法(实例代码)
2020/05/12 Python
python实现学生通讯录管理系统
2021/02/25 Python
Hotter Shoes英国官网:英伦风格,舒适的鞋子
2017/12/28 全球购物
Sneaker Studio法国:购买运动鞋
2018/06/08 全球购物
Three Graces London官网:英国奢侈品牌
2021/03/18 全球购物
后勤人员岗位职责
2013/12/17 职场文书
我未来的职业规划范文
2014/01/11 职场文书
幼儿园教师节活动方案
2014/02/02 职场文书
中职三好学生事迹材料
2014/08/24 职场文书
2014矛盾纠纷排查调处工作总结
2014/12/09 职场文书
MySQL索引失效的典型案例
2021/06/05 MySQL