feat(tenpayv3): 升级公共组件

This commit is contained in:
Fu Diwei
2022-01-21 13:10:56 +08:00
parent 3656eb176f
commit b442a3d618
48 changed files with 304 additions and 569 deletions

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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)
{

View File

@@ -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>

View File

@@ -0,0 +1,27 @@
## SKIT.FlurlHttpClient.Wechat.TenpayV3
[![GitHub Stars](https://img.shields.io/github/stars/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat?logo=github&label=Stars)](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) [![GitHub Forks](https://img.shields.io/github/forks/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat?logo=github&label=Forks)](https://github.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat) [![NuGet Download](https://img.shields.io/nuget/dt/SKIT.FlurlHttpClient.Wechat.TenpayV3.svg?sanitize=true&label=Downloads)](https://www.nuget.org/packages/SKIT.FlurlHttpClient.Wechat.TenpayV3) [![License](https://img.shields.io/github/license/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat?label=License)](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)。

View File

@@ -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>

View File

@@ -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>