首页 > 其他分享 >微信支付 V3 开发教程:初识 Senparc.Weixin.TenPayV3

微信支付 V3 开发教程:初识 Senparc.Weixin.TenPayV3

时间:2023-08-09 10:55:06浏览次数:40  
标签:Weixin 微信 Senparc TenPayV3 V3 支付

前言

  我在 9 年前发布了 Senparc.Weixin SDK 第一个开源版本,一直维护至今,如今 Stras 已经破 7K,这一路上得到了 .NET 社区的积极响应和支持,也受到了非常多的宝贵建议,甚至代码的 PR,目前累计的代码贡献者数量已经超过350人,在此表示衷心的感谢!

  我们也总在第一时间及时更新微信官方的各类接口,其中也包括微信支付。

  如今,针对已经发布了一段时间的“微信支付V3”,我们发布了一个完全重构后的全新版本:Senparc.Weixin.TenPayV3

  即使您没有开发过之前版本的微信支付也没有关系,因为这是一个完全崭新的开始,下面让我们开始最新一代的微信支付开发之旅。

 

关于微信支付 V2 和 V3

  从微信支付 V2 开始,我们第一时间上线了微信支付的功能,并在 2018 年正式分离出独立的 Senparc.Weixin.TenPay 作为微信支付的专用类库。

  微信支付自诞生以来进行了多次升级,其中比较容易混淆的是 V2 和 V3 两个版本号,在继续介绍之前,必须要做一个说明:

 目前社区中流传的“微信支付V3”实际上有 2  个版本的说法,一个 V3 是早期微信支付文档和接口进行了一轮升级,当时文档称其为 V3,后来又出来一个是微信支付官方对 API 的版本号进行了升级,也称其为 V3。

 后者的 V3 是真正意义上的“微信支付V3”,本次发布的模块也是针对这个 V3 而言的。

 由于历史原因,在先前发布的 Senparc.Weixin.TenPay 中也已经包含了 V2 和 V3 两个版本的命名,这里的 V3 就是早期文档的 V3,和“微信支付V3"的用法实际上有很大差别,但在功能上,基本上属于“微信支付V3”的子集。

 

快速开发-准备

  这里,我先从宏观演示一下 Senparc.Weixin.TenPayV3 的能力,通过网页演示和单元测试,完成最简单的鉴权、支付、退款和订单拉取功能(这些功能代表了几乎所有微信支付内部接口的形式),后续的章节将继续展开细节进行介绍。

  关于具体的接口和流程介绍,大家还是要耐心看官方的文档:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml,准备好微信支付V3所需的所有配置(V3 比之前的文档已经有了很大的飞跃,照着做基本上可以顺利完成)。下面的示例将以【普通商户+微信公众号JSAPI】这个组合进行展示,其他组合功能将在后续展开介绍。

  所有微信支付形式的 Sample 已经在开源项目中,默认使用 .NET 6 项目打开:https://github.com/JeffreySu/WeiXinMPSDK/tree/master/Samples/net6-mvc,为了方便测试,您可以直接下载或者克隆项目,机型测试,对应代码可以移植到自己的项目中。

  下载代码并打开上述目录中的 Senparc.Weixin.Sample.Net6.sln:

 

   其中,Controller 和 Views 的命名,为了和之前已经诞生的旧版本 V3 区分,我们暂时命名为 RealV3 :

 

  不需要修改任何代码,直接运行 Senparc.Weixin.Sample.NET6 项目,即可打开 Sample 首页:

 

  由于 Sample 集成了微信公众号、小程序、企业微信、微信支付,以及相关的缓存、模拟消息、文档下载等演示,所以看上去内容比较多,不用着急,Sample 配有详细的注释,并且对文件进行了分类,我们只需聚焦相关的部分。

 

 

 

开发第一步:引用 Nuget 包

  Sample 项目已经引用好了源码项目,如果您是全新的项目,可以直接引用 Senparc.Weixin.TenPayV3 包。

  方法一:使用 VS 管理器引用:

 

 

   方法二:直接在 .csproj 文件中引用(注意从 Senparc.Weixin.TenPayV3 网页查看最新版本):

    <ItemGroup>
        <PackageReference Include="Senparc.Weixin.TenPayV3" Version="0.3.500.2-preview2" />
    </ItemGroup>

 

开发第二步:设置微信支付信息

  在 Web 项目下面,找到 appsettings.json 文件,设置微信公众号和微信支付信息(其他信息根据说明,不需要的可以删除,或者保留原状),默认情况下只需要修改 SenparcWeixinSetting 节点下的“公众号”和“微信支付V3(新版)”的对应信息:

复制代码
  "SenparcWeixinSetting": {
    //注意:所有的字符串值都可能被用于字典索引,因此请勿留空字符串(但可以根据需要,删除对应的整条设置)!

    //微信全局
    "IsDebug": true,

    //以下不使用的参数可以删除,key 修改后将会失效

    //公众号
    "Token": "微信支付不需要",
    "EncodingAESKey": "微信支付不需要",
    "WeixinAppId": "MyWeixinAppId",
    "WeixinAppSecret": "MyWeixinAppSecret",

    //微信支付V3(新版)
    "TenPayV3_AppId": "MyWeixinAppId(同上)",
    "TenPayV3_AppSecret": "MyWeixinAppSecret(同上)",
    "TenPayV3_SubAppId": "",
    "TenPayV3_SubAppSecret": "",
    "TenPayV3_MchId": "xxxxxxxx",
    "TenPayV3_SubMchId": "", //子商户,没有可留空
    "TenPayV3_Key": "79xxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "TenPayV3_CertPath": "可留空", //支付证书物理路径,如:D:\\cert\\apiclient_cert.p12
    "TenPayV3_CertSecret": "可留空", //支付证书密码(原始密码和 MchId 相同)
    "TenPayV3_TenpayNotify": "http://sdk.weixin.senparc.com/TenpayV3/PayNotifyUrl", //http://YourDomainName/TenpayV3/PayNotifyUrl
    "TenPayV3_PrivateKey": "MIIExxxxxxxxxxxxxxxxx", //(新)证书私钥
    "TenPayV3_SerialNumber": "5Bxxxxxxxxxxxxxxxxxxxxxx", //证书序列号
    "TenPayV3_ApiV3Key": "xxxxxxxxxxxxxxxxxxxxxxxx", //(新)APIv3 密钥
    //如果不设置TenPayV3_WxOpenTenpayNotify,默认在 TenPayV3_TenpayNotify 的值最后加上 "WxOpen"
    "TenPayV3_WxOpenTenpayNotify": "http://sdk.weixin.senparc.com/TenpayV3/PayNotifyUrlWxOpen" //http://YourDomainName/TenpayV3/PayNotifyUrlWxOpen
  }
复制代码

说明:TenPayV3_CertPath 和 TenPayV3_CertSecret 是“文档版本V3"时期的遗留产物,在新V3中已经可以忽略

 

开发第三步:开发商品列表和 JSAPI 支付页面

  Sample 中提供了一个非常简约的商品列表和支付(详情)页:

功能 Controller文件 View文件
商品列表 TenPayRealV3Controller.cs / ProductList() /Views/TenPayRealV3/ProductList.cshtml

JSAPI支付页面

(商品详情)

TenPayRealV3Controller.cs / JsApi() /Views/TenPayRealV3/JsApi.cshtml

  具体业务的实现这里不再展开,相关 OAuth 授权的内容属于公众号开发的范畴,详细介绍可以参考《Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明》。

  这里着重讲一下 JSAPI 支付页面,为了方便演示,Sample 中把 JSAPI 和详情页放到了一起,实际项目中,详情页可以单独安排,此处 JSAPI 页面相当于是订单支付页面。

 

  Controller:

  先看 TenPayRealV3Controller.cs 下的 JsApi() 方法中的关键代码:

 

sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId/*10位*/, SystemTime.Now.ToString("yyyyMMddHHmmss"),
                        TenPayV3Util.BuildRandomStr(6));

  上述代码用于生成订单号(在文档中也叫 out_trade_no),订单号建议加上日期,方便排序,然后加上流水号或者随机数,根据具体项目情况而定。这里一定要确保唯一性。

 

var notifyUrl = TenPayV3Info.TenPayV3Notify.Replace("/TenpayV3/", "/TenpayRealV3/").Replace("http://", "https://");

  上述代码用于定义支付回调的地址,这里使用 Replace 是因为 Sample 中兼容了 2 套支付示范,实际开发过程中直接设置好 appsettings.json 中的参数即可。

 

TransactionsRequestData jsApiRequestData = new(TenPayV3Info.AppId, TenPayV3Info.MchId, name + " - 微信支付 V3", sp_billno, new TenpayDateTime(DateTime.Now.AddHours(1), false), null, notifyUrl, null, new() { currency = "CNY", total = price }, new(openId), null, null, null);

  上述代码用于组装访问预支付接口的参数。

 

var result = await _basePayApis.JsApiAsync(jsApiRequestData);

  上述代码用于调用预支付接口,获取 prepay_id,其中已经在构造函数中定义好的私有变量 _basePayApis(BasePayApis 类型),是执行相关一系列支付接口的实例化类:

        public TenPayRealV3Controller()
        {
            _tenpayV3Setting = Senparc.Weixin.Config.SenparcWeixinSetting.TenpayV3Setting;
            _basePayApis = new BasePayApis(_tenpayV3Setting);
        }

 

 

                if (result.VerifySignSuccess != true)
                {
                    throw new WeixinException("获取 prepay_id 结果校验出错!");
                }

  获取到 result 后,一定要进行签名验证(包括其他接口)!实际的签名和验证过程比较复杂,SDK 已经完全封装好,您只需要确保 VerifySignSuccess 参数为 true 即可。

 

                var jsApiUiPackage = TenPaySignHelper.GetJsApiUiPackage(TenPayV3Info.AppId, result.prepay_id);
                ViewData["jsApiUiPackage"] = jsApiUiPackage;

  上述代码用于生成前端 UI JsSdk 所需的所有信息,包括时间戳、随机字符串、签名字符串等,开发者不需要自行编写加密算法,开箱即用。

  jsApiUiPackage 信息存放在 ViewData["jsApiUiPackage"] 中,在 View 中可以直接被调用。实际开发环境下,可以用各类方式传递此信息,包括 Ajax + Json。

 

  View:

  对应 View 页面(JsApi.cshtml)关键代码介绍如下:

        document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
        //...
        }

  上述代码是监听 JSAPI 就绪的方法。

 

复制代码
 1               WeixinJSBridge.invoke('getBrandWCPayRequest', {
 2                    "appId": "@jsApiUiPackage.AppId", //公众号名称,由商户传入
 3                    "timeStamp": "@jsApiUiPackage.Timestamp", //时间戳
 4                    "nonceStr": "@jsApiUiPackage.NonceStr", //随机串
 5                    "package": "@Html.Raw(jsApiUiPackage.PrepayIdPackage)",//扩展包
 6                    "signType": "RSA", //微信V3签名方式:RSA
 7                    "paySign": "@Html.Raw(jsApiUiPackage.Signature)" //微信签名
 8                }, function (res) {
 9 
10                    //alert(JSON.stringify(res));
11 
12                    if (res.err_msg == "get_brand_wcpay_request:ok") {
13                        if (confirm('支付成功!点击“确定”进入退款流程测试。')) {
14                            location.href = '@Url.Action("Refund", "TenPayRealV3")';
15                        }
16                        //console.log(JSON.stringify(res));
17                    }else{
18                        alert(JSON.stringify(res));
19                    }
20                    // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
21                    //因此微信团队建议,当收到ok返回时,向商户后台询问是否收到交易成功的通知,若收到通知,前端展示交易成功的界面;若此时未收到通知,商户后台主动调用查询订单接口,查询订单的当前状态,并反馈给前端展示相应的界面。
22                });
复制代码

  上述代码在用户点击支付按钮的时候触发,将自动进行一系列验证,并唤起客户端的微信支付界面(如输入密码或指纹)。

  其中:

  • 第 2-7 行:注入之前在 Controller 中配置的各类参数。注意:paySign 参数一定要加 Html.Raw(),否则可能因为加密字符串被转义而失败!
  • 第 12 行:判断是否支付成功,并进行下一步操作。注意:此处的成功不一定是微信支付真的成功了,因为此信息有被篡改的可能性,因此正式环境一定要以 PayNotifyUrl 中的验证结果为准!

 

  回调验证 PayNotifyUrl:

  微信客户端收到的支付成功信息始终具有被篡改的可能性,因此,千万不要:

  1. 因为客户端的 JS 收到了看似正确的信息,就触发服务器端完成支付的指令(如一条Ajax请求);
  2. 即使触发服务器端的下一步指令,也不要在该条指令中进行订单“已支付”状态的修改,订单状态修改,必须是在 PayNotifyUrl 中!

  根据之前 appsettings.json 以及 JsApi() 方法中的设置,最终的回调地址为:https://sdk.weixin.senparc.com/TenpayRealV3/PayNotifyUrl,代码在 TenPayRealV3Controller 中的 PayNotifyUrl() 方法,此方法中演示了正确的验证支付状态的最佳实践:

复制代码
 1         /// <summary>
 2          /// JS-SDK支付回调地址(在下单接口中设置的 notify_url)
 3          /// </summary>
 4          /// <returns></returns>
 5          public async Task<IActionResult> PayNotifyUrl()
 6          {
 7              try
 8              {
 9                  //获取微信服务器异步发送的支付通知信息
10                  var resHandler = new TenPayNotifyHandler(HttpContext);
11                  var orderReturnJson = await resHandler.AesGcmDecryptGetObjectAsync<OrderReturnJson>();
12  
13                  //记录日志
14                  Senparc.Weixin.WeixinTrace.SendCustomLog("PayNotifyUrl 接收到消息", orderReturnJson.ToJson(true));
15  
16                  //演示记录 transaction_id,实际开发中需要记录到数据库,以便退款和后续跟踪
17                  TradeNumberToTransactionId[orderReturnJson.out_trade_no] = orderReturnJson.transaction_id;
18  
19                  //获取支付状态
20                  string trade_state = orderReturnJson.trade_state;
21  
22                  //验证请求是否从微信发过来(安全)
23                  NotifyReturnData returnData = new();
24  
25                  //验证可靠的支付状态
26                  if (orderReturnJson.VerifySignSuccess == true && trade_state == "SUCCESS")
27                  {
28                      returnData.code = "SUCCESS";//正确的订单处理
29                      /* 提示:
30                       * 1、直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
31                       * 2、上述判断已经具有比较高的安全性以外,还可以对访问 IP 进行判断进一步加强安全性。
32                       * 3、下面演示的是发送支付成功的模板消息提示,非必须。
33                       */
34  
35                      #region 发送支付成功模板消息提醒
36                      //略...
37                      #endregion
38                  }
39                  else
40                  {
41                      returnData.code = "FAILD";//错误的订单处理
42                      returnData.message = "验证失败";
43  
44                      //此处可以给用户发送支付失败提示等
45                  }
46  
47                  #region 记录日志(也可以记录到数据库审计日志中)
48                  //略...
49                  #endregion
50                
51                  return Json(returnData);
52              }
53              catch (Exception ex)
54              {
55                  WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
56                  throw;
57              }
58          }
复制代码

  注释已经比较详细,这里不再赘述,所有签名校验等安全验证信息已经全部封装在接口中,开箱即用。官方要求的完整流程可参考文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml

 

开发第四步:Startup.cs 中配置启动代码

  Senparc.Weixin.TenPayV3 基于 Senparc.Weixin SDK 整体基座,同时由 CO2NET、NeuChar 等基础库提供强大的底层能力支撑,同时我们需要使用一些代码,完成 appsettings.json 等信息的自动注入,因此,需要在 Web 项目的 startup.cs 中添加一些代码,以下是关键代码的介绍(Sample 中为了演示所有的模块所以代码比较多,可以根据需要选用下方的代码):

  ConfigureServices() 方法:

复制代码
 1         public void ConfigureServices(IServiceCollection services)
 2          {
 3              services.AddSession();//使用Session(实践证明需要在配置 Mvc 之前)
 4  
 5              var builder = services.AddControllersWithViews()
 6                                    .AddNewtonsoftJson();// 支持 NewtonsoftJson
 7  
 8              services.AddSingleton<ITempDataProvider, CookieTempDataProvider>();
 9  
10              services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
11              services.AddMemoryCache();//使用本地缓存必须添加
12  
13              services.AddSenparcWeixinServices(Configuration);//Senparc.Weixin 注册(必须)
14          }
复制代码

  上述代码完成了 Web 项目的一系列注册,其中:

  • 第 3 行:为了让 Demo 不依赖数据库,我们使用了 Session 进行个人临时数据的存储,实际开发项目中不一定需要,可根据需要添加。
  • 第 5-6 行:注册 MVC 和 JSON 相关能力,根据需要添加。
  • 第 8 行:提供 Cookie 支持,根据需要添加。
  • 第 10 行:为自动注入 HttpContext 添加注册,根据需要添加。
  • 第 11 行:注册本地缓存,这一行为必须,因为 SDK 运行过程总需要使用到本地缓存。
  • 第 13 行:对 Senparc.Weixin SDK 进行注册,必须。

  可以看到,最小化支持 Senpar.Weixin.TenPayV3,此处实际上只需要最少添加 2 行代码。

 

  Configure() 方法:

复制代码
 1       public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
 2                IOptions<SenparcSetting> senparcSetting, IOptions<SenparcWeixinSetting> senparcWeixinSetting)
 3        {
 4            app.UseHttpsRedirection();
 5            app.UseStaticFiles();
 6            app.UseRouting();
 7 
 8            var registerService = app
 9                    //使用 Senparc.CO2NET 引擎
10                    .UseSenparcGlobal(env, senparcSetting.Value, g => { })
11                    //使用 Senparc.Weixin SDK
12                    .UseSenparcWeixin(senparcWeixinSetting.Value, weixinRegister =>
13                    {
14                        //注册最新的 TenPay V3
15                        weixinRegister.RegisterTenpayRealV3(senparcWeixinSetting.Value, "【盛派网络小助手】公众号-RealV3");
16                    });
17        }
复制代码

  上述代码中:

  • 第 4-6 行:常规方法。
  • 第 10 行:启动 Senparc.CO2NET 引擎,提供一系列基础能力(如缓存、日志、队列等)。
  • 第 12 行:启动 Senparc.Weixin SDK,其中可以进行微信公众号、小程序、企业微信、微信支付等不同模块的注册。
  • 第 15 行:注册微信支付V3的信息,数据源头为 appsettings.json。注意:这一行注册过程可以在使用微信支付功能前的任意地方执行,但建议在启动时就完成注册。除使用 appsetting.json 方式自动注入,也可以手动构造实体类,赋值并传入。

 

上线演示

  上述 Sample 可以直接发布,最新的代码我们已经发布到了到官方在线示例站点:https://sdk.weixin.senparc.com/,有两种途径可以进入上述 JsApi 页面进行支付测试。

  方式一:关注公众号:盛派网络小助手,点击菜单

 

 

 

  进入菜单【更多测试】>【微信支付V3】:

 

 

   选择任意一个商品,如【产品1】,点击进入:

 

 

   点击【点击提交可体验微信支付】按钮,进入客户端支付状态:

 

 

   在客户端完成支付(输入密码或指纹),即可出现支付完成的官方界面:

 

 

   点击【完成】按钮,可以继续体验退款流程(开发相关功能介绍请看下一篇系列文章:《微信支付 V3 开发教程(二):退款》。

  返回公众号内,可以看到已经通过 PayNotifyUrl 发送过来的模板消息(同时已经经过安全验证):

 

 

   

  并可以在微信支付消息中,看到官方的消息推送:

 

 

 

  方式二:通过 https://sdk.weixin.senparc.com/ 顶部菜单【工具箱】>【微信支付 V3 测试(PC端)】进入:

 

 

   进入后同样是 ProductList 页面:

 

 

   选择一个商品进入,可以看到 PC 端提供了多种支付方式的演示,包括:H5 支付、Native 支付,以及扫一扫支付:

 

  提示:由于产品Id随每次系统启动变化,所以上述二维码在您看到的时候已经失效,您可以重新从入口进入,获得最新的二维码。

 

  • 关于 H5 支付请关注后续文章:《微信支付 V3 开发教程(三):H5 支付》
  • 关于 Native 支付请关注后续文章:《微信支付 V3 开发教程(四):Native 支付》

  当前演示的 JsApi 支付,可在“扫一扫”支付方式中,使用微信扫码进入,即可在微信端打开上述“方法一”中介绍的产品列表,并体验支付流程。

  

更多内容

  本文是《微信支付 V3 开发教程》的开篇,后续还将对包括退款、对账订单、H5 支付、Native 支付、微信分等更多的接口展开介绍,欢迎关注,感谢大家的支持!

标签:Weixin,微信,Senparc,TenPayV3,V3,支付
From: https://www.cnblogs.com/Alex80/p/17616295.html

相关文章

  • 微信小程序支付V2版之JSAPI支付
    文章目录一、微信支付环境搭建1企业微信小程序的开通2.企业商户号的开通3小程序号与商户号关联二、微信小程序的支付流程1`JSAPI`支付流程2微信小程序获取`openid`3微信小程序下单4后台服务程序对订单的处理5微信小程序发起支付6支付结果的通知三......
  • uniapp中微信小程序取微信头像并上传到.net core后端
    uniapp中微信小程序取微信头像并上传到.netcore后端2023年08月09日后端net7测试成功,先记下来,以后要用的时候直接来这复制粘贴前端uniapp里的vue代码: <template><view><buttonclass="avatar-wrapper"open-type="chooseAvatar"@chooseavatar="o......
  • codeforces 891 (div3)857E - Power of Points
    E.点的力量每个测试限时2秒每个测试限制内存为256兆字节输入以标准格式输入输出以标准格式输出给定n个具有整数坐标x1,…xn的点,这些点位于数线上。对于某个整数s,我们构建段[s,x1],[s,x2],…,[s,xn]。注意,如果xi<s,则段将类似于[xi,s]。段[a,b]覆盖了所有整数点a,a+1,a+2,…,b。......
  • 微信开发之检测僵尸粉的技术实现
    简要描述:检测好友状态请求URL:http://域名地址/checkZombie请求方式:POST请求头Headers:Content-Type:application/jsonAuthorization:login接口返回参数:参数名必选类型说明wId是String登录实例标识wcId是String好友微信id,多个已","分隔,每次最多支持......
  • 微信开发之检测僵尸粉的技术实现
    简要描述:检测好友状态请求URL:http://域名地址/checkZombie请求方式:POST请求头Headers:Content-Type:application/jsonAuthorization:login接口返回参数:参数名必选类型说明wId是String登录实例标识wcId是String好友微信id,多个已","分隔,每次最多支持个20请求参数示例{"wId":"0137......
  • 微信小程序15 做一个搜索框的样式
    一般来说首页上都会有搜索的功能,那么我们来加个搜索框试试在newlist上继续操作 简单搜索框的布局和样式页面上<viewclass="headClass"><inputtype="text"placeholder="请输入"></input></view>但是这样太丑了,完善一下样式.headClass{background-color:silver;......
  • 从零玩转系列之微信支付实战PC端支付微信退款接口搭建 | 技术创作特训营第一期
    一、前言从零玩转系列之微信支付实战PC端支付微信退款接口搭建|技术创作特训营第一期继前文章取消订单接口和查询订单接口此篇为申请退款流程,此篇文章过长我将分几个阶段的文章发布(项目源码都有,小程序和PC端)在此之前已经更新了微信支付开篇、微信支付安全、微信实战基础......
  • 微信公众号HTML5如何预览EXCEL、word、ppt、pdf等文件
    1、pfile文件预览   很简单一句话window.open('http://www.pfile.com.cn/api/profile/onlinePreview?url='+encodeURIComponent(“文档地址”));使用了一段时间,简单完美,强烈推荐!!! 2、 officeonlineleturl="https://view.officeapps.live.com/op/view.aspx?src="+......
  • 微信小程序14 头部设置,通用,单独,动态。
    这里用一个例子来学习新的东西一个可以搜索,切换tab的页面,这个太常见了。新建一个newlist/newlist  在全局配置app.json中的pages里把newlist放到第一个去,这样方便。 通用头部设置这时候我们注意到,app.json中除了pages,还有这个"window":{"backgroundTextStyle":......
  • 搭建微信小程序的步骤
    1、租云服务器2、搭建后端服务3、申请购买域名4、域名解析5、服务器配置域名访问6、域名备案(备案后才能申请ssl证书)7、申请ssl证书(微信小程序必须使用https访问,必须申请ssl证书)8、在微信公众平台上申请创建小程序,填写项目信息,不是游戏不能选择游戏类型9、前端项目绑定小程......