mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-12-30 02:14:44 +08:00
docs: 更新示例项目
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
using Autofac;
|
||||
using Autofac.Integration.Mvc;
|
||||
using Autofac.Integration.WebApi;
|
||||
using Hangfire;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample
|
||||
{
|
||||
public class AutofacConfig
|
||||
{
|
||||
public static void Init()
|
||||
{
|
||||
var builder = new ContainerBuilder();
|
||||
|
||||
builder.RegisterControllers(Assembly.GetExecutingAssembly());
|
||||
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
|
||||
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).AsImplementedInterfaces().AsSelf();
|
||||
|
||||
builder.RegisterType<Services.HttpClients.Implements.WechatTenpayCertificateManagerFactory>()
|
||||
.As<Services.HttpClients.IWechatTenpayCertificateManagerFactory>()
|
||||
.SingleInstance();
|
||||
builder.RegisterType<Services.HttpClients.Implements.WechatTenpayPublicKeyManagerFactory>()
|
||||
.As<Services.HttpClients.IWechatTenpayPublicKeyManagerFactory>()
|
||||
.SingleInstance();
|
||||
builder.RegisterType<Services.HttpClients.Implements.WechatTenpayClientFactory>()
|
||||
.As<Services.HttpClients.IWechatTenpayClientFactory>()
|
||||
.SingleInstance();
|
||||
|
||||
builder.RegisterType<Services.BackgroundJobs.TenpayCertificateRefreshingBackgroundJob>()
|
||||
.AsSelf()
|
||||
.InstancePerBackgroundJob();
|
||||
|
||||
var container = builder.Build();
|
||||
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
|
||||
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample
|
||||
{
|
||||
public class FilterConfig
|
||||
{
|
||||
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
|
||||
{
|
||||
filters.Add(new HandleErrorAttribute());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Hangfire;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample
|
||||
{
|
||||
public class HangfireConfig
|
||||
{
|
||||
public static BackgroundJobServer Init()
|
||||
{
|
||||
GlobalConfiguration.Configuration
|
||||
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
|
||||
.UseSimpleAssemblyNameTypeSerializer()
|
||||
.UseRecommendedSerializerSettings()
|
||||
.UseInMemoryStorage();
|
||||
|
||||
var server = new BackgroundJobServer();
|
||||
|
||||
HangfireAspNet.Use(() => new BackgroundJobServer[] { server });
|
||||
|
||||
BackgroundJob.Enqueue<Services.BackgroundJobs.TenpayCertificateRefreshingBackgroundJob>(job => job.ExecuteAsync());
|
||||
RecurringJob.AddOrUpdate<Services.BackgroundJobs.TenpayCertificateRefreshingBackgroundJob>(job => job.ExecuteAsync(), Cron.Daily);
|
||||
|
||||
return server;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample
|
||||
{
|
||||
public class RouteConfig
|
||||
{
|
||||
public static void RegisterRoutes(RouteCollection routes)
|
||||
{
|
||||
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||
|
||||
routes.MapRoute(
|
||||
name: "Default",
|
||||
url: "{controller}/{action}/{id}",
|
||||
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Web.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample
|
||||
{
|
||||
public static class WebApiConfig
|
||||
{
|
||||
public static void Register(HttpConfiguration config)
|
||||
{
|
||||
config.MapHttpAttributeRoutes();
|
||||
|
||||
config.Routes.MapHttpRoute(
|
||||
name: "Default",
|
||||
routeTemplate: "{controller}/{action}",
|
||||
defaults: new { }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Controllers
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
|
||||
|
||||
[RoutePrefix("api/notify")]
|
||||
public class TenpayNotifyController : ApiController
|
||||
{
|
||||
private readonly Services.HttpClients.IWechatTenpayClientFactory _wechatTenpayClientFactory;
|
||||
|
||||
public TenpayNotifyController(
|
||||
Services.HttpClients.IWechatTenpayClientFactory wechatTenpayClientFactory)
|
||||
{
|
||||
_wechatTenpayClientFactory = wechatTenpayClientFactory;
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[Route("m-{merchant_id}/message-push")]
|
||||
public async Task<IHttpActionResult> ReceiveMessage([FromUri(Name = "merchant_id")] string merchantId, CancellationToken cancellationToken)
|
||||
{
|
||||
using (var stream = await Request.Content.ReadAsStreamAsync())
|
||||
using (var reader = new StreamReader(stream, Encoding.UTF8))
|
||||
{
|
||||
string timestamp = Request.Headers.Contains("Wechatpay-Timestamp") ? Request.Headers.GetValues("Wechatpay-Timestamp").First() : null;
|
||||
string nonce = Request.Headers.Contains("Wechatpay-Nonce") ? Request.Headers.GetValues("Wechatpay-Nonce").First() : null;
|
||||
string signature = Request.Headers.Contains("Wechatpay-Signature") ? Request.Headers.GetValues("Wechatpay-Signature").First() : null;
|
||||
string serialNumber = Request.Headers.Contains("Wechatpay-Serial") ? Request.Headers.GetValues("Wechatpay-Serial").First() : null;
|
||||
string content = await reader.ReadToEndAsync();
|
||||
Debug.WriteLine("接收到微信支付推送的数据:{0}", content);
|
||||
|
||||
using (var client = _wechatTenpayClientFactory.Create(merchantId))
|
||||
{
|
||||
bool valid = client.VerifyEventSignature(
|
||||
webhookTimestamp: timestamp,
|
||||
webhookNonce: nonce,
|
||||
webhookBody: content,
|
||||
webhookSignature: signature,
|
||||
webhookSerialNumber: serialNumber
|
||||
);
|
||||
if (!valid)
|
||||
{
|
||||
// NOTICE:
|
||||
// 需提前注入 CertificateManager、并添加平台证书,才可以使用扩展方法执行验签操作。
|
||||
// 请参考本示例项目 TenpayCertificateRefreshingBackgroundService 后台任务中的相关实现。
|
||||
// 有关 CertificateManager 的完整介绍请参阅《开发文档 / 基础用法 / 如何验证回调通知事件签名?》。
|
||||
// 后续如何解密并反序列化,请参阅《开发文档 / 基础用法 / 如何解密回调通知事件中的敏感数据?》。
|
||||
|
||||
return Json(new { code = "FAIL", message = "验签失败" });
|
||||
}
|
||||
|
||||
var callbackModel = client.DeserializeEvent(content);
|
||||
var eventType = callbackModel.EventType?.ToUpper();
|
||||
switch (eventType)
|
||||
{
|
||||
case "TRANSACTION.SUCCESS":
|
||||
{
|
||||
var callbackResource = client.DecryptEventResource<Events.TransactionResource>(callbackModel);
|
||||
Debug.WriteLine("接收到微信支付推送的订单支付成功通知,商户订单号:{0}", callbackResource.OutTradeNumber);
|
||||
// 后续处理略
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// 其他情况略
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return Json(new { code = "SUCCESS", message = "成功" });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Controllers
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
|
||||
|
||||
[RoutePrefix("api/order")]
|
||||
public class TenpayOrderController : ApiController
|
||||
{
|
||||
private readonly Services.HttpClients.IWechatTenpayClientFactory _wechatTenpayClientFactory;
|
||||
|
||||
public TenpayOrderController(
|
||||
Services.HttpClients.IWechatTenpayClientFactory wechatTenpayClientFactory)
|
||||
{
|
||||
_wechatTenpayClientFactory = wechatTenpayClientFactory;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("jsapi")]
|
||||
public async Task<IHttpActionResult> CreateOrderByJsapi([FromBody] Models.CreateOrderByJsapiRequest requestModel, CancellationToken cancellationToken)
|
||||
{
|
||||
if (requestModel == null)
|
||||
return BadRequest();
|
||||
|
||||
using (var client = _wechatTenpayClientFactory.Create(requestModel.MerchantId))
|
||||
{
|
||||
var request = new CreatePayTransactionJsapiRequest()
|
||||
{
|
||||
OutTradeNumber = "SAMPLE_OTN_" + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff"),
|
||||
AppId = requestModel.AppId,
|
||||
Description = "演示订单",
|
||||
NotifyUrl = Options.TenpayOptions.Instance.Value.NotifyUrl,
|
||||
Amount = new CreatePayTransactionJsapiRequest.Types.Amount() { Total = requestModel.Amount },
|
||||
Payer = new CreatePayTransactionJsapiRequest.Types.Payer() { OpenId = requestModel.OpenId }
|
||||
};
|
||||
var response = await client.ExecuteCreatePayTransactionJsapiAsync(request, cancellationToken);
|
||||
if (!response.IsSuccessful())
|
||||
{
|
||||
Debug.WriteLine(
|
||||
"JSAPI 下单失败(状态码:{0},错误代码:{1},错误描述:{2})。",
|
||||
response.GetRawStatus(), response.ErrorCode, response.ErrorMessage
|
||||
);
|
||||
}
|
||||
|
||||
return Json(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Controllers
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
|
||||
|
||||
[RoutePrefix("api/refund")]
|
||||
public class TenpayRefundController : ApiController
|
||||
{
|
||||
private readonly Services.HttpClients.IWechatTenpayClientFactory _wechatTenpayClientFactory;
|
||||
|
||||
public TenpayRefundController(
|
||||
Services.HttpClients.IWechatTenpayClientFactory wechatTenpayClientFactory)
|
||||
{
|
||||
_wechatTenpayClientFactory = wechatTenpayClientFactory;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Route("")]
|
||||
public async Task<IHttpActionResult> CreateRefund([FromBody] Models.CreateRefundRequest requestModel, CancellationToken cancellationToken)
|
||||
{
|
||||
if (requestModel == null)
|
||||
return BadRequest();
|
||||
|
||||
using (var client = _wechatTenpayClientFactory.Create(requestModel.MerchantId))
|
||||
{
|
||||
var request = new CreateRefundDomesticRefundRequest()
|
||||
{
|
||||
TransactionId = requestModel.TransactionId,
|
||||
OutRefundNumber = "SAMPLE_ORN_" + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff"),
|
||||
Amount = new CreateRefundDomesticRefundRequest.Types.Amount()
|
||||
{
|
||||
Total = requestModel.OrderAmount,
|
||||
Refund = requestModel.RefundAmount
|
||||
},
|
||||
Reason = "示例退款",
|
||||
NotifyUrl = Options.TenpayOptions.Instance.Value.NotifyUrl
|
||||
};
|
||||
var response = await client.ExecuteCreateRefundDomesticRefundAsync(request, cancellationToken);
|
||||
if (!response.IsSuccessful())
|
||||
{
|
||||
Debug.WriteLine(
|
||||
"申请退款失败(状态码:{0},错误代码:{1},错误描述:{2})。",
|
||||
response.GetRawStatus(), response.ErrorCode, response.ErrorMessage
|
||||
);
|
||||
}
|
||||
|
||||
return Json(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<%@ Application Codebehind="Global.asax.cs" Inherits="SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.WebApiApplication" Language="C#" %>
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Optimization;
|
||||
using System.Web.Routing;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample
|
||||
{
|
||||
public class WebApiApplication : System.Web.HttpApplication
|
||||
{
|
||||
private Hangfire.BackgroundJobServer _backgroundJobServer;
|
||||
|
||||
protected void Application_Start()
|
||||
{
|
||||
AreaRegistration.RegisterAllAreas();
|
||||
GlobalConfiguration.Configure(WebApiConfig.Register);
|
||||
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
|
||||
RouteConfig.RegisterRoutes(RouteTable.Routes);
|
||||
|
||||
AutofacConfig.Init();
|
||||
_backgroundJobServer = HangfireConfig.Init();
|
||||
}
|
||||
|
||||
protected void Application_End()
|
||||
{
|
||||
_backgroundJobServer?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Models
|
||||
{
|
||||
public class CreateOrderByJsapiRequest
|
||||
{
|
||||
public string MerchantId { get; set; }
|
||||
|
||||
public string AppId { get; set; }
|
||||
|
||||
public string OpenId { get; set; }
|
||||
|
||||
// NOTICE:
|
||||
// 单机演示时金额来源于客户端请求,生产项目请改为服务端计算生成,切勿依赖客户端提供的金额结果。
|
||||
public int Amount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Models
|
||||
{
|
||||
public class CreateRefundRequest
|
||||
{
|
||||
public string MerchantId { get; set; }
|
||||
|
||||
public string TransactionId { get; set; }
|
||||
|
||||
// NOTICE:
|
||||
// 单机演示时金额来源于客户端请求,生产项目请改为服务端计算生成,切勿依赖客户端提供的金额结果。
|
||||
public int OrderAmount { get; set; }
|
||||
|
||||
public int RefundAmount { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Configuration;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Options
|
||||
{
|
||||
public partial class TenpayOptions
|
||||
{
|
||||
public static readonly Lazy<TenpayOptions> Instance = new Lazy<TenpayOptions>(() =>
|
||||
{
|
||||
var configMerchantRegex = new Regex("^TenpayOptions_Merchant_(\\d+)_MerchantId$");
|
||||
var configMerchantIndexes = WebConfigurationManager.AppSettings.AllKeys
|
||||
.Where(key => configMerchantRegex.IsMatch(key))
|
||||
.Select(key => configMerchantRegex.Matches(key)[0].Groups[1].Value)
|
||||
.ToArray();
|
||||
|
||||
return new TenpayOptions()
|
||||
{
|
||||
Merchants = configMerchantIndexes
|
||||
.Select(i => new Types.WechatMerchant()
|
||||
{
|
||||
MerchantId = WebConfigurationManager.AppSettings[$"TenpayOptions_Merchant_{i}_MerchantId"],
|
||||
SecretV3 = WebConfigurationManager.AppSettings[$"TenpayOptions_Merchant_{i}_SecretV3"],
|
||||
CertificateSerialNumber = WebConfigurationManager.AppSettings[$"TenpayOptions_Merchant_{i}_CertificateSerialNumber"],
|
||||
CertificatePrivateKey = WebConfigurationManager.AppSettings[$"TenpayOptions_Merchant_{i}_CertificatePrivateKey"],
|
||||
PlatformPublicKeyId = WebConfigurationManager.AppSettings[$"TenpayOptions_Merchant_{i}_PlatformPublicKeyId"],
|
||||
PlatformPublicKey = WebConfigurationManager.AppSettings[$"TenpayOptions_Merchant_{i}_PlatformPublicKey"],
|
||||
})
|
||||
.ToArray(),
|
||||
NotifyUrl = WebConfigurationManager.AppSettings[$"TenpayOptions_NotifyUrl"]
|
||||
};
|
||||
}, isThreadSafe: true);
|
||||
}
|
||||
|
||||
public partial class TenpayOptions
|
||||
{
|
||||
public Types.WechatMerchant[] Merchants { get; set; } = Array.Empty<Types.WechatMerchant>();
|
||||
|
||||
public string NotifyUrl { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public partial class TenpayOptions
|
||||
{
|
||||
public static class Types
|
||||
{
|
||||
public class WechatMerchant
|
||||
{
|
||||
public string MerchantId { get; set; } = string.Empty;
|
||||
|
||||
public string SecretV3 { get; set; } = string.Empty;
|
||||
|
||||
public string CertificateSerialNumber { get; set; } = string.Empty;
|
||||
|
||||
public string CertificatePrivateKey { get; set; } = string.Empty;
|
||||
|
||||
public string PlatformPublicKeyId { get; set; }
|
||||
|
||||
public string PlatformPublicKey { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的常规信息是通过以下项进行控制的
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample_NetFramework48")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample_NetFramework48")]
|
||||
[assembly: AssemblyCopyright("版权所有(C) 2025")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 将使此程序集中的类型
|
||||
// 对 COM 组件不可见。如果需要
|
||||
// COM,在该类型上将 ComVisible 属性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
|
||||
[assembly: Guid("22aea3c5-d9af-4ec5-b208-73dc8795a1bb")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 内部版本号
|
||||
// 修订号
|
||||
//
|
||||
// 你可以指定所有值,也可以让修订版本和内部版本号采用默认值,
|
||||
// 方法是按如下所示使用 "*":
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,281 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>
|
||||
</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{DFA229FF-0A4B-411E-9A11-681BA55DFBAE}</ProjectGuid>
|
||||
<ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample_NetFramework48</RootNamespace>
|
||||
<AssemblyName>SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample_NetFramework48</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||
<MvcBuildViews>false</MvcBuildViews>
|
||||
<UseIISExpress>true</UseIISExpress>
|
||||
<Use64BitIISExpress />
|
||||
<IISExpressSSLPort>44339</IISExpressSSLPort>
|
||||
<IISExpressAnonymousAuthentication />
|
||||
<IISExpressWindowsAuthentication />
|
||||
<IISExpressUseClassicPipelineMode />
|
||||
<UseGlobalApplicationHostFile />
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Autofac, Version=6.4.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Autofac.6.4.0\lib\netstandard2.0\Autofac.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Autofac.Integration.Mvc, Version=6.1.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Autofac.Mvc5.6.1.0\lib\net472\Autofac.Integration.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Autofac.Integration.WebApi, Version=6.1.1.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Autofac.WebApi2.6.1.1\lib\net472\Autofac.Integration.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Flurl, Version=4.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Flurl.4.0.0\lib\net472\Flurl.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Flurl.Http, Version=4.0.2.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Flurl.Http.4.0.2\lib\net461\Flurl.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Hangfire.AspNet, Version=0.3.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Hangfire.AspNet.0.3.0\lib\net45\Hangfire.AspNet.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Hangfire.Autofac, Version=2.7.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Hangfire.Autofac.2.7.0\lib\net45\Hangfire.Autofac.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Hangfire.Core, Version=1.8.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Hangfire.Core.1.8.0\lib\net46\Hangfire.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Hangfire.InMemory, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Hangfire.InMemory.1.0.0\lib\net451\Hangfire.InMemory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Bcl.AsyncInterfaces, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Bcl.AsyncInterfaces.8.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.Host.SystemWeb, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.Owin.Host.SystemWeb.3.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="SKIT.FlurlHttpClient.Common, Version=3.1.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\SKIT.FlurlHttpClient.Common.3.1.1\lib\net462\SKIT.FlurlHttpClient.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.5.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.7.1\lib\net46\System.Diagnostics.DiagnosticSource.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.2, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Encodings.Web, Version=8.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Text.Encodings.Web.8.0.0\lib\net462\System.Text.Encodings.Web.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Text.Json, Version=8.0.0.5, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Text.Json.8.0.5\lib\net462\System.Text.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.ValueTuple, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Entity" />
|
||||
<Reference Include="System.Web.ApplicationServices" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Abstractions" />
|
||||
<Reference Include="System.Web.Routing" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="Microsoft.Web.Infrastructure, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.Web.Infrastructure.2.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http">
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.WebRequest">
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.Helpers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http, Version=5.2.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.9\lib\net45\System.Web.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Http.WebHost, Version=5.2.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.9\lib\net45\System.Web.Http.WebHost.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Mvc, Version=5.2.9.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.Mvc.5.2.9\lib\net45\System.Web.Mvc.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Optimization">
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.Razor.3.2.9\lib\net45\System.Web.Razor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.WebPages.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.9\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="WebGrease">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Antlr3.Runtime">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform">
|
||||
<HintPath>..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="App_Start\AutofacConfig.cs" />
|
||||
<Compile Include="App_Start\FilterConfig.cs" />
|
||||
<Compile Include="App_Start\HangfireConfig.cs" />
|
||||
<Compile Include="App_Start\RouteConfig.cs" />
|
||||
<Compile Include="App_Start\WebApiConfig.cs" />
|
||||
<Compile Include="Controllers\TenpayNotifyController.cs" />
|
||||
<Compile Include="Controllers\TenpayOrderController.cs" />
|
||||
<Compile Include="Controllers\TenpayRefundController.cs" />
|
||||
<Compile Include="Global.asax.cs">
|
||||
<DependentUpon>Global.asax</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Models\CreateOrderByJsapiRequest.cs" />
|
||||
<Compile Include="Models\CreateRefundRequest.cs" />
|
||||
<Compile Include="Options\TenpayOptions.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\BackgroundJobs\TenpayCertificateRefreshingBackgroundJob.cs" />
|
||||
<Compile Include="Services\HttpClients\Implements\WechatTenpayPublicKeyManagerFactory.cs" />
|
||||
<Compile Include="Services\HttpClients\Implements\WechatTenpayCertificateManagerFactory.cs" />
|
||||
<Compile Include="Services\HttpClients\Implements\WechatTenpayClientFactory.cs" />
|
||||
<Compile Include="Services\HttpClients\IWechatTenpayPublicKeyManagerFactory.cs" />
|
||||
<Compile Include="Services\HttpClients\IWechatTenpayCertificateManagerFactory.cs" />
|
||||
<Compile Include="Services\HttpClients\IWechatTenpayClientFactory.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Global.asax" />
|
||||
<Content Include="Web.config" />
|
||||
<Content Include="Web.Debug.config">
|
||||
<DependentUpon>Web.config</DependentUpon>
|
||||
</Content>
|
||||
<Content Include="Web.Release.config">
|
||||
<DependentUpon>Web.config</DependentUpon>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="App_Data\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\SKIT.FlurlHttpClient.Wechat.TenpayV3\SKIT.FlurlHttpClient.Wechat.TenpayV3.csproj">
|
||||
<Project>{b9f2eb07-609c-d1b6-31de-1bfb32beee0d}</Project>
|
||||
<Name>SKIT.FlurlHttpClient.Wechat.TenpayV3</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
|
||||
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
|
||||
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
|
||||
</Target>
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<UseIIS>True</UseIIS>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<DevelopmentServerPort>49987</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>https://localhost:44339/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<UseCustomServer>False</UseCustomServer>
|
||||
<CustomServerUrl>
|
||||
</CustomServerUrl>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target> -->
|
||||
</Project>
|
||||
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.BackgroundJobs
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
|
||||
|
||||
internal class TenpayCertificateRefreshingBackgroundJob
|
||||
{
|
||||
private readonly HttpClients.IWechatTenpayClientFactory _wechatTenpayClientFactory;
|
||||
|
||||
public TenpayCertificateRefreshingBackgroundJob(
|
||||
HttpClients.IWechatTenpayClientFactory wechatTenpayClientFactory)
|
||||
{
|
||||
_wechatTenpayClientFactory = wechatTenpayClientFactory;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync()
|
||||
{
|
||||
// NOTICE:
|
||||
// 2024-10-01 后微信支付新增了基于微信支付公钥的验证身份方式,
|
||||
// 如果你已切换至使用平台公钥,则不再需要下载平台证书,可删除此定时任务。
|
||||
|
||||
foreach (var tenpayMerchantOptions in Options.TenpayOptions.Instance.Value.Merchants)
|
||||
{
|
||||
try
|
||||
{
|
||||
const string ALGORITHM_TYPE = "RSA";
|
||||
using (var client = _wechatTenpayClientFactory.Create(tenpayMerchantOptions.MerchantId))
|
||||
{
|
||||
var request = new QueryCertificatesRequest() { AlgorithmType = ALGORITHM_TYPE };
|
||||
var response = await client.ExecuteQueryCertificatesAsync(request);
|
||||
if (response.IsSuccessful())
|
||||
{
|
||||
// NOTICE:
|
||||
// 如果构造 Client 时启用了 `AutoDecryptResponseSensitiveProperty` 配置项,则无需再执行下面一行的手动解密方法:
|
||||
response = client.DecryptResponseSensitiveProperty(response);
|
||||
|
||||
foreach (var certificate in response.CertificateList)
|
||||
{
|
||||
client.PlatformCertificateManager.AddEntry(CertificateEntry.Parse(ALGORITHM_TYPE, certificate));
|
||||
}
|
||||
|
||||
Debug.WriteLine("刷新微信商户平台证书成功。");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine(
|
||||
"刷新微信商户平台证书失败(状态码:{0},错误代码:{1},错误描述:{2})。",
|
||||
response.GetRawStatus(), response.ErrorCode, response.ErrorMessage
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine("刷新微信商户平台证书遇到异常。\r\n{0}", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.HttpClients
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
|
||||
|
||||
public interface IWechatTenpayCertificateManagerFactory
|
||||
{
|
||||
ICertificateManager Create(string merchantId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.HttpClients
|
||||
{
|
||||
public interface IWechatTenpayClientFactory
|
||||
{
|
||||
WechatTenpayClient Create(string merchantId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.HttpClients
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
|
||||
|
||||
public interface IWechatTenpayPublicKeyManagerFactory
|
||||
{
|
||||
IPublicKeyManager Create(string merchantId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.HttpClients.Implements
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
|
||||
|
||||
internal partial class WechatTenpayCertificateManagerFactory : IWechatTenpayCertificateManagerFactory
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, ICertificateManager> _dict;
|
||||
|
||||
public WechatTenpayCertificateManagerFactory()
|
||||
{
|
||||
_dict = new ConcurrentDictionary<string, ICertificateManager>();
|
||||
}
|
||||
|
||||
public ICertificateManager Create(string merchantId)
|
||||
{
|
||||
// NOTICE:
|
||||
// 这里的工厂方法是为了演示多租户而存在的,可根据商户号生成不同的证书管理器。
|
||||
// 如果你的项目只存在唯一一个租户,那么直接注入 `PlatformCertificateManager` 即可。
|
||||
|
||||
return _dict.GetOrAdd(merchantId, new InMemoryCertificateManager());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.HttpClients.Implements
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
|
||||
|
||||
internal partial class WechatTenpayClientFactory : IWechatTenpayClientFactory
|
||||
{
|
||||
private readonly IWechatTenpayCertificateManagerFactory _tenpayCertificateManagerFactory;
|
||||
private readonly IWechatTenpayPublicKeyManagerFactory _tenpayPublicKeyManagerFactory;
|
||||
|
||||
public WechatTenpayClientFactory(
|
||||
IWechatTenpayCertificateManagerFactory tenpayCertificateManagerFactory,
|
||||
IWechatTenpayPublicKeyManagerFactory tenpayPublicKeyManagerFactory)
|
||||
{
|
||||
_tenpayCertificateManagerFactory = tenpayCertificateManagerFactory;
|
||||
_tenpayPublicKeyManagerFactory = tenpayPublicKeyManagerFactory;
|
||||
}
|
||||
|
||||
public WechatTenpayClient Create(string merchantId)
|
||||
{
|
||||
// NOTICE:
|
||||
// 这里的工厂方法是为了演示多租户而存在的,可根据商户号生成不同的 API 客户端。
|
||||
// 如果你的项目只存在唯一一个租户,那么直接注入 `WechatTenpayClient` 即可。
|
||||
|
||||
var tenpayMerchantOptions = Options.TenpayOptions.Instance.Value.Merchants?.FirstOrDefault(e => string.Equals(merchantId, e.MerchantId));
|
||||
if (tenpayMerchantOptions == null)
|
||||
throw new Exception("未在配置项中找到该 MerchantId 对应的微信商户号。");
|
||||
|
||||
return new WechatTenpayClient(new WechatTenpayClientOptions()
|
||||
{
|
||||
MerchantId = tenpayMerchantOptions.MerchantId,
|
||||
MerchantV3Secret = tenpayMerchantOptions.SecretV3,
|
||||
MerchantCertificateSerialNumber = tenpayMerchantOptions.CertificateSerialNumber,
|
||||
MerchantCertificatePrivateKey = tenpayMerchantOptions.CertificatePrivateKey,
|
||||
AutoEncryptRequestSensitiveProperty = false,
|
||||
AutoDecryptResponseSensitiveProperty = false,
|
||||
|
||||
// 基于平台证书的认证方式还需设置以下参数:
|
||||
PlatformAuthScheme = PlatformAuthScheme.Certificate,
|
||||
PlatformCertificateManager = _tenpayCertificateManagerFactory.Create(tenpayMerchantOptions.MerchantId),
|
||||
|
||||
// 基于平台公钥的认证方式还需设置以下参数:
|
||||
//PlatformAuthScheme = PlatformAuthScheme.PublicKey,
|
||||
//PlatformPublicKeyManager = _tenpayPublicKeyManagerFactory.Create(tenpayMerchantOptions.MerchantId)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.HttpClients.Implements
|
||||
{
|
||||
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
|
||||
|
||||
internal partial class WechatTenpayPublicKeyManagerFactory : IWechatTenpayPublicKeyManagerFactory
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, IPublicKeyManager> _dict;
|
||||
|
||||
public WechatTenpayPublicKeyManagerFactory()
|
||||
{
|
||||
_dict = new ConcurrentDictionary<string, IPublicKeyManager>();
|
||||
}
|
||||
|
||||
public IPublicKeyManager Create(string merchantId)
|
||||
{
|
||||
// NOTICE:
|
||||
// 这里的工厂方法是为了演示多租户而存在的,可根据商户号生成不同的公钥管理器。
|
||||
// 如果你的项目只存在唯一一个租户,那么直接注入 `PlatformPublicKeyManager` 即可。
|
||||
|
||||
var tenpayMerchantOptions = Options.TenpayOptions.Instance.Value.Merchants?.FirstOrDefault(e => string.Equals(merchantId, e.MerchantId));
|
||||
if (tenpayMerchantOptions == null)
|
||||
throw new Exception("未在配置项中找到该 MerchantId 对应的微信商户号。");
|
||||
|
||||
return _dict.GetOrAdd(merchantId, (_) =>
|
||||
{
|
||||
var manager = new InMemoryPublicKeyManager();
|
||||
manager.AddEntry(new PublicKeyEntry(PublicKeyEntry.ALGORITHM_TYPE_RSA, tenpayMerchantOptions.PlatformPublicKeyId, tenpayMerchantOptions.PlatformPublicKey));
|
||||
return manager;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- 有关使用 Web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301874 -->
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--
|
||||
在下例中,“SetAttributes”转换将更改
|
||||
“connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
|
||||
特性“name”时使用“ReleaseSQLServer”。
|
||||
|
||||
<connectionStrings>
|
||||
<add name="MyDB"
|
||||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
|
||||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
|
||||
</connectionStrings>
|
||||
-->
|
||||
<system.web>
|
||||
<!--
|
||||
在以下示例中,"Replace" 转换将替换 Web.config 文件的
|
||||
整个 <customErrors> 节。
|
||||
请注意,由于在 <system.web> 节点下只有一个
|
||||
customErrors 节,因此无需使用 "xdt:Locator" 属性。
|
||||
|
||||
<customErrors defaultRedirect="GenericError.htm"
|
||||
mode="RemoteOnly" xdt:Transform="Replace">
|
||||
<error statusCode="500" redirect="InternalError.htm"/>
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- 有关使用 Web.config 转换的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301874 -->
|
||||
|
||||
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<!--
|
||||
在下例中,“SetAttributes”转换将更改
|
||||
“connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
|
||||
特性“name”时使用“ReleaseSQLServer”。
|
||||
|
||||
<connectionStrings>
|
||||
<add name="MyDB"
|
||||
connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
|
||||
xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
|
||||
</connectionStrings>
|
||||
-->
|
||||
<system.web>
|
||||
<compilation xdt:Transform="RemoveAttributes(debug)" />
|
||||
<!--
|
||||
在以下示例中,"Replace" 转换将替换 Web.config 文件的
|
||||
整个 <customErrors> 节。
|
||||
请注意,由于在 <system.web> 节点下只有一个
|
||||
customErrors 节,因此无需使用 "xdt:Locator" 属性。
|
||||
|
||||
<customErrors defaultRedirect="GenericError.htm"
|
||||
mode="RemoteOnly" xdt:Transform="Replace">
|
||||
<error statusCode="500" redirect="InternalError.htm"/>
|
||||
</customErrors>
|
||||
-->
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -0,0 +1,102 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
有关如何配置 ASP.NET 应用程序的详细信息,请访问
|
||||
https://go.microsoft.com/fwlink/?LinkId=301879
|
||||
-->
|
||||
<configuration>
|
||||
<appSettings>
|
||||
<add key="TenpayOptions_Merchant_0_MerchantId" value="填写商户号" />
|
||||
<add key="TenpayOptions_Merchant_0_SecretV3" value="填写商户 V3 API 密钥" />
|
||||
<add key="TenpayOptions_Merchant_0_CertificateSerialNumber" value="填写商户证书序列号" />
|
||||
<add key="TenpayOptions_Merchant_0_CertificatePrivateKey" value="填写商户证书文件内容" />
|
||||
<add key="TenpayOptions_Merchant_0_PlatformPublicKeyId" value="填写平台公钥 ID(仅当基于平台公钥的认证方式时需要)" />
|
||||
<add key="TenpayOptions_Merchant_0_PlatformPublicKey" value="填写平台公钥内容(仅当基于平台公钥的认证方式时需要)" />
|
||||
<add key="TenpayOptions_NotifyUrl" value="https://localhost:5001" />
|
||||
</appSettings>
|
||||
<system.web>
|
||||
<compilation debug="true" targetFramework="4.8" />
|
||||
<httpRuntime targetFramework="4.8" />
|
||||
</system.web>
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
|
||||
<remove name="OPTIONSVerbHandler" />
|
||||
<remove name="TRACEVerbHandler" />
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
</handlers>
|
||||
</system.webServer>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-13.0.0.0" newVersion="13.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Web.Infrastructure" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
|
||||
<bindingRedirect oldVersion="1.0.0.0-5.2.9.0" newVersion="5.2.9.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.9.0" newVersion="5.2.9.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.9.0" newVersion="5.2.9.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.4.0.0" newVersion="6.4.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-8.0.0.5" newVersion="8.0.0.5" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<system.codedom>
|
||||
<compilers>
|
||||
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
|
||||
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
|
||||
</compilers>
|
||||
</system.codedom>
|
||||
</configuration>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Antlr" version="3.5.0.2" targetFramework="net48" />
|
||||
<package id="Autofac" version="6.4.0" targetFramework="net48" />
|
||||
<package id="Autofac.Mvc5" version="6.1.0" targetFramework="net48" />
|
||||
<package id="Autofac.WebApi2" version="6.1.1" targetFramework="net48" />
|
||||
<package id="bootstrap" version="5.2.3" targetFramework="net48" />
|
||||
<package id="Flurl" version="4.0.0" targetFramework="net48" />
|
||||
<package id="Flurl.Http" version="4.0.2" targetFramework="net48" />
|
||||
<package id="Hangfire.AspNet" version="0.3.0" targetFramework="net48" />
|
||||
<package id="Hangfire.Autofac" version="2.7.0" targetFramework="net48" />
|
||||
<package id="Hangfire.Core" version="1.8.0" targetFramework="net48" />
|
||||
<package id="Hangfire.InMemory" version="1.0.0" targetFramework="net48" />
|
||||
<package id="jQuery" version="3.7.0" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.Mvc" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.Mvc.zh-Hans" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.Razor" version="3.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.Razor.zh-Hans" version="3.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.Web.Optimization.zh-Hans" version="1.1.3" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.Client.zh-Hans" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core.zh-Hans" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.HelpPage" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebApi.WebHost.zh-Hans" version="5.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebPages" version="3.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.AspNet.WebPages.zh-Hans" version="3.2.9" targetFramework="net48" />
|
||||
<package id="Microsoft.Bcl.AsyncInterfaces" version="8.0.0" targetFramework="net48" />
|
||||
<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net48" />
|
||||
<package id="Microsoft.Owin" version="3.0.1" targetFramework="net48" />
|
||||
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net48" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="2.0.0" targetFramework="net48" />
|
||||
<package id="Modernizr" version="2.8.3" targetFramework="net48" />
|
||||
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" />
|
||||
<package id="Owin" version="1.0" targetFramework="net48" />
|
||||
<package id="SKIT.FlurlHttpClient.Common" version="3.1.1" targetFramework="net48" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||
<package id="System.Diagnostics.DiagnosticSource" version="4.7.1" targetFramework="net48" />
|
||||
<package id="System.Memory" version="4.5.5" targetFramework="net48" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net48" />
|
||||
<package id="System.Text.Encodings.Web" version="8.0.0" targetFramework="net48" />
|
||||
<package id="System.Text.Json" version="8.0.5" targetFramework="net48" />
|
||||
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net48" />
|
||||
<package id="System.ValueTuple" version="4.5.0" targetFramework="net48" />
|
||||
<package id="WebGrease" version="1.6.0" targetFramework="net48" />
|
||||
</packages>
|
||||
Reference in New Issue
Block a user