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

发布时间 - 2026-01-10 22:25:06    点击率:

首先介绍一下我在调用微信支付接口使用的是 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,但并不保证它绝对可靠。
 }
});

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


# 微信JSAPI支付  # 微信支付  # 微信JSAPI  # Java通过JsApi方式实现微信支付  # 微信支付之JSAPI公众号支付详解  # java对接微信支付之JSAPI支付(微信公众号支付)  # 微信小程序支付Jsapi下单Java版保姆级教程  # 商户  # 下单  # 我在  # 是否正确  # 不匹配  # 的是  # 客户端  # 您没有  # 随机数  # 也会  # 在这个  # 将在  # 均为  # 会在  # 这个问题  # 能在  # 帐号  # 可在  # 不存在  # 找了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何使用Gate和Policy进行授权?(权限控制)  Laravel如何使用Blade组件和插槽?(Component代码示例)  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  奇安信“盘古石”团队突破 iOS 26.1 提权  JavaScript如何实现音频处理_Web Audio API如何工作?  如何自己制作一个网站链接,如何制作一个企业网站,建设网站的基本步骤有哪些?  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  免费视频制作网站,更新又快又好的免费电影网站?  python中快速进行多个字符替换的方法小结  如何确认建站备案号应放置的具体位置?  高性价比服务器租赁——企业级配置与24小时运维服务  如何在IIS中新建站点并解决端口绑定冲突?  Thinkphp 中 distinct 的用法解析  在线制作视频网站免费,都有哪些好的动漫网站?  Python文本处理实践_日志清洗解析【指导】  Windows10电脑怎么设置虚拟光驱_Win10右键装载ISO镜像文件  如何在IIS中新建站点并配置端口与IP地址?  如何快速启动建站代理加盟业务?  如何快速打造个性化非模板自助建站?  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  如何在搬瓦工VPS快速搭建网站?  猎豹浏览器开发者工具怎么打开 猎豹浏览器F12调试工具使用【前端必备】  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  教你用AI将一段旋律扩展成一首完整的曲子  如何快速搭建FTP站点实现文件共享?  如何在局域网内绑定自建网站域名?  如何用狗爹虚拟主机快速搭建网站?  高端智能建站公司优选:品牌定制与SEO优化一站式服务  学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?  laravel怎么使用数据库工厂(Factory)生成带有关联模型的数据_laravel Factory生成关联数据方法  DeepSeek是免费使用的吗 DeepSeek收费模式与Pro版本功能详解  Android滚轮选择时间控件使用详解  佛山企业网站制作公司有哪些,沟通100网上服务官网?  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  Laravel如何实现数据库事务?(DB Facade示例)  悟空识字怎么关闭自动续费_悟空识字取消会员自动扣费步骤  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  java中使用zxing批量生成二维码立牌  如何快速搭建高效WAP手机网站吸引移动用户?  如何用西部建站助手快速创建专业网站?  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门  黑客如何利用漏洞与弱口令入侵网站服务器?  如何快速生成专业多端适配建站电话?  瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口  详解Huffman编码算法之Java实现  Laravel Eloquent:优雅地将关联模型字段扁平化到主模型中  HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】