mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2026-01-09 09:55:10 +08:00
feat(tenpayv3): 升级公共组件
This commit is contained in:
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using System.Linq;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
internal class TextualStringIListWithCommaConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
bool ret = objectType == typeof(IList<string>) || objectType == typeof(List<string>);
|
||||
if (!ret)
|
||||
{
|
||||
ret = objectType.IsGenericType &&
|
||||
objectType.GetGenericTypeDefinition() == typeof(List<>) &&
|
||||
objectType.GetElementType() == typeof(string);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
string? value = serializer.Deserialize<string>(reader);
|
||||
if (value == null)
|
||||
return null;
|
||||
if (string.IsNullOrEmpty(value))
|
||||
return new List<string>();
|
||||
|
||||
return value.Split(',').ToList();
|
||||
}
|
||||
|
||||
throw new JsonReaderException();
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value != null)
|
||||
writer.WriteValue(string.Join(",", value));
|
||||
else
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
internal class TextualStringIListWithJsonConverter : JsonConverter<IList<string>?>
|
||||
{
|
||||
private readonly JsonConverter<List<string>?> _converter = new TextualStringListWithJsonConverter();
|
||||
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override IList<string>? ReadJson(JsonReader reader, Type objectType, IList<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
return _converter.ReadJson(reader, objectType, ConvertIListToList(existingValue), hasExistingValue, serializer);
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, IList<string>? value, JsonSerializer serializer)
|
||||
{
|
||||
_converter.WriteJson(writer, ConvertIListToList(value), serializer);
|
||||
}
|
||||
|
||||
private List<string>? ConvertIListToList(IList<string>? src)
|
||||
{
|
||||
if (src == null)
|
||||
return null;
|
||||
|
||||
List<string>? dest = src as List<string>;
|
||||
if (dest != null)
|
||||
return dest;
|
||||
|
||||
return new List<string>(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
internal class TextualStringListWithCommaConverter : JsonConverter<List<string>?>
|
||||
{
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override List<string>? ReadJson(JsonReader reader, Type objectType, List<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
string? value = serializer.Deserialize<string>(reader);
|
||||
if (value == null)
|
||||
return existingValue;
|
||||
|
||||
return value.Split(',').ToList();
|
||||
}
|
||||
|
||||
throw new JsonReaderException();
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, List<string>? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value != null)
|
||||
writer.WriteValue(string.Join(",", value));
|
||||
else
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
namespace Newtonsoft.Json.Converters
|
||||
{
|
||||
internal class TextualStringListWithJsonConverter : JsonConverter<List<string>?>
|
||||
{
|
||||
public override bool CanRead
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public override List<string>? ReadJson(JsonReader reader, Type objectType, List<string>? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonToken.String)
|
||||
{
|
||||
string? value = serializer.Deserialize<string>(reader);
|
||||
if (value == null)
|
||||
return existingValue;
|
||||
|
||||
return JsonConvert.DeserializeObject<List<string>>(value);
|
||||
}
|
||||
|
||||
throw new JsonReaderException();
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, List<string>? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value != null)
|
||||
writer.WriteValue(JsonConvert.SerializeObject(value, Formatting.None));
|
||||
else
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace System.Text.Json.Converters
|
||||
{
|
||||
internal class TextualStringIListWithCommaConverter : JsonConverter<List<string>?>
|
||||
{
|
||||
public override List<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
string? value = reader.GetString();
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
return value.Split(',').ToList();
|
||||
}
|
||||
|
||||
throw new JsonException();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, List<string>? value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value != null)
|
||||
writer.WriteStringValue(string.Join(",", value));
|
||||
else
|
||||
writer.WriteNullValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace System.Text.Json.Converters
|
||||
{
|
||||
internal class TextualStringIListWithJsonConverter : JsonConverter<IList<string>?>
|
||||
{
|
||||
private readonly JsonConverter<List<string>?> _converter = new TextualStringListWithJsonConverter();
|
||||
|
||||
public override IList<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return _converter.Read(ref reader, typeToConvert, options);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, IList<string>? value, JsonSerializerOptions options)
|
||||
{
|
||||
_converter.Write(writer, ConvertIListToList(value), options);
|
||||
}
|
||||
|
||||
private List<string>? ConvertIListToList(IList<string>? src)
|
||||
{
|
||||
if (src == null)
|
||||
return null;
|
||||
|
||||
List<string>? dest = src as List<string>;
|
||||
if (dest != null)
|
||||
return dest;
|
||||
|
||||
return new List<string>(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace System.Text.Json.Converters
|
||||
{
|
||||
internal class TextualStringListWithCommaConverter : JsonConverter<IList<string>?>
|
||||
{
|
||||
private readonly JsonConverter<List<string>?> _converter = new TextualStringIListWithCommaConverter();
|
||||
|
||||
public override IList<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
return _converter.Read(ref reader, typeToConvert, options);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, IList<string>? value, JsonSerializerOptions options)
|
||||
{
|
||||
_converter.Write(writer, ConvertIListToList(value), options);
|
||||
}
|
||||
|
||||
private List<string>? ConvertIListToList(IList<string>? src)
|
||||
{
|
||||
if (src == null)
|
||||
return null;
|
||||
|
||||
List<string>? dest = src as List<string>;
|
||||
if (dest != null)
|
||||
return dest;
|
||||
|
||||
return new List<string>(src);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace System.Text.Json.Converters
|
||||
{
|
||||
internal class TextualStringListWithJsonConverter : JsonConverter<List<string>?>
|
||||
{
|
||||
public override List<string>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (reader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
string? value = reader.GetString();
|
||||
if (value == null)
|
||||
return null;
|
||||
|
||||
return JsonSerializer.Deserialize<List<string>>(value, options);
|
||||
}
|
||||
|
||||
throw new JsonException();
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, List<string>? value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value != null)
|
||||
writer.WriteStringValue(JsonSerializer.Serialize(value, options));
|
||||
else
|
||||
writer.WriteNullValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -692,9 +692,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||
/// 获取或设置优惠费率活动值。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("activities_rate")]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Converters.NewtonsoftJsonActivityRateConverter))]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Converters.RequestPropertyActivityRateNewtonsoftJsonConverter))]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("activities_rate")]
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.SystemTextJsonActivityRateConverter))]
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.RequestPropertyActivityRateSystemTextJsonConverter))]
|
||||
public double? ActivityRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -793,7 +793,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||
|
||||
internal static class Converters
|
||||
{
|
||||
internal class NewtonsoftJsonActivityRateConverter : Newtonsoft.Json.JsonConverter<double?>
|
||||
internal class RequestPropertyActivityRateNewtonsoftJsonConverter : Newtonsoft.Json.JsonConverter<double?>
|
||||
{
|
||||
public override bool CanRead
|
||||
{
|
||||
@@ -837,7 +837,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||
}
|
||||
}
|
||||
|
||||
internal class SystemTextJsonActivityRateConverter : System.Text.Json.Serialization.JsonConverter<double?>
|
||||
internal class RequestPropertyActivityRateSystemTextJsonConverter : System.Text.Json.Serialization.JsonConverter<double?>
|
||||
{
|
||||
public override double? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
|
||||
{
|
||||
|
||||
@@ -280,6 +280,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||
}
|
||||
}
|
||||
|
||||
internal static class Converters
|
||||
{
|
||||
public class RequestPropertyMediaIdListNewtonsoftJsonConverter : Newtonsoft.Json.Converters.TextualObjectInJsonFormatConverterBase<IList<string>>
|
||||
{
|
||||
}
|
||||
|
||||
public class RequestPropertyMediaIdListSystemTextJsonConverter : System.Text.Json.Converters.TextualObjectInJsonFormatConverterBase<IList<string>>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置业务申请编号。
|
||||
/// </summary>
|
||||
@@ -368,18 +379,18 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
|
||||
/// 获取或设置特殊资质图片媒体文件标识 ID 列表。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("qualifications")]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.TextualStringIListWithJsonConverter))]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Converters.RequestPropertyMediaIdListNewtonsoftJsonConverter))]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("qualifications")]
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.TextualStringIListWithJsonConverter))]
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.RequestPropertyMediaIdListSystemTextJsonConverter))]
|
||||
public IList<string>? QualificationPictureMediaIdList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置补充材料媒体文件标识 ID 列表。
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("business_addition_pics")]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.TextualStringIListWithJsonConverter))]
|
||||
[Newtonsoft.Json.JsonConverter(typeof(Converters.RequestPropertyMediaIdListNewtonsoftJsonConverter))]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("business_addition_pics")]
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Converters.TextualStringIListWithJsonConverter))]
|
||||
[System.Text.Json.Serialization.JsonConverter(typeof(Converters.RequestPropertyMediaIdListSystemTextJsonConverter))]
|
||||
public IList<string>? BusinessAdditionPictureMediaIdList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
27
src/SKIT.FlurlHttpClient.Wechat.TenpayV3/README.md
Normal file
27
src/SKIT.FlurlHttpClient.Wechat.TenpayV3/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
|
||||
[](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) [](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) [](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3) [](https://mit-license.org/)
|
||||
|
||||
基于 `Flurl.Http` 的微信商户平台 API v3 版客户端。
|
||||
|
||||
---
|
||||
|
||||
### 【功能特性】
|
||||
|
||||
- 基于微信支付 v3 版 API 封装。
|
||||
- 支持直连商户、服务商两种模式。
|
||||
- 请求时自动生成签名,无需开发者手动干预。
|
||||
- 提供了微信支付所需的 RSA、AES、SHA-256 等算法工具类。
|
||||
- 提供了调起支付签名、解析响应敏感数据、解析回调通知事件敏感数据等扩展方法。
|
||||
|
||||
---
|
||||
|
||||
### 【开发文档】
|
||||
|
||||
[点此查看](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat)。
|
||||
|
||||
---
|
||||
|
||||
### 【更新日志】
|
||||
|
||||
[点此查看](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat/blob/main/CHANGELOG.md)。
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageId>SKIT.FlurlHttpClient.Wechat.TenpayV3</PackageId>
|
||||
<PackageIcon>LOGO.png</PackageIcon>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat</PackageProjectUrl>
|
||||
<PackageTags>Flurl.Http Wechat Weixin MicroMessage Tenpay WechatPay WeixinPay Wxpay 微信 微信支付 微信商户</PackageTags>
|
||||
@@ -17,11 +19,22 @@
|
||||
<Authors>Fu Diwei</Authors>
|
||||
<RepositoryType>git</RepositoryType>
|
||||
<RepositoryUrl>https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git</RepositoryUrl>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
|
||||
<Deterministic>true</Deterministic>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../../LOGO.png" Pack="true" PackagePath="/" />
|
||||
<None Include="README.md" Pack="true" PackagePath="/" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Web" Condition="'$(TargetFramework)' == 'net461' Or '$(TargetFramework)' == 'net47'" />
|
||||
</ItemGroup>
|
||||
@@ -29,7 +42,7 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net461'" />
|
||||
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.1.1" />
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -10,7 +10,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
|
||||
public static class SHA256Utility
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取信息摘要。
|
||||
/// 获取 SHA-256 信息摘要。
|
||||
/// </summary>
|
||||
/// <param name="bytes">信息字节数组。</param>
|
||||
/// <returns>信息摘要。</returns>
|
||||
@@ -24,7 +24,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取信息摘要。
|
||||
/// 获取 SHA-256 信息摘要。
|
||||
/// </summary>
|
||||
/// <param name="message">文本信息。</param>
|
||||
/// <returns>信息摘要。</returns>
|
||||
|
||||
Reference in New Issue
Block a user