微信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 相关文章推荐
一个XML格式数据转换为图表的例子
Feb 09 Javascript
FileUpload上传图片(图片不变形)
Aug 05 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
Dec 04 Javascript
JavaScript动态添加事件之事件委托
Jul 12 Javascript
Bootstrap图片轮播效果详解
Oct 17 Javascript
Angular实现的简单查询天气预报功能示例
Dec 27 Javascript
angular4 JavaScript内存溢出问题
Mar 06 Javascript
jQuery中的for循环var与let的区别
Apr 21 jQuery
jQuery+ajax实现批量删除功能完整示例
Jun 06 jQuery
js中值引用和地址引用实例分析
Jun 21 Javascript
javascript面向对象创建对象的方式小结
Jul 29 Javascript
Vue中component标签解决项目组件化操作
Sep 04 Javascript
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
比特率,大家看看这个就不用收音机音质去比MP3音质了
2021/03/01 无线电
PHP获取一年有几周以及每周开始日期和结束日期
2015/08/06 PHP
全面解读PHP的人气开发框架Laravel
2015/10/15 PHP
实例讲解php实现多线程
2019/01/27 PHP
javascript 图片裁剪技巧解读
2012/11/15 Javascript
一个页面放2段图片滚动代码出现冲突的问题如何解决
2012/12/21 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
2013/05/14 Javascript
解决Extjs4中form表单提交后无法进入success函数问题
2013/11/26 Javascript
巧用局部变量提升javascript性能
2014/02/24 Javascript
JS中使用DOM来控制HTML元素
2016/07/31 Javascript
基于jQuery实现选项卡效果
2017/01/04 Javascript
JavaScript校验Number(4,1)格式的数字实例代码
2017/03/13 Javascript
Node.js学习教程之HTTP/2服务器推送【译】
2017/10/31 Javascript
解决vue+webpack打包路径的问题
2018/03/06 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
2018/04/18 jQuery
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
js加减乘除精确运算方法实例代码
2021/01/17 Javascript
跟老齐学Python之Python文档
2014/10/10 Python
python安装Scrapy图文教程
2017/08/14 Python
Python3中的列表生成式、生成器与迭代器实例详解
2018/06/11 Python
Linux下Pycharm、Anaconda环境配置及使用踩坑
2018/12/19 Python
OpenCV+Python识别车牌和字符分割的实现
2019/01/31 Python
python 列表中[ ]中冒号‘:’的作用
2019/04/30 Python
解决pycharm安装第三方库失败的问题
2020/05/09 Python
html5 Canvas画图教程(1)—画图的基本常识
2013/01/09 HTML / CSS
HTML5之tabindex属性全面解析
2016/07/07 HTML / CSS
MAC Cosmetics官方网站:魅可专业艺术彩妆
2019/04/10 全球购物
What is EJB
2016/07/22 面试题
大学生评语大全
2014/04/18 职场文书
文明礼貌演讲稿
2014/05/12 职场文书
政府个人对照检查材料思想汇报
2014/10/08 职场文书
会议邀请函
2015/01/30 职场文书
2015年国庆节慰问信
2015/03/23 职场文书
矛盾论读书笔记
2015/06/29 职场文书
珍惜时间的诗歌赏析
2019/08/23 职场文书
php解析非标准json、非规范json的方式实例
2022/05/10 PHP