GVKun编程网logo

微信支付开发-Senparc.Weixin.MP详解(微信支付开发教程)

3

对于想了解微信支付开发-Senparc.Weixin.MP详解的读者,本文将提供新的信息,我们将详细介绍微信支付开发教程,并且为您提供关于JAVA-微信支付开发、jfinal-weixin启动报错-找

对于想了解微信支付开发-Senparc.Weixin.MP详解的读者,本文将提供新的信息,我们将详细介绍微信支付开发教程,并且为您提供关于JAVA-微信支付开发、jfinal-weixin 启动报错-找不到或无法加载主类 com.jfinal.weixin.demo.WeixinConfig、Senparc.Weixin SDK v4.20.14 发布,微信 .NET SDK、Senparc.Weixin SDK v5.0 升级公告的有价值信息。

本文目录一览:

微信支付开发-Senparc.Weixin.MP详解(微信支付开发教程)

微信支付开发-Senparc.Weixin.MP详解(微信支付开发教程)

  公众号+微信支付 sdk:senparc.weixin.mp.dll

  企业号 SDK:Senparc.Weixin.QY.dll

  开放平台 SDK:Senparc.Weixin.Open.dll 

  官方地址:http://weixin.senparc.com/  

  当然,我们要完成公众号微信支付功能的开发,需要使用Senparc.Weixin.MP.dll这个DLL,查阅了一下官方提供的DEMO以及教程,并没有载入微信支付相关的说明,没办法,既然拿到源码了,自己找吧。

  打开Senparc.Weixin.MP.sln,根据英文文件夹名称的分类,可以初步判断,关于微信支付,被封装在TenPayLib文件夹中,但是我还发现,里面存在名称叫“TenPayLibV3”的文件夹,那如何选择呢?网上搜索了一下,得出这个结论:2014年9月10号之前申请的为v2版,之后申请的为v3版。我用来测试微信支付的服务号是在16年刚申请,并且通过验证的,那么果断使用V3吧。

  打开TenPayLibV3文件夹:

微信支付开发-Senparc.Weixin.MP详解

 这里发现多个类库,每一个都是做什么的呢?我们这里不一一叙述,感兴趣的朋友可以下载来看,每一个类的文件头都有功能说明与描述,对照微信官方支付说明,我们直接开始做支付。

  进入微信公众号,点击功能菜单中的微信支付:并相应点击 使用教程-公众号支付

微信支付开发-Senparc.Weixin.MP详解 微信支付开发-Senparc.Weixin.MP详解

 迅速对文档内容重温、浏览,以方便在Senparc.Weixin.MP.dll中查找相应的功能。

微信支付开发-Senparc.Weixin.MP详解

  先配置支付授权目录,添加支付测试白名单,支付目录只支持三个,并且域名必须经过ICP备案。授权目录的作用是,如果要发起微信支付请求,请求的链接地址必须在授权目录下,否则身份无效,支付不能成功。测试白名单中添加的个人微信号,才能完成微信支付测试目录支付的测试,不在白名单中人员发起支付申请,支付不能成功。

  配置完成后,如何调用呢?我们继续看官方说明:H5调起支付API  

  “在微信浏览器里面打开H5网页中执行JS调起支付。接口输入输出数据格式为JSON。

  注意:WeixinJSBridge内置对象在其他浏览器中无效。

  列表中参数名区分大小,大小写错误签名验证会失败。”

  OK,这里说明了几个事情,第一必须在微信浏览器进行;第二,参数区分大小写;第三,数据格式为JSON。

  官方说明,只要在页面中调用如下脚本,即可开启微信支付功能:

function onBridgeReady(){
   WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
           "appId" : "wx2421b1c4370ec43b",     //公众号名称,由商户传入     
           "timeStamp":" 1395712654",         //时间戳,自1970年以来的秒数     
           "nonceStr" : "e61463f8efa94090b1f366cccfbbb444", //随机串     
           "package" : "prepay_id=u802345jgfjsdfgsdg888",     
           "signType" : "MD5",         //微信签名方式:     
           "paySign" : "70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信签名 
       },
       function(res){     
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {}     // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。 
       }
   ); 
}
if (typeof WeixinJSBridge == "undefined"){
   if( document.addEventListener ){
       document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
   }else if (document.attachEvent){
       document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
       document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
   }
}else{
   onBridgeReady();
}
登录后复制

 我的调用代码:因为我要在点击按钮确认支付之后,在调用微信支付进行后续操作,把官方代码提出到方法中

function onBridgeReady() {
            WeixinJSBridge.invoke(
                'getBrandWCPayRequest', {
                    "appId": $('#APPID').val(),     //公众号名称,由商户传入     
                    "timeStamp": $('#Timestamp').val(),         //时间戳,自1970年以来的秒数     
                    "nonceStr": $('#Noncestr').val(), //随机串     
                    "package": $('#package').val(),
                    "signType": "MD5",         //微信签名方式:     
                    "paySign": $('#paySign').val() //微信签名 
                },
                function (res) {
                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                        //支付成功,后续自行处理
                        
                    }
                    else
                    {
                        //支付取消,或者其他错误,自行处理
                    }
                }
            );
        }
登录后复制

 好吧,那这堆参数是从哪来的,都是啥玩意儿?我们逐个分析一下:

  appId:这个做微信开发都应该知道,公众号在开发者菜单就能找到

  timeStamp:时间戳,官方描述为“自1970年以来的秒数”,不用担心,肯定能从支付类库里找到

  nonceStr:官方解释是随机串“e61463f8efa94090b1f366cccfbbb444”,靠啥玩意儿?详见随机数生成算法,原来就是一套加密规则和算法,做过URL请求接口的朋友应该知道,有些公司JSON串的签名方式和这比较类似。

  package:预支付ID,调用官方API统一下单接口可以获得

  signType:字符串"MD5"

  paySign:官方解释是微信签名“70EA570631E4BB79628FBCA90534C63FF7FADD89”,好吧,我忍了,在看下签名生成算法,看来和随机串一个鸟样

  到这里,官方的接口说明已经了解的很清楚了,那么下面就要解决调用微信支付的这几个参数了,通过Senparc.Weixin.MP.dll应该如何使用呢?既然需要先调用统一下单接口获取预支付订单ID,好吧,我们先来研究一下,如何获得这个ID吧。

  官方给出了详细说明,我们不在赘述,各参数研究按照上述接口的方式自行研究解决,唯一区别在于,调用官方接口需要传入一个XML,那很好办,拼接一下就可以了,预支付调用方法如下:

//这里通过官方的一个实体,用户自行使用,我这里是直接读取的CONFIG文件
private static Senparc.Weixin.MP.TenPayLibV3.TenPayV3Info tenPayV3Info = new Senparc.Weixin.MP.TenPayLibV3.TenPayV3Info(ConfigurationManager.AppSettings["corpId"], ConfigurationManager.AppSettings["corpSecret"], ConfigurationManager.AppSettings["mch_id"]
                    , ConfigurationManager.AppSettings["key"], ConfigurationManager.AppSettings["v3url"]);

        /// <summary>
        /// 微信预支付
        /// </summary>
        /// <param name="attach"></param>
        /// <param name="body"></param>
        /// <param name="openid"></param>
        /// <param name="price"></param>
        /// <param name="orderNum"></param>
        /// <returns></returns>
        public static string PayInfo(string attach, string body, string openid, string price, string orderNum = "1833431773763549")
        {
            RequestHandler requestHandler = new RequestHandler(HttpContext.Current);
            //微信分配的公众账号ID(企业号corpid即为此appId)
            requestHandler.SetParameter("appid", tenPayV3Info.AppId);
            //附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
            requestHandler.SetParameter("attach", attach);
            //商品或支付单简要描述
            requestHandler.SetParameter("body", body);
            //微信支付分配的商户号
            requestHandler.SetParameter("mch_id", tenPayV3Info.MchId);
            //随机字符串,不长于32位。
            requestHandler.SetParameter("nonce_str", TenPayUtil.GetNoncestr());
            //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
            requestHandler.SetParameter("notify_url", tenPayV3Info.TenPayV3Notify);
            //trade_type=JSAPI,此参数必传,用户在商户公众号appid下的唯一标识。
            requestHandler.SetParameter("openid", openid);
            //商户系统内部的订单号,32个字符内、可包含字母,自己生成
            requestHandler.SetParameter("out_trade_no", orderNum);
            //APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP。
            requestHandler.SetParameter("spbill_create_ip", "127.0.0.1");
            //订单总金额,单位为分,做过银联支付的朋友应该知道,代表金额为12位,末位分分
            requestHandler.SetParameter("total_fee", price);
            //取值如下:JSAPI,NATIVE,APP,我们这里使用JSAPI
            requestHandler.SetParameter("trade_type", "JSAPI");
            //设置KEY
            requestHandler.SetKey(tenPayV3Info.Key);

            requestHandler.CreateMd5Sign();
            requestHandler.GetRequestURL();
            requestHandler.CreateSHA1Sign();
            string data = requestHandler.ParseXML();
            requestHandler.GetDebugInfo();

            //获取并返回预支付XML信息
            return TenPayV3.Unifiedorder(data);
        }
    }
登录后复制

好的,拿到预支付订单的返回数据,一切又都好办了,根据返回参数的不同,自行解决,我们只关心调用正确的过程,操作继续,在返回的正确XML数据中,我们获取到了

<![CDATA[wx201411101639507cbf6ffd8b0779950874]]></prepay_id>(官方示例),好的,开始在页面做支付吧!</p><p>这里,我封装了一个实体,用来传输常用的数据,当然,各位也可以参考Senparc.Weixin.MP.dll提供的实体类。</p><pre>public class ShareInfo { string corpId = string.Empty; public string CorpId { get { return corpId; } set { corpId = value; } } string ticket = string.Empty; public string Ticket { get { return ticket; } set { ticket = value; } } string noncestr = string.Empty; public string Noncestr { get { return noncestr; } set { noncestr = value; } } string timestamp = string.Empty; public string Timestamp { get { return timestamp; } set { timestamp = value; } } private string paySign = string.Empty; public string PaySign { get { return paySign; } set { paySign = value; } } private string package = string.Empty; public string Package { get { return package; } set { package = value; } } }
登录后复制

我们继续,来看一下支付接口需要用到的参数如何获取:

public static ShareInfo GetPayInfo(string prepayid)
        {
            shareInfo = new ShareInfo();
            //检查是否已经注册jssdk
            if (!JsApiTicketContainer.CheckRegistered(corpId))
            {
                JsApiTicketContainer.Register(corpId, corpSecret);
            }
            JsApiTicketResult jsApiTicket = JsApiTicketContainer.GetTicketResult(corpId);
            JSSDKHelper jssdkHelper = new JSSDKHelper();
            shareInfo.Ticket = jsApiTicket.ticket;
            shareInfo.CorpId = corpId.ToLower();
            shareInfo.Noncestr = JSSDKHelper.GetNoncestr().ToLower();
            shareInfo.Timestamp = JSSDKHelper.GetTimestamp().ToLower();
            shareInfo.Package="prepay_id=" + prepayid.ToLower();

            RequestHandler requestHandler = new RequestHandler(HttpContext.Current);

            requestHandler.SetParameter("appId", shareInfo.CorpId);
            requestHandler.SetParameter("timeStamp", shareInfo.Timestamp);
            requestHandler.SetParameter("nonceStr", shareInfo.Noncestr);
            requestHandler.SetParameter("package", shareInfo.Package);
            requestHandler.SetParameter("signType", "MD5");

            requestHandler.SetKey(tenPayV3Info.Key);
            requestHandler.CreateMd5Sign();
            requestHandler.GetRequestURL();
            requestHandler.CreateSHA1Sign();
            shareInfo.PaySign = (requestHandler.GetAllParameters()["sign"]).ToString();
            return shareInfo;
        }
登录后复制

这样,支付接口需要用到的参数,就都封装在ShareInfo里了,好吧,调用之后,我们回到页面的后置代码中,或者你采用的ORM对应代码中去,将参数输出到页面

//处理页面支付调用信息
                    ShareInfo shareInfo = TenPayModule.GetPayInfo(prepayid);
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"Noncestr\" runat=\"server\" value=\"{0}\" />", shareInfo.Noncestr));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"Timestamp\" runat=\"server\" value=\"{0}\" />", shareInfo.Timestamp));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"APPID\" runat=\"server\" value=\"{0}\" />", shareInfo.CorpId));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"paySign\" runat=\"server\" value=\"{0}\" />", shareInfo.PaySign));
                    System.Web.HttpContext.Current.Response.Write(string.Format("<input type=\"hidden\" id=\"package\" runat=\"server\" value=\"{0}\" />", shareInfo.Package));
登录后复制

好的,写到这里,大家参照上面的JS代码,就可以完成整个的支付功能了。最后,再附送一个生成商家订单号的方法,代码如下:

public string GetOrderNumber()
        {
            string Number = DateTime.Now.ToString("yyMMddHHmmss");
            return Number + Next(1000, 1).ToString();
        }
        private static int Next(int numSeeds, int length)
        {
            byte[] buffer = new byte[length]; 
            System.Security.Cryptography.RNGCryptoServiceProvider Gen = new System.Security.Cryptography.RNGCryptoServiceProvider();
            Gen.GetBytes(buffer);
            uint randomResult = 0x0; 
            for (int i = 0; i < length; i++)
            {
                randomResult |= ((uint)buffer[i] << ((length - 1 - i) * 8));
            }
            return (int)(randomResult % numSeeds);
        }
登录后复制

更多微信支付开发-Senparc.Weixin.MP详解 相关文章请关注PHP中文网!

JAVA-微信支付开发

JAVA-微信支付开发

怕忘记,记录一下。

首先。先看一边官方文档。https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

然后。微信公众号设置支付目录及授权域名

参照https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3

具体流程

用户发起支付请求 --> 重定向至微信授权 -->微信重定向至服务器接口 --> 创建订单信息跳转至支付页面 --> 统一下单 --> 等待用户支付,微信回调 --> 接口接收到微信通知 --> 完成支付流程

1.

 用户发起支付请求,重定向至微信提供的授权接口,需携带参数

appid 为 公众号的APP_ID

redirect_uri 为 微信处理完授权 回调接口 需要进行URLEncode

state 为微信回调时携带的参数 根据需要填写 我这里填的是手机号

https://open.weixin.qq.com/connect/oauth2/authorize?appid="+WeChatConfig.APP_ID+"&redirect_uri="+URLEncoder.encode(WeChatConfig.CALL_BACK_URL)+"&response_type=code&scope=snsapi_base&state="+phonenmb+"#wechat_redirect";

2.

用户同意授权会获得一个code,通过这个code获取授权的access_token

String code = request.getParameter("code");
AuthToken authToken = WeChatUtils.getTokenByAuthCode(code);

在这里,我预先根据用户信息创建了一个未支付订单,将订单信息传到支付页面

3.

用户查看支付信息,同意后进行支付,进入统一下单

主要是构建微信统一下单需要的各种参数

//构建微信统一下单需要的参数
Map<String,String> map = Maps.newHashMap();
//用户ID
map.put("userId",userId);
//用户标识openId
map.put("openId",openid);
//请求Ip地址
map.put("remoteIp",request.getRemoteAddr());
//调用统一下单service
Map<String,Object> resultMap = WeChatPayService.unifiedOrderJsApi(order,map);
//通信标识
String returnCode = (String) resultMap.get("return_code");
//交易标识
String resultCode = (String) resultMap.get("result_code");
//返回信息
String return_msg = (String) resultMap.get("return_msg");

成功的情况下微信会返回

returnCode=SUCCESS

result_code=SUCCESS

return_msg=OK

失败的话查看msg信息,对照开发文档

只有当returnCode与resultCode均返回“success”,才代表微信支付统一下单成功

然后需要将信息传递到支付页面

//微信公众号AppId
String appId = (String) resultMap.get("appid");
//当前时间戳
String timeStamp = WeChatUtils.getTimeStamp();
//统一下单返回的预支付id
String prepayId = "prepay_id="+resultMap.get("prepay_id");
//不长于32位的随机字符串
String nonceStr = WeChatUtils.getRandomStr(32);
//自然升序map
SortedMap<String,Object> signMap = Maps.newTreeMap();
signMap.put("appId",appId);
signMap.put("package",prepayId);
signMap.put("timeStamp",timeStamp);
signMap.put("nonceStr",nonceStr);
signMap.put("signType","MD5");
model.addAttribute("appId",appId);
model.addAttribute("timeStamp",timeStamp);
model.addAttribute("nonceStr",nonceStr);
model.addAttribute("prepayId",prepayId);
//获取签名
model.addAttribute("paySign",WeChatUtils.getSign(signMap));

其中最重要的是签名,签名没有问题,支付流程基本上就完成了

4.

支付成功回调接口

支付后,微信会发送成功信息到步骤1中的redirect_uri接口

返回信息 XML解析到Map中

验证其中return_code 是否为SUCCESS

是则支付成功,保存微信返回的支付数据,return_msg = OK

否则支付失败,打印一下return_msg 信息处理

 

 

 

jfinal-weixin 启动报错-找不到或无法加载主类 com.jfinal.weixin.demo.WeixinConfig

jfinal-weixin 启动报错-找不到或无法加载主类 com.jfinal.weixin.demo.WeixinConfig

今天想学习一下jfinal-weixin框架,下载后启动发现报错,本人的开发工具是IDEA 2018,具体错误为:

错误: 找不到或无法加载主类 com.jfinal.weixin.demo.WeixinConfig

如下图。

 

尝试了创建一个新类User再运行,却又是正常的。

 

此时如果让User类继承JfinalConfig再运行,又会报错。

不知道为什么会这样。请问有谁遇到这个问题吗?

 

Senparc.Weixin SDK v4.20.14 发布,微信 .NET SDK

Senparc.Weixin SDK v4.20.14 发布,微信 .NET SDK

Senparc.Weixin SDK v4.20.14 发布了。微信公众平台SDK Senparc.Weixin for C#,支持.NET Framework及.NET Core。已支持微信公众号、小程序、小游戏、企业号、企业微信、开放平台、微信支付、JSSDK、微信周边等全平台。 WeChat SDK for C#.

本次重要更新内容:

1、提供 RegisterServices 进行快捷注册(见Sample.sln代码)

2、优化MP微信支付方法

3、完善评论数据接口

4、持续优化 .net core 版本

5、Demo添加退款通知:TenPayV3Controller.cs/RefundNotifyUrl()

注意:

1、本次同时更新了 .NET 3.5/4.0/4.5/.NET Core 2.0 四个版本。

2、DLL帮助文档已经更新到最新版本

下载地址请关注发布主页更新。

来自:盛派网络小助手

Senparc.Weixin SDK v5.0 升级公告

Senparc.Weixin SDK v5.0 升级公告

  经过五年半的持续维护,Senparc.Weixin SDK 逐步丰满和完善,在升级的过程中,我们为基础库(Senparc.Weixin.dll)加入了许多通用的功能,例如加密/解密算法、通用缓存方法等等,许多这些方法其实和微信没有一对一的服务关系,而是具备了非常好的全局通用性。经过一系列的调研,也已经有许多开发者开始使用 Senparc.Weixin.dll 中的通用方法为全系统服务,而不只是用于开发微信。为此,盛派团队决定将 Senparc.Weixin.dll 中具备全系统通用性的功能分离出来,帮助大家提供一个更加完善高效的基础通用模块,并融入更多盛派尚未开源的模块和技术。与此同时, Senparc.Weixin.dll 中的方法也将更加集中地为微信各模块服务。希望大家继续关注和支持此次计划,关注并一起建设好 CO2NET!盛派一直在你身边!

  本次升级版本号为 v5.0,对 Senparc.Weixin.dll 进行了大范围的重构,将其与微信没有直接关系的基础方法(例如通用的加密/解密算法、通用缓存方法等),分离到 Senparc.CO2NET 项目,Senparc.Weixin SDK 将引用 Senparc.CO2NET 。

  CO2NET 项目也使用 Senparc.Weixin SDK 相同的 Apache License Version 2.0 协议开源,支持商用。全部代码开放,并将逐步提供更加完善的配套工具以及全套单元测试。

  关于移植的内容可以直接查看 CO2NET 的源码,在 Senparc.Weixin 中,移除代码的处理有两种方式:

  1.   继承 CO2NET 方法,并标注方法过期,例如:
        /// <summary>
        /// 微信日期处理帮助类
        /// </summary>
        [Obsolete("请使用 Senparc.CO2NET.Helpers.DateTimeHelper 类")]
        public class DateTimeHelper : CO2NET.Helpers.DateTimeHelper
        {
            
        }
    

     

  2.   删除方法,请大家升级的时候直接使用 Senparc.CO2NET.xx 取代 Senparc.Weixin.xx 相关代码,大家只要通过编译查看到命名空间、类或方法不存在的情况下,修改命名空间即可。

  决定保留(标记过期)或删除的原则是:如果过程简单,且一般不涉及深度的调试,或封装已经非常完善,则进行删除(彻底转移),否则使用向下兼容的方式暂时保留,今后会逐步删除。

 

  本次升级还对部分 Senparc.Weixin.dll 中的类做了调整,具体如下:

  1.  缓存方面:
    1. 删除 LocalObjectCacheStragety.cs (在 CO2NET 中已经提供)
    2. 删除 ILocalContainerCacheStrategy 接口
    3. 对应 Senparc.Weixin.Cache.Redis 和 Senparc.Weixin.Cache.Memcached 模块也对应做上述调整
    4. CacheStrategyFactory 重命名为 ContainerCacheStrategyFactory
    5. Senparc.Weixin.dll 中的缓存更专注地服务于各类 Container(数据容器),CacheStrategyFactory.RegisterObjectCacheStrategy() 重命名为 ContainerCacheStrategyFactory.RegisterContainerCacheStrategy()
    6. CacheStrategyFactory.GetobjectCacheStrategyInstance() 重命名为 ContainerCacheStrategyFactory.GetobjectCacheStrategyInstance()
    7. 将 Senparc.Weixin.Cache.Redis.RedLock 项目 完整迁移到 Senparc.CO2NET.Cache.Redis.RedLock 项目
    8. Senparc.Weixin.Cache.Memcached MemcachedServiceCollectionExtensions.AddSenparcmemcached() 更名为 AddWeixinMemcached()
    9. Senparc.Weixin.Register.ChangeDefaultCacheNamespace() 迁移到 Senparc.CO2NET 对应位置 
    10. 缓存实体修改不再使用属性通知,回到常规的手动 Get/Set 模式
    11. 如果现有系统使用分布式缓存,升级到 v5.0,请先删除原有 Accesstoken 等缓存,缓存格式已经发生变化
  2.  其他:
    1. .net framework 和 .net core 下的注册过程有所改变,请参考Demo。
    2. Senparc.Weixin.EntityUtility 命名空间改为 Senparc.CO2NET.Utilities;
    3. Senparc.Weixin.XmlUtility 命名空间改为 Senparc.CO2NET.Utilities;
    4. using Senparc.Weixin.MP.Entities.GoogleMap 命名空间改为 using Senparc.CO2NET.Helpers.GoogleMap (BaiduMap同理)

  PS:本文发布时,CO2NET 尚未正式发布,Senprc.Weixin v5.0.0 也正在 Developer-CO2NET 中不断更新,正式发布后将会合并到 master 分支。欢迎关注!本文将会根据项目进展持续更新。最后更新时间:2018-8-11。

 

我们今天的关于微信支付开发-Senparc.Weixin.MP详解微信支付开发教程的分享已经告一段落,感谢您的关注,如果您想了解更多关于JAVA-微信支付开发、jfinal-weixin 启动报错-找不到或无法加载主类 com.jfinal.weixin.demo.WeixinConfig、Senparc.Weixin SDK v4.20.14 发布,微信 .NET SDK、Senparc.Weixin SDK v5.0 升级公告的相关信息,请在本站查询。

本文标签: