feat(tenpayv3): 适配国密接入模式

This commit is contained in:
Fu Diwei
2022-11-13 23:17:18 +08:00
parent 74a4c72f78
commit d18985f260
53 changed files with 995 additions and 389 deletions

View File

@@ -62,7 +62,7 @@ public class MyFakeRequest : WechatTenpayRequest
{
[Newtonsoft.Json.JsonProperty("my_fake_props")]
[System.Text.Json.Serialization.JsonPropertyName("my_fake_props")]
[WechatTenpaySensitiveProperty("my_alg")]
[WechatTenpaySensitiveProperty("my_scheme", "my_alg")]
public string MyFakeProps { get; set; }
}
@@ -71,7 +71,7 @@ public class MyFakeResponse : WechatTenpayResponse
{
[Newtonsoft.Json.JsonProperty("my_fake_props")]
[System.Text.Json.Serialization.JsonPropertyName("my_fake_props")]
[WechatTenpaySensitiveProperty("my_alg")]
[WechatTenpaySensitiveProperty("my_scheme", "my_alg")]
public string MyFakeProps { get; set; }
}
```

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
@@ -34,18 +34,19 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.BackgroundService
{
try
{
const string ALGORITHM_TYPE = "RSA";
var client = _tenpayHttpClientFactory.Create(tenpayMerchantOptions.MerchantId);
var request = new QueryCertificatesRequest();
var request = new QueryCertificatesRequest() { AlgorithmType = ALGORITHM_TYPE };
var response = await client.ExecuteQueryCertificatesAsync(request, cancellationToken: stoppingToken);
if (response.IsSuccessful())
{
// NOTICE:
// 如果启用了 `AutoDecryptResponseSensitiveProperty` 配置项,则无需再手动执行下面被注释的解密方法:
// 如果构造 Client 时启用了 `AutoDecryptResponseSensitiveProperty` 配置项,则无需再手动执行下面被注释的解密方法:
// response = client.DecryptResponseSensitiveProperty(response);
foreach (var certificateModel in response.CertificateList)
foreach (var certificate in response.CertificateList)
{
client.PlatformCertificateManager.AddEntry(new CertificateEntry(certificateModel));
client.PlatformCertificateManager.AddEntry(new CertificateEntry(ALGORITHM_TYPE, certificate));
}
_logger.LogInformation("刷新微信商户平台证书成功。");

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.BackgroundJobs
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Sample.Services.BackgroundJobs
{
internal class TenpayCertificateRefreshingBackgroundJob
{
@@ -16,18 +16,19 @@
{
try
{
const string ALGORITHM_TYPE = "RSA";
var client = _tenpayHttpClientFactory.Create(tenpayMerchantOptions.MerchantId);
var request = new QueryCertificatesRequest();
var request = new QueryCertificatesRequest() { AlgorithmType = ALGORITHM_TYPE };
var response = await client.ExecuteQueryCertificatesAsync(request);
if (response.IsSuccessful())
{
// NOTICE:
// 如果启用了 `AutoDecryptResponseSensitiveProperty` 配置项,则无需再手动执行下面被注释的解密方法:
// 如果构造 Client 时启用了 `AutoDecryptResponseSensitiveProperty` 配置项,则无需再手动执行下面被注释的解密方法:
// response = client.DecryptResponseSensitiveProperty(response);
foreach (var certificateModel in response.CertificateList)
foreach (var certificate in response.CertificateList)
{
client.CertificateManager.AddEntry(new CertificateEntry(certificateModel));
client.CertificateManager.AddEntry(new CertificateEntry(ALGORITHM_TYPE, certificate));
}
Debug.WriteLine("刷新微信商户平台证书成功。");

View File

@@ -1,14 +1,17 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class WechatTenpaySensitivePropertyAttribute : Attribute
{
public string Scheme { get; }
public string Algorithm { get; }
public WechatTenpaySensitivePropertyAttribute(string algorithm)
public WechatTenpaySensitivePropertyAttribute(string scheme, string algorithm)
{
Scheme = scheme;
Algorithm = algorithm;
}
}

View File

@@ -1,11 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Constants
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Constants
{
public static class EncryptionAlgorithms
{
public const string AEAD_AES_256_GCM = "AEAD_AES_256_GCM";
public const string AEAD_SM4_128_GCM = "AEAD_SM4_GCM";
public const string RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1 = "RSA_2048_ECB_PKCS8_OAEPWithSHA-1AndMGF1";
public const string RSA_2048_ECB_PKCS1 = "RSA_2048_ECB_PKCS1";
public const string SM2_C1C3C2_ASN1 = "SM2_C1C3C2_ASN1";
}
}

View File

@@ -1,10 +1,15 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Constants
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Constants
{
public static class SignSchemes
{
/// <summary>
/// WECHATPAY2-SHA256-RSA2048
/// RSA 算法RSA2048 Sign with SHA256
/// </summary>
public const string WECHATPAY2_SHA256_RSA2048 = "WECHATPAY2-SHA256-RSA2048";
public const string WECHATPAY2_RSA_2048_WITH_SHA256 = "WECHATPAY2-SHA256-RSA2048";
/// <summary>
/// 国密算法SM2 Sign with SM3。
/// </summary>
public const string WECHATPAY2_SM2_WITH_SM3 = "WECHATPAY2-SM2-WITH-SM3";
}
}

View File

@@ -1,70 +1,98 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
internal static class WechatTenpayClientSignExtensions
{
public static bool VerifySignature(this WechatTenpayClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber)
{
return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, Constants.SignSchemes.WECHATPAY2_SHA256_RSA2048, out _);
}
public static bool VerifySignature(this WechatTenpayClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber, string strSignScheme)
{
return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, strSignScheme, out _);
}
public static bool VerifySignature(this WechatTenpayClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber, out Exception? error)
{
return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, Constants.SignSchemes.WECHATPAY2_SHA256_RSA2048, out error);
}
public static bool VerifySignature(this WechatTenpayClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber, string strSignScheme, out Exception? error)
public static bool VerifySignature(this WechatTenpayClient client, string strTimestamp, string strNonce, string strContent, string strSignature, string strSignatureScheme, string strSerialNumber, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
switch (strSignScheme)
switch (strSignatureScheme)
{
case Constants.SignSchemes.WECHATPAY2_SHA256_RSA2048:
case Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256:
{
if (client.PlatformCertificateManager != null)
if (client.PlatformCertificateManager == null)
{
try
{
var cert = client.PlatformCertificateManager.GetEntry(strSerialNumber);
if (!cert.HasValue)
{
error = new Exceptions.WechatTenpayEventVerificationException("There is no platform certificate matched the serial number.");
return false;
}
error = null;
return Utilities.RSAUtility.VerifyWithSHA256ByCertificate(
certificate: cert.Value.Certificate,
plainText: GetPlainTextForSignature(timestamp: strTimestamp, nonce: strNonce, body: strBody),
signature: strSignature
);
}
catch (Exception ex)
{
error = ex;
return false;
}
error = new Exception("The platform certificate manager is not initialized.");
return false;
}
error = new Exception("There is no platform certificate in the certificate manager.");
return false;
var entry = client.PlatformCertificateManager.GetEntry(strSerialNumber);
if (!entry.HasValue)
{
error = new Exception($"There is no platform certificate matched the serial number: \"{strSerialNumber}\", please make sure you have downloaded platform certificates first.");
return false;
}
if (!Settings.CertificateEntry.ALGORITHM_TYPE_RSA.Equals(entry.Value.AlgorithmType))
{
error = new Exception($"The platform certificate with serial number: \"{strSerialNumber}\" is not for RSA.");
return false;
}
error = null;
try
{
return Utilities.RSAUtility.VerifyWithSHA256ByCertificate(
certificate: entry.Value.Certificate,
message: GenerateMessageForSignature(timestamp: strTimestamp, nonce: strNonce, body: strContent),
signature: strSignature
);
}
catch (Exception ex)
{
error = ex;
return false;
}
}
case Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3:
{
if (client.PlatformCertificateManager == null)
{
error = new Exception("The platform certificate manager is not initialized.");
return false;
}
var entry = client.PlatformCertificateManager.GetEntry(strSerialNumber);
if (!entry.HasValue)
{
error = new Exception($"There is no platform certificate matched the serial number: \"{strSerialNumber}\", please make sure you have downloaded platform certificates first.");
return false;
}
if (!Settings.CertificateEntry.ALGORITHM_TYPE_SM2.Equals(entry.Value.AlgorithmType))
{
error = new Exception($"The platform certificate with serial number: \"{strSerialNumber}\" is not for SM2.");
return false;
}
error = null;
try
{
return Utilities.SM2Utility.VerifyWithSM3ByCertificate(
certificate: entry.Value.Certificate,
message: GenerateMessageForSignature(timestamp: strTimestamp, nonce: strNonce, body: strContent),
signature: strSignature
);
}
catch (Exception ex)
{
error = ex;
return false;
}
}
default:
{
error = new Exception("Unsupported sign scheme.");
error = new Exception($"Unsupported signature scheme: \"{strSignatureScheme}\".");
return false;
}
}
}
private static string GetPlainTextForSignature(string timestamp, string nonce, string body)
private static string GenerateMessageForSignature(string timestamp, string nonce, string body)
{
return $"{timestamp}\n{nonce}\n{body}\n";
}

View File

@@ -1,4 +1,5 @@
using System;
using System;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
@@ -51,26 +52,55 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
if (resource == null) throw new ArgumentNullException(nameof(resource));
string plainJson;
switch (resource.Algorithm)
{
case Constants.EncryptionAlgorithms.AEAD_AES_256_GCM:
{
try
{
plainJson = Utilities.AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
nonce: resource.Nonce,
aad: resource.AssociatedData,
cipherText: resource.CipherText
);
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayEventDecryptionException("Decrypt event resource failed. Please see the `InnerException` for more details.", ex);
}
}
break;
if (Constants.EncryptionAlgorithms.AEAD_AES_256_GCM.Equals(resource.Algorithm))
{
try
{
plainJson = Utilities.AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
iv: resource.Nonce,
aad: resource.AssociatedData,
cipherText: resource.CipherText
);
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayEventDecryptionException("Decrypt event resource failed. Please see the `InnerException` for more details.", ex);
}
}
else
{
throw new Exceptions.WechatTenpayEventDecryptionException("Unsupported encrypt algorithm of the resource.");
case Constants.EncryptionAlgorithms.AEAD_SM4_128_GCM:
{
try
{
// REF: https://pay.weixin.qq.com/docs/merchant/development/shangmi/guide.html
// 由于 SM4 密钥长度的限制,密钥由 APIv3 密钥通过国密 SM3 Hash 计算生成。SM4 密钥取其摘要256bit的前 128bit。
byte[] secretBytes = Utilities.SM3Utility.Hash(Encoding.UTF8.GetBytes(client.Credentials.MerchantV3Secret));
byte[] keyBytes = new byte[16];
Array.Copy(secretBytes, keyBytes, keyBytes.Length);
byte[] plainBytes = Utilities.SM4Utility.DecryptWithGCM(
keyBytes: keyBytes,
nonceBytes: Encoding.UTF8.GetBytes(resource.Nonce),
aadBytes: Encoding.UTF8.GetBytes(resource.AssociatedData),
cipherBytes: Convert.FromBase64String(resource.CipherText)
);
plainJson = Encoding.UTF8.GetString(plainBytes);
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayEventDecryptionException("Decrypt event resource failed. Please see the `InnerException` for more details.", ex);
}
}
break;
default:
{
throw new Exceptions.WechatTenpayEventDecryptionException($"Unsupported encryption algorithm: \"{resource.Algorithm}\".");
}
}
return client.JsonSerializer.Deserialize<T>(plainJson);

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
@@ -21,7 +21,42 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// <returns></returns>
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber)
{
return VerifyEventSignature(client, callbackTimestamp, callbackNonce, callbackBody, callbackSignature, callbackSerialNumber, out _);
return VerifyEventSignature(
client,
callbackTimestamp: callbackTimestamp,
callbackNonce: callbackNonce,
callbackBody: callbackBody,
callbackSignature: callbackSignature,
callbackSignatureType: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256,
callbackSerialNumber: callbackSerialNumber
);
}
/// <summary>
/// <para>验证回调通知事件签名。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="callbackTimestamp">微信回调通知中的 Wechatpay-Timestamp 字段。</param>
/// <param name="callbackNonce">微信回调通知中的 Wechatpay-Nonce 字段。</param>
/// <param name="callbackBody">微信回调通知中请求正文。</param>
/// <param name="callbackSignature">微信回调通知中的 Wechatpay-Signature 字段。</param>
/// <param name="callbackSignatureType">微信回调通知中的 Wechatpay-Signature-Type 字段。</param>
/// <param name="callbackSerialNumber">微信回调通知中的 Wechatpay-Serial 字段。</param>
/// <returns></returns>
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSignatureType, string callbackSerialNumber)
{
return VerifyEventSignature(
client,
callbackTimestamp: callbackTimestamp,
callbackNonce: callbackNonce,
callbackBody: callbackBody,
callbackSignature: callbackSignature,
callbackSignatureType: callbackSignatureType,
callbackSerialNumber: callbackSerialNumber,
out _
);
}
/// <summary>
@@ -39,17 +74,60 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber, out Exception? error)
{
return VerifyEventSignature(
client,
callbackTimestamp: callbackTimestamp,
callbackNonce: callbackNonce,
callbackBody: callbackBody,
callbackSignature: callbackSignature,
callbackSignatureType: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256,
callbackSerialNumber: callbackSerialNumber,
out error
);
}
/// <summary>
/// <para>验证回调通知事件签名。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="callbackTimestamp">微信回调通知中的 Wechatpay-Timestamp 字段。</param>
/// <param name="callbackNonce">微信回调通知中的 Wechatpay-Nonce 字段。</param>
/// <param name="callbackBody">微信回调通知中请求正文。</param>
/// <param name="callbackSignature">微信回调通知中的 Wechatpay-Signature 字段。</param>
/// <param name="callbackSignatureType">微信回调通知中的 Wechatpay-Signature-Type 字段。</param>
/// <param name="callbackSerialNumber">微信回调通知中的 Wechatpay-Serial 字段。</param>
/// <param name="error"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSignatureType, string callbackSerialNumber, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (callbackTimestamp == null) throw new ArgumentNullException(nameof(callbackTimestamp));
if (callbackNonce == null) throw new ArgumentNullException(nameof(callbackNonce));
if (callbackBody == null) throw new ArgumentNullException(nameof(callbackBody));
if (callbackSignature == null) throw new ArgumentNullException(nameof(callbackSignature));
if (callbackSignatureType == null) throw new ArgumentNullException(nameof(callbackSignatureType));
if (callbackSerialNumber == null) throw new ArgumentNullException(nameof(callbackSerialNumber));
bool ret = WechatTenpayClientSignExtensions.VerifySignature(client, callbackTimestamp, callbackNonce, callbackBody, callbackSignature, callbackSerialNumber, out error);
bool ret = WechatTenpayClientSignExtensions.VerifySignature(
client,
strTimestamp: callbackTimestamp,
strNonce: callbackNonce,
strContent: callbackBody,
strSignature: callbackSignature,
strSignatureScheme: callbackSignatureType,
strSerialNumber: callbackSerialNumber,
out error
);
if (error != null)
{
error = new Exceptions.WechatTenpayEventVerificationException("Verify signature of event failed. Please see the `InnerException` for more details.", error);
}
return ret;
}
}

View File

@@ -37,7 +37,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
string package = $"prepay_id={prepayId}";
string sign = Utilities.RSAUtility.SignWithSHA256(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
plainText: $"{appId}\n{timestamp}\n{nonce}\n{package}\n"
message: $"{appId}\n{timestamp}\n{nonce}\n{package}\n"
);
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
@@ -92,7 +92,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
string nonce = Guid.NewGuid().ToString("N");
string sign = Utilities.RSAUtility.SignWithSHA256(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
plainText: $"{appId}\n{timestamp}\n{nonce}\n{prepayId}\n"
message: $"{appId}\n{timestamp}\n{nonce}\n{prepayId}\n"
);
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()

View File

@@ -1,6 +1,7 @@
using System;
using System;
using System.Linq;
using System.Reflection;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
@@ -9,6 +10,147 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// </summary>
public static class WechatTenpayClientRequestEncryptionExtensions
{
private static TRequest InnerEncryptRequestSensitivePropertyByRSA<TRequest>(WechatTenpayClient client, TRequest request)
where TRequest : WechatTenpayRequest
{
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref request, (target, currentProp, oldValue) =>
{
var attribute = currentProp
.GetCustomAttributes<WechatTenpaySensitivePropertyAttribute>()
.FirstOrDefault(attr => Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256.Equals(attr.Scheme));
if (attribute == null)
return (false, oldValue);
if (client.PlatformCertificateManager == null)
throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed, because the platform certificate manager is not initialized.");
string certificate;
if (string.IsNullOrEmpty(request.WechatpayCertificateSerialNumber))
{
// 如果未在请求中指定特定的平台证书序列号,从管理器中取过期时间最远的
var entries = client.PlatformCertificateManager.AllEntries()
.Where(e => Settings.CertificateEntry.ALGORITHM_TYPE_RSA.Equals(e.AlgorithmType))
.OrderByDescending(e => e.ExpireTime);
if (!entries.Any())
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate in the manager, please make sure you have downloaded platform certificates first.");
}
var entry = entries.First();
certificate = entry.Certificate;
request.WechatpayCertificateSerialNumber = entry.SerialNumber;
}
else
{
// 如果已在请求中指定特定的平台证书序列号,直接从管理器中取值
var entry = client.PlatformCertificateManager.GetEntry(request.WechatpayCertificateSerialNumber!);
if (!entry.HasValue)
{
throw new Exceptions.WechatTenpayEventVerificationException($"Encrypt request failed, because there is no platform certificate matched the serial number: \"{request.WechatpayCertificateSerialNumber}\", please make sure you have downloaded platform certificates first.");
}
certificate = entry.Value.Certificate;
}
string newValue;
switch (attribute.Algorithm)
{
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1:
{
newValue = Utilities.RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: oldValue
);
}
break;
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1:
{
newValue = Utilities.RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: oldValue,
paddingMode: "PKCS1PADDING"
);
}
break;
default:
{
throw new Exceptions.WechatTenpayRequestEncryptionException($"Unsupported encryption algorithm: \"{attribute.Algorithm}\".");
}
}
return (true, newValue);
});
return request;
}
private static TRequest InnerEncryptRequestSensitivePropertyBySM<TRequest>(WechatTenpayClient client, TRequest request)
where TRequest : WechatTenpayRequest
{
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref request, (target, currentProp, oldValue) =>
{
var attribute = currentProp
.GetCustomAttributes<WechatTenpaySensitivePropertyAttribute>()
.FirstOrDefault(attr => Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3.Equals(attr.Scheme));
if (attribute == null)
return (false, oldValue);
if (client.PlatformCertificateManager == null)
throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed, because the platform certificate manager is not initialized.");
string certificate;
if (string.IsNullOrEmpty(request.WechatpayCertificateSerialNumber))
{
// 如果未在请求中指定特定的平台证书序列号,从管理器中取过期时间最远的
var entries = client.PlatformCertificateManager.AllEntries()
.Where(e => Settings.CertificateEntry.ALGORITHM_TYPE_SM2.Equals(e.AlgorithmType))
.OrderByDescending(e => e.ExpireTime);
if (!entries.Any())
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate in the manager, please make sure you have downloaded platform certificates first.");
}
var entry = entries.First();
certificate = entry.Certificate;
request.WechatpayCertificateSerialNumber = entry.SerialNumber;
}
else
{
// 如果已在请求中指定特定的平台证书序列号,直接从管理器中取值
var entry = client.PlatformCertificateManager.GetEntry(request.WechatpayCertificateSerialNumber!);
if (!entry.HasValue)
{
throw new Exceptions.WechatTenpayEventVerificationException($"Encrypt request failed, because there is no platform certificate matched the serial number: \"{request.WechatpayCertificateSerialNumber}\", please make sure you have downloaded platform certificates first.");
}
certificate = entry.Value.Certificate;
}
string newValue;
switch (attribute.Algorithm)
{
case Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1:
{
newValue = Utilities.SM2Utility.EncryptByCertificate(
certificate: certificate,
plainText: oldValue,
asn1Encoding: true
);
}
break;
default:
{
throw new Exceptions.WechatTenpayRequestEncryptionException($"Unsupported encryption algorithm: \"{attribute.Algorithm}\".");
}
}
return (true, newValue);
});
return request;
}
/// <summary>
/// <para>加密请求中传入的敏感数据。该方法会改变传入的请求模型对象。</para>
/// </summary>
@@ -23,81 +165,30 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
try
{
// 遍历并加密被标记为敏感数据的字段
bool requireEncrypt = Attribute.IsDefined(request.GetType(), typeof(WechatTenpaySensitiveAttribute));
if (requireEncrypt)
{
// 遍历并加密被标记为敏感数据的字段
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref request, (target, currentProp, oldValue) =>
switch (client.Credentials.SignScheme)
{
var attr = currentProp.GetCustomAttribute<WechatTenpaySensitivePropertyAttribute>();
if (attr == null)
return (false, oldValue);
case Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256:
return InnerEncryptRequestSensitivePropertyByRSA(client, request);
if (Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1.Equals(attr.Algorithm) ||
Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1.Equals(attr.Algorithm))
{
if (client.PlatformCertificateManager == null)
throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed, because there is no platform certificate in the manager.");
string certificate;
if (!string.IsNullOrEmpty(request.WechatpayCertificateSerialNumber))
{
// 如果已在请求中指定特定的平台证书序列号,直接从管理器中取值
var cert = client.PlatformCertificateManager.GetEntry(request.WechatpayCertificateSerialNumber!);
if (!cert.HasValue)
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate matched the serial number.");
}
certificate = cert.Value.Certificate;
}
else
{
// 如果未在请求中指定特定的平台证书序列号,从管理器中取过期时间最远的
var certs = client.PlatformCertificateManager.AllEntries().OrderByDescending(e => e.ExpireTime);
if (!certs.Any())
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate in the manager.");
}
var cert = certs.First();
certificate = cert.Certificate;
request.WechatpayCertificateSerialNumber = cert.SerialNumber;
}
string newValue = oldValue;
if (Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1.Equals(attr.Algorithm))
{
newValue = Utilities.RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: oldValue
);
}
else if (Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1.Equals(attr.Algorithm))
{
newValue = Utilities.RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: oldValue,
paddingMode: "PKCS1PADDING"
);
}
return (true, newValue);
}
else
{
throw new Exceptions.WechatTenpayRequestEncryptionException("Unsupported encryption algorithm.");
}
});
case Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3:
return InnerEncryptRequestSensitivePropertyBySM(client, request);
}
}
return request;
}
catch (Exception ex) when (!(ex is Exceptions.WechatTenpayRequestEncryptionException))
catch (WechatTenpayException)
{
throw;
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed. Please see the `InnerException` for more details.", ex);
}
return request;
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System;
using System.Linq;
using System.Reflection;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
@@ -9,6 +10,143 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// </summary>
public static class WechatTenpayClientResponseDecryptionExtensions
{
private static TResponse InnerDecryptResponseSensitiveProperty<TResponse>(WechatTenpayClient client, TResponse response)
where TResponse : Models.QueryCertificatesResponse
{
if (response.CertificateList == null)
return response;
foreach (var certificate in response.CertificateList)
{
if (certificate.EncryptCertificate == null)
continue;
switch (certificate.EncryptCertificate.Algorithm)
{
case Constants.EncryptionAlgorithms.AEAD_AES_256_GCM:
{
if (string.IsNullOrEmpty(client.Credentials.MerchantCertificatePrivateKey))
throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because there is no merchant private key.");
certificate.EncryptCertificate.CipherText = Utilities.AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
nonce: certificate.EncryptCertificate.Nonce,
aad: certificate.EncryptCertificate.AssociatedData,
cipherText: certificate.EncryptCertificate.CipherText
);
}
break;
case Constants.EncryptionAlgorithms.AEAD_SM4_128_GCM:
{
if (string.IsNullOrEmpty(client.Credentials.MerchantV3Secret))
throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because there is no merchant APIv3 secret.");
// REF: https://pay.weixin.qq.com/docs/merchant/development/shangmi/guide.html
// 由于 SM4 密钥长度的限制,密钥由 APIv3 密钥通过国密 SM3 Hash 计算生成。SM4 密钥取其摘要256bit的前 128bit。
byte[] secretBytes = Utilities.SM3Utility.Hash(Encoding.UTF8.GetBytes(client.Credentials.MerchantV3Secret));
byte[] keyBytes = new byte[16];
Array.Copy(secretBytes, keyBytes, keyBytes.Length);
byte[] plainBytes = Utilities.SM4Utility.DecryptWithGCM(
keyBytes: keyBytes,
nonceBytes: Encoding.UTF8.GetBytes(certificate.EncryptCertificate.Nonce),
aadBytes: Encoding.UTF8.GetBytes(certificate.EncryptCertificate.AssociatedData ?? string.Empty),
cipherBytes: Convert.FromBase64String(certificate.EncryptCertificate.CipherText)
);
certificate.EncryptCertificate.CipherText = Encoding.UTF8.GetString(plainBytes);
}
break;
default:
{
throw new Exceptions.WechatTenpayResponseDecryptionException($"Unsupported encryption algorithm: \"{certificate.EncryptCertificate.Algorithm}\".");
}
}
}
return response;
}
private static TResponse InnerDecryptResponseSensitivePropertyByRSA<TResponse>(WechatTenpayClient client, TResponse response)
where TResponse : WechatTenpayResponse
{
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref response, (target, currentProp, oldValue) =>
{
var attribute = currentProp
.GetCustomAttributes<WechatTenpaySensitivePropertyAttribute>()
.FirstOrDefault(attr => Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256.Equals(attr.Scheme));
if (attribute == null)
return (false, oldValue);
string newValue;
switch (attribute.Algorithm)
{
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1:
{
newValue = Utilities.RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue
);
}
break;
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1:
{
newValue = Utilities.RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue,
paddingMode: "PKCS1PADDING"
);
}
break;
default:
{
throw new Exceptions.WechatTenpayResponseDecryptionException($"Unsupported encryption algorithm: \"{attribute.Algorithm}\".");
}
}
return (true, newValue);
});
return response;
}
private static TResponse InnerDecryptResponseSensitivePropertyBySM<TResponse>(WechatTenpayClient client, TResponse response)
where TResponse : WechatTenpayResponse
{
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref response, (target, currentProp, oldValue) =>
{
var attribute = currentProp
.GetCustomAttributes<WechatTenpaySensitivePropertyAttribute>()
.FirstOrDefault(attr => Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3.Equals(attr.Scheme));
if (attribute == null)
return (false, oldValue);
string newValue;
switch (attribute.Algorithm)
{
case Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1:
{
newValue = Utilities.SM2Utility.Decrypt(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue,
asn1Encoding: true
);
}
break;
default:
{
throw new Exceptions.WechatTenpayResponseDecryptionException($"Unsupported encryption algorithm: \"{attribute.Algorithm}\".");
}
}
return (true, newValue);
});
return response;
}
/// <summary>
/// <para>解密响应中返回的敏感数据。该方法会改变传入的响应模型对象。</para>
/// </summary>
@@ -29,77 +167,33 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
// [GET] /certificates 接口的响应模型需特殊处理
if (response is Models.QueryCertificatesResponse queryCertificatesResponse)
{
if (queryCertificatesResponse.CertificateList == null)
return response;
foreach (var certificateModel in queryCertificatesResponse.CertificateList)
{
if (Constants.EncryptionAlgorithms.AEAD_AES_256_GCM.Equals(certificateModel.EncryptCertificate?.Algorithm))
{
if (string.IsNullOrEmpty(client.Credentials.MerchantCertificatePrivateKey))
throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because there is no merchant private key.");
certificateModel.EncryptCertificate.CipherText = Utilities.AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
iv: certificateModel.EncryptCertificate.Nonce,
aad: certificateModel.EncryptCertificate.AssociatedData,
cipherText: certificateModel.EncryptCertificate.CipherText
);
}
else
{
throw new Exceptions.WechatTenpayResponseDecryptionException("Unsupported decryption algorithm.");
}
}
return response;
return (InnerDecryptResponseSensitiveProperty(client, queryCertificatesResponse) as TResponse)!;
}
// 遍历并解密被标记为敏感数据的字段
bool requireDecrypt = Attribute.IsDefined(response.GetType(), typeof(WechatTenpaySensitiveAttribute));
if (requireDecrypt)
{
// 遍历并解密被标记为敏感数据的字段
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref response, (target, currentProp, oldValue) =>
switch (client.Credentials.SignScheme)
{
var attr = currentProp.GetCustomAttribute<WechatTenpaySensitivePropertyAttribute>();
if (attr == null)
return (false, oldValue);
case Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256:
return InnerDecryptResponseSensitivePropertyByRSA(client, response);
if (Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1.Equals(attr.Algorithm) ||
Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1.Equals(attr.Algorithm))
{
string newValue = oldValue;
if (Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1.Equals(attr.Algorithm))
{
newValue = Utilities.RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue
);
}
else if (Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1.Equals(attr.Algorithm))
{
newValue = Utilities.RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue,
paddingMode: "PKCS1PADDING"
);
}
return (true, newValue);
}
else
{
throw new Exceptions.WechatTenpayResponseDecryptionException("Unsupported decryption algorithm.");
}
});
case Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3:
return InnerDecryptResponseSensitivePropertyBySM(client, response);
}
}
return response;
}
catch (Exception ex) when (!(ex is Exceptions.WechatTenpayResponseDecryptionException))
catch (WechatTenpayException)
{
throw;
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed. Please see the `InnerException` for more details.", ex);
}
return response;
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
@@ -40,7 +40,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
if (client == null) throw new ArgumentNullException(nameof(client));
if (response == null) throw new ArgumentNullException(nameof(response));
return VerifyResponseSignature(client, response.WechatpayTimestamp, response.WechatpayNonce, Encoding.UTF8.GetString(response.RawBytes), response.WechatpaySignature, response.WechatpayCertificateSerialNumber, out error);
return VerifyResponseSignature(
client,
responseTimestamp: response.WechatpayTimestamp,
responseNonce: response.WechatpayNonce,
responseBody: Encoding.UTF8.GetString(response.RawBytes),
responseSignature: response.WechatpaySignature,
responseSignatureType: response.WechatpaySignatureType,
responseSerialNumber: response.WechatpayCertificateSerialNumber,
out error
);
}
/// <summary>
@@ -57,7 +66,42 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// <returns></returns>
public static bool VerifyResponseSignature(this WechatTenpayClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber)
{
return VerifyResponseSignature(client, responseTimestamp, responseNonce, responseBody, responseSignature, responseSerialNumber, out _);
return VerifyResponseSignature(
client,
responseTimestamp: responseTimestamp,
responseNonce: responseNonce,
responseBody: responseBody,
responseSignature: responseSignature,
responseSignatureType: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256,
responseSerialNumber: responseSerialNumber
);
}
/// <summary>
/// <para>验证响应签名。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml </para>
/// </summary>
/// <param name="client"></param>
/// <param name="responseTimestamp"></param>
/// <param name="responseNonce">。</param>
/// <param name="responseBody"></param>
/// <param name="responseSignature"></param>
/// <param name="responseSignatureType"></param>
/// <param name="responseSerialNumber"></param>
/// <returns></returns>
public static bool VerifyResponseSignature(this WechatTenpayClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSignatureType, string responseSerialNumber)
{
return VerifyResponseSignature(
client,
responseTimestamp: responseTimestamp,
responseNonce: responseNonce,
responseBody: responseBody,
responseSignature: responseSignature,
responseSignatureType: responseSignatureType,
responseSerialNumber,
out _
);
}
/// <summary>
@@ -76,17 +120,61 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool VerifyResponseSignature(this WechatTenpayClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber, out Exception? error)
{
return VerifyResponseSignature(
client,
responseTimestamp: responseTimestamp,
responseNonce: responseNonce,
responseBody: responseBody,
responseSignature: responseSignature,
responseSignatureType: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256,
responseSerialNumber,
out error
);
}
/// <summary>
/// <para>验证响应签名。</para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml </para>
/// <para>REF: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/wechatpay/wechatpay4_1.shtml </para>
/// </summary>
/// <typeparam name="TResponse"></typeparam>
/// <param name="client"></param>
/// <param name="responseTimestamp"></param>
/// <param name="responseNonce">。</param>
/// <param name="responseBody"></param>
/// <param name="responseSignature"></param>
/// <param name="responseSignatureType"></param>
/// <param name="responseSerialNumber"></param>
/// <param name="error"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool VerifyResponseSignature(this WechatTenpayClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSignatureType, string responseSerialNumber, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (responseTimestamp == null) throw new ArgumentNullException(nameof(responseTimestamp));
if (responseNonce == null) throw new ArgumentNullException(nameof(responseNonce));
if (responseBody == null) throw new ArgumentNullException(nameof(responseBody));
if (responseSignature == null) throw new ArgumentNullException(nameof(responseSignature));
if (responseSignatureType == null) throw new ArgumentNullException(nameof(responseSignatureType));
if (responseSerialNumber == null) throw new ArgumentNullException(nameof(responseSerialNumber));
bool ret = WechatTenpayClientSignExtensions.VerifySignature(client, responseTimestamp, responseNonce, responseBody, responseSignature, responseSerialNumber, out error);
bool ret = WechatTenpayClientSignExtensions.VerifySignature(
client,
strTimestamp: responseTimestamp,
strNonce: responseNonce,
strContent: responseBody,
strSignature: responseSignature,
strSignatureScheme: responseSignatureType,
strSerialNumber: responseSerialNumber,
out error
);
if (error != null)
{
error = new Exceptions.WechatTenpayEventVerificationException("Verify signature of response failed. Please see the `InnerException` for more details.", error);
}
return ret;
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
@@ -46,16 +46,29 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
body = flurlCall.RequestBody ?? string.Empty;
}
string plainText = $"{method}\n{url}\n{timestamp}\n{nonce}\n{body}\n";
string msgText = $"{method}\n{url}\n{timestamp}\n{nonce}\n{body}\n";
string signText;
switch (_scheme)
{
case Constants.SignSchemes.WECHATPAY2_SHA256_RSA2048:
case Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256:
{
try
{
signText = Utilities.RSAUtility.SignWithSHA256(_mchCertPk, plainText);
signText = Utilities.RSAUtility.SignWithSHA256(_mchCertPk, msgText);
}
catch (Exception ex)
{
throw new Exceptions.WechatTenpayRequestSignatureException("Generate signature of request failed. Please see the `InnerException` for more details.", ex);
}
}
break;
case Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3:
{
try
{
signText = Utilities.SM2Utility.SignWithSM3(_mchCertPk, msgText);
}
catch (Exception ex)
{
@@ -65,7 +78,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
break;
default:
throw new Exceptions.WechatTenpayRequestSignatureException("Unsupported authorization scheme.");
throw new Exceptions.WechatTenpayRequestSignatureException($"Unsupported signature scheme: \"{_scheme}\".");
}
string auth = $"mchid=\"{_mchId}\",nonce_str=\"{nonce}\",signature=\"{signText}\",timestamp=\"{timestamp}\",serial_no=\"{_mchCertSn}\"";

View File

@@ -24,7 +24,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("contact_name")]
[System.Text.Json.Serialization.JsonPropertyName("contact_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string ContactName { get; set; } = string.Empty;
/// <summary>
@@ -39,7 +40,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("contact_id_number")]
[System.Text.Json.Serialization.JsonPropertyName("contact_id_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -89,7 +91,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("mobile_phone")]
[System.Text.Json.Serialization.JsonPropertyName("mobile_phone")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string MobileNumber { get; set; } = string.Empty;
/// <summary>
@@ -97,7 +100,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("contact_email")]
[System.Text.Json.Serialization.JsonPropertyName("contact_email")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string Email { get; set; } = string.Empty;
}
@@ -414,7 +418,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdCardName { get; set; } = string.Empty;
/// <summary>
@@ -422,7 +427,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdCardNumber { get; set; } = string.Empty;
/// <summary>
@@ -430,7 +436,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_address")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdCardAddress { get; set; }
/// <summary>
@@ -469,7 +476,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdDocumentName { get; set; } = string.Empty;
/// <summary>
@@ -477,7 +485,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdDocumentNumber { get; set; } = string.Empty;
/// <summary>
@@ -485,7 +494,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_address")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdDocumentAddress { get; set; }
/// <summary>
@@ -561,7 +571,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdName { get; set; } = string.Empty;
/// <summary>
@@ -583,7 +594,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -591,7 +603,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_address")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdAddress { get; set; }
/// <summary>
@@ -1009,7 +1022,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("account_name")]
[System.Text.Json.Serialization.JsonPropertyName("account_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountName { get; set; } = string.Empty;
/// <summary>
@@ -1017,7 +1031,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountNumber { get; set; } = string.Empty;
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /apply4sub/sub_merchants/{sub_mchid}/modify-settlement 接口的请求。</para>
@@ -25,7 +25,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountNumber { get; set; } = string.Empty;
/// <summary>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -24,7 +24,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string ContactName { get; set; } = string.Empty;
/// <summary>
@@ -39,7 +40,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -82,7 +84,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string MobileNumber { get; set; } = string.Empty;
}
@@ -345,7 +348,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("identification_name")]
[System.Text.Json.Serialization.JsonPropertyName("identification_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdName { get; set; } = string.Empty;
/// <summary>
@@ -353,7 +357,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("identification_number")]
[System.Text.Json.Serialization.JsonPropertyName("identification_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -361,7 +366,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("identification_address")]
[System.Text.Json.Serialization.JsonPropertyName("identification_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdAddress { get; set; }
/// <summary>
@@ -414,7 +420,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdName { get; set; } = string.Empty;
/// <summary>
@@ -436,7 +443,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -444,7 +452,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_address")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdAddress { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /bill/sub-merchant-fundflowbill 接口的响应。</para>
@@ -43,7 +43,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("encrypt_key")]
[System.Text.Json.Serialization.JsonPropertyName("encrypt_key")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string EncryptKey { get; set; } = default!;
/// <summary>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -31,7 +31,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? Name { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /capital/capitallhh/banks/search-banks-by-bank-account 接口的请求。</para>
@@ -11,7 +11,8 @@
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountNumber { get; set; } = string.Empty;
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -42,7 +42,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ciphertext")]
[System.Text.Json.Serialization.JsonPropertyName("ciphertext")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.AEAD_AES_256_GCM)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.AEAD_AES_256_GCM)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.AEAD_SM4_128_GCM)]
public string CipherText { get; set; } = default!;
}
}

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -107,7 +107,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdCardName { get; set; } = string.Empty;
/// <summary>
@@ -115,7 +116,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdCardNumber { get; set; } = string.Empty;
/// <summary>
@@ -123,7 +125,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_card_address")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdCardAddress { get; set; }
/// <summary>
@@ -162,7 +165,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdDocumentName { get; set; } = string.Empty;
/// <summary>
@@ -170,7 +174,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdDocumentNumber { get; set; } = string.Empty;
/// <summary>
@@ -178,7 +183,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("id_doc_address")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdDocumentAddress { get; set; }
/// <summary>
@@ -210,7 +216,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("contact_name")]
[System.Text.Json.Serialization.JsonPropertyName("contact_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string ContactName { get; set; } = string.Empty;
/// <summary>
@@ -225,7 +232,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("contact_id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("contact_id_card_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -268,7 +276,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("mobile_phone")]
[System.Text.Json.Serialization.JsonPropertyName("mobile_phone")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string MobileNumber { get; set; } = string.Empty;
/// <summary>
@@ -276,7 +285,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("contact_email")]
[System.Text.Json.Serialization.JsonPropertyName("contact_email")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string Email { get; set; } = string.Empty;
}
@@ -294,7 +304,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string IdName { get; set; } = string.Empty;
/// <summary>
@@ -316,7 +327,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdNumber { get; set; }
/// <summary>
@@ -324,7 +336,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("ubo_id_doc_address")]
[System.Text.Json.Serialization.JsonPropertyName("ubo_id_doc_address")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? IdAddress { get; set; }
/// <summary>
@@ -383,7 +396,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("account_name")]
[System.Text.Json.Serialization.JsonPropertyName("account_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountName { get; set; } = string.Empty;
/// <summary>
@@ -391,7 +405,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountNumber { get; set; } = string.Empty;
/// <summary>

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -17,7 +17,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("account_name")]
[System.Text.Json.Serialization.JsonPropertyName("account_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string AccountName { get; set; } = default!;
/// <summary>
@@ -25,7 +26,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("account_no")]
[System.Text.Json.Serialization.JsonPropertyName("account_no")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? AccountNumber { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /ecommerce/bill/fundflowbill 接口的响应。</para>
@@ -43,7 +43,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("encrypt_key")]
[System.Text.Json.Serialization.JsonPropertyName("encrypt_key")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string EncryptKey { get; set; } = default!;
/// <summary>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -31,7 +31,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("receiver_name")]
[System.Text.Json.Serialization.JsonPropertyName("receiver_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? Name { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /ecommerce/profitsharing/receivers/add 接口的请求。</para>
@@ -39,7 +39,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("encrypted_name")]
[System.Text.Json.Serialization.JsonPropertyName("encrypted_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? EncryptedName { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /customs/verify-certificate 接口的请求。</para>
@@ -67,7 +67,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("certificate_id")]
[System.Text.Json.Serialization.JsonPropertyName("certificate_id")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string CertificateId { get; set; } = string.Empty;
/// <summary>
@@ -75,7 +76,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("certificate_name")]
[System.Text.Json.Serialization.JsonPropertyName("certificate_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string CertificateName { get; set; } = string.Empty;
}
}

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -17,7 +17,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string ContactName { get; set; } = string.Empty;
/// <summary>
@@ -25,7 +26,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("phone")]
[System.Text.Json.Serialization.JsonPropertyName("phone")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string MobileNumber { get; set; } = string.Empty;
/// <summary>
@@ -33,7 +35,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("email")]
[System.Text.Json.Serialization.JsonPropertyName("email")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string Email { get; set; } = string.Empty;
}

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /merchants/{sub_mchid} 接口的响应。</para>
@@ -14,7 +14,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string ContactName { get; set; } = default!;
/// <summary>
@@ -22,7 +23,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("phone")]
[System.Text.Json.Serialization.JsonPropertyName("phone")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string MobileNumber { get; set; } = default!;
/// <summary>
@@ -30,7 +32,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("email")]
[System.Text.Json.Serialization.JsonPropertyName("email")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string Email { get; set; } = default!;
}

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /marketing/membercard-open/cards/{card_id}/phone-membercard/import 接口的请求。</para>
@@ -17,7 +17,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("encrypted_phone_number")]
[System.Text.Json.Serialization.JsonPropertyName("encrypted_phone_number")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string EncryptedPhoneNumber { get; set; } = string.Empty;
/// <summary>

View File

@@ -118,7 +118,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("payer_phone")]
[System.Text.Json.Serialization.JsonPropertyName("payer_phone")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? PayerPhone { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -65,7 +65,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("payer_phone")]
[System.Text.Json.Serialization.JsonPropertyName("payer_phone")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? PayerPhone { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /partner-transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} 接口的响应。</para>
@@ -18,7 +18,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("username")]
[System.Text.Json.Serialization.JsonPropertyName("username")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public override string UserName { get; set; } = default!;
}
}

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /payscore/merchant-bill 接口的响应。</para>
@@ -43,7 +43,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("encrypt_key")]
[System.Text.Json.Serialization.JsonPropertyName("encrypt_key")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string EncryptKey { get; set; } = default!;
/// <summary>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -31,7 +31,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? Name { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /profitsharing/receivers/add 接口的请求。</para>
@@ -46,7 +46,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? Name { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /profitsharing/receivers/add 接口的响应。</para>
@@ -32,7 +32,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? Name { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [POST] /smartguide/guides 接口的请求。</para>
@@ -39,7 +39,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string UserName { get; set; } = string.Empty;
/// <summary>
@@ -47,7 +48,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string UserMobile { get; set; } = string.Empty;
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /smartguide/guides 接口的请求。</para>
@@ -32,7 +32,8 @@
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? UserMobile { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [GET] /smartguide/guides 接口的响应。</para>
@@ -36,7 +36,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string UserName { get; set; } = default!;
/// <summary>
@@ -44,7 +45,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string UserMobile { get; set; } = default!;
/// <summary>

View File

@@ -1,4 +1,4 @@
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
/// <summary>
/// <para>表示 [PATCH] /smartguide/guides/{guide_id} 接口的请求。</para>
@@ -25,7 +25,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? UserName { get; set; }
/// <summary>
@@ -33,7 +34,8 @@
/// </summary>
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? UserMobile { get; set; }
/// <summary>

View File

@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -45,7 +45,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("user_name")]
[System.Text.Json.Serialization.JsonPropertyName("user_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public string? UserName { get; set; }
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
{
@@ -83,7 +83,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
/// </summary>
[Newtonsoft.Json.JsonProperty("user_name")]
[System.Text.Json.Serialization.JsonPropertyName("user_name")]
[WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256, algorithm: Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1)]
[WechatTenpaySensitiveProperty(scheme: Constants.SignSchemes.WECHATPAY2_SM2_WITH_SM3, algorithm: Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1)]
public virtual string UserName { get; set; } = default!;
/// <summary>

View File

@@ -10,8 +10,8 @@
- 基于微信支付 v3 版 API 封装。
- 支持直连商户、服务商两种模式。
- 请求时自动生成签名,无需开发者手动干预。
- 提供了微信支付所需的 RSA、AES、SHA-256 等算法工具类。
- 请求时自动生成签名(同时支持国际 RSA 算法或国密 SM 算法),无需开发者手动干预。
- 提供了微信支付所需的 RSA、AES、SM2/SM3/SM4、SHA-256 等算法工具类。
- 提供了调起支付签名、解析响应敏感数据、解析回调通知事件敏感数据等扩展方法。
---

View File

@@ -7,17 +7,25 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
/// </summary>
public struct CertificateEntry : IEquatable<CertificateEntry>
{
public const string ALGORITHM_TYPE_RSA = "RSA";
public const string ALGORITHM_TYPE_SM2 = "SM2";
/// <summary>
/// 获取证书序列号
/// <para>序列号相同的实体将被视为同一个证书。</para>
/// 获取证书算法类型
/// 取值范围RSA、SM2。
/// </summary>
public string SerialNumber { get; }
public string AlgorithmType { get; }
/// <summary>
/// 获取证书内容CRT/CER 格式,即 -----BEGIN CERTIFICATE----- ... -----END CERTIFICATE
/// </summary>
public string Certificate { get; }
/// <summary>
/// 获取证书序列号。
/// </summary>
public string SerialNumber { get; }
/// <summary>
/// 获取生效时间。
/// </summary>
@@ -30,39 +38,102 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
[Newtonsoft.Json.JsonConstructor]
[System.Text.Json.Serialization.JsonConstructor]
public CertificateEntry(string serialNumber, string certificate, DateTimeOffset effectiveTime, DateTimeOffset expireTime)
public CertificateEntry(string algorithmType, string serialNumber, string certificate, DateTimeOffset effectiveTime, DateTimeOffset expireTime)
{
if (string.IsNullOrEmpty(serialNumber))
throw new ArgumentException("The value of `serialNumber` can not be empty.", nameof(serialNumber));
if (string.IsNullOrEmpty(algorithmType))
throw new ArgumentException("The value of `algorithmType` can not be empty.", nameof(algorithmType));
if (string.IsNullOrEmpty(certificate))
throw new ArgumentException("The value of `certificate` can not be empty.", nameof(certificate));
if (string.IsNullOrEmpty(serialNumber))
throw new ArgumentException("The value of `serialNumber` can not be empty.", nameof(serialNumber));
if (!ALGORITHM_TYPE_RSA.Equals(algorithmType) && !ALGORITHM_TYPE_SM2.Equals(algorithmType))
throw new ArgumentException("The value of `algorithmType` an invalid value.", nameof(algorithmType));
if (!certificate.Trim().StartsWith("-----BEGIN CERTIFICATE-----") || !certificate.Trim().EndsWith("-----END CERTIFICATE-----"))
throw new ArgumentException("The value of `certificate` is an invalid certificate file content.", nameof(certificate));
SerialNumber = serialNumber;
AlgorithmType = algorithmType;
SerialNumber = serialNumber.ToUpper();
Certificate = certificate;
EffectiveTime = effectiveTime;
ExpireTime = expireTime;
}
public CertificateEntry(string certificate)
public CertificateEntry(string algorithmType, string certificate)
{
if (string.IsNullOrEmpty(algorithmType))
throw new ArgumentException("The value of `algorithmType` can not be empty.", nameof(algorithmType));
if (string.IsNullOrEmpty(certificate))
throw new ArgumentException("The value of `certificate` can not be empty.", nameof(certificate));
if (!certificate.Trim().StartsWith("-----BEGIN CERTIFICATE-----") || !certificate.Trim().EndsWith("-----END CERTIFICATE-----"))
throw new ArgumentException("The value of `certificate` is an invalid certificate file content.", nameof(certificate));
SerialNumber = Utilities.RSAUtility.ExportSerialNumberFromCertificate(certificate);
AlgorithmType = algorithmType;
Certificate = certificate;
EffectiveTime = Utilities.RSAUtility.ExportEffectiveTimeFromCertificate(certificate);
ExpireTime = Utilities.RSAUtility.ExportExpireTimeFromCertificate(certificate);
switch (algorithmType)
{
case ALGORITHM_TYPE_RSA:
{
SerialNumber = Utilities.RSAUtility.ExportSerialNumberFromCertificate(certificate).ToUpper();
EffectiveTime = Utilities.RSAUtility.ExportEffectiveTimeFromCertificate(certificate);
ExpireTime = Utilities.RSAUtility.ExportExpireTimeFromCertificate(certificate);
}
break;
case ALGORITHM_TYPE_SM2:
{
SerialNumber = Utilities.SM2Utility.ExportSerialNumberFromCertificate(certificate).ToUpper();
EffectiveTime = Utilities.SM2Utility.ExportEffectiveTimeFromCertificate(certificate);
ExpireTime = Utilities.SM2Utility.ExportExpireTimeFromCertificate(certificate);
}
break;
default:
{
throw new ArgumentException("The value of `algorithmType` an invalid value.", nameof(algorithmType));
}
}
}
public CertificateEntry(Models.QueryCertificatesResponse.Types.Certificate cert)
: this(cert.SerialNumber, cert.EncryptCertificate.CipherText, cert.EffectiveTime, cert.ExpireTime)
public CertificateEntry(string algorithmType, Models.QueryCertificatesResponse.Types.Certificate certificate)
: this(algorithmType, certificate.SerialNumber, certificate.EncryptCertificate.CipherText, certificate.EffectiveTime, certificate.ExpireTime)
{
}
public CertificateEntry(Models.QueryCertificatesResponse.Types.Certificate certificate)
{
AlgorithmType = default!;
Certificate = certificate.EncryptCertificate.CipherText;
SerialNumber = certificate.SerialNumber.ToUpper();
EffectiveTime = certificate.EffectiveTime;
ExpireTime = certificate.ExpireTime;
if (AlgorithmType == null)
{
try
{
Utilities.RSAUtility.ExportPublicKeyFromCertificate(Certificate);
AlgorithmType = ALGORITHM_TYPE_RSA;
}
catch { }
}
if (AlgorithmType == null)
{
try
{
Utilities.SM2Utility.ExportPublicKeyFromCertificate(Certificate);
AlgorithmType = ALGORITHM_TYPE_SM2;
}
catch { }
}
if (AlgorithmType == null)
{
throw new ArgumentException("Unrecognized certificate algorithm type, please make sure you have decrypted the certificate content first.");
}
}
public bool IsAvailable()
{
DateTimeOffset now = DateTimeOffset.Now;
@@ -71,20 +142,35 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
public bool Equals(CertificateEntry other)
{
return string.Equals(SerialNumber, other.SerialNumber);
if (ReferenceEquals(null, other))
return false;
if (ReferenceEquals(this, other))
return true;
return string.Equals(AlgorithmType, other.AlgorithmType) &&
string.Equals(Certificate, other.Certificate) &&
string.Equals(SerialNumber, other.SerialNumber);
}
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
return false;
if (ReferenceEquals(this, obj))
return true;
if (GetType() != obj.GetType())
return false;
return (obj is CertificateEntry other) && Equals(other);
return Equals((CertificateEntry)obj);
}
public override int GetHashCode()
{
return SerialNumber?.GetHashCode() ?? base.GetHashCode();
#if NETFRAMEWORK || NETSTANDARD2_0
return (AlgorithmType?.GetHashCode(), Certificate?.GetHashCode(), SerialNumber?.GetHashCode()).GetHashCode();
#else
return HashCode.Combine(AlgorithmType?.GetHashCode(), Certificate?.GetHashCode(), SerialNumber?.GetHashCode());
#endif
}
public static bool operator ==(CertificateEntry left, CertificateEntry right)

View File

@@ -1,4 +1,4 @@
using System;
using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
{
@@ -24,6 +24,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
/// </summary>
public string MerchantCertificatePrivateKey { get; }
/// <summary>
/// 初始化客户端时 <see cref="WechatTenpayClientOptions.SignScheme"/> 的副本。
/// </summary>
internal string SignScheme { get; }
internal Credentials(WechatTenpayClientOptions options)
{
if (options == null) throw new ArgumentNullException(nameof(options));
@@ -32,6 +37,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
MerchantV3Secret = options.MerchantV3Secret;
MerchantCertificateSerialNumber = options.MerchantCertificateSerialNumber;
MerchantCertificatePrivateKey = options.MerchantCertificatePrivateKey;
SignScheme = options.SignScheme;
}
}
}

View File

@@ -26,25 +26,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// </summary>
public static class SM2Utility
{
private static readonly X9ECParameters _ecX9Parameters = GMNamedCurves.GetByName("SM2P256v1");
private static readonly ECDomainParameters _ecDomainParameters = new ECDomainParameters(_ecX9Parameters.Curve, _ecX9Parameters.G, _ecX9Parameters.N);
private static readonly X9ECParameters SM2_ECX9_PARAMS = GMNamedCurves.GetByName("SM2P256v1");
private static readonly ECDomainParameters SM2_DOMAIN_PARAMS = new ECDomainParameters(SM2_ECX9_PARAMS.Curve, SM2_ECX9_PARAMS.G, SM2_ECX9_PARAMS.N);
private static readonly byte[] SM2_DEFAULT_UID = new byte[] { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };
private static readonly int SM2_C1_LENGTH;
private static readonly int SM2_C3_LENGTH;
private static readonly int SM2_RS_LENGTH;
static SM2Utility()
{
SM2_C1_LENGTH = (_ecX9Parameters.Curve.FieldSize + 7) / 8 * 2 + 1;
SM2_C3_LENGTH = new SM3Digest().GetDigestSize();
SM2_RS_LENGTH = 32;
if (SM2_C1_LENGTH != 65)
throw new PlatformNotSupportedException($"Expected c1 length: {65}, actual: {SM2_C1_LENGTH}.");
if (SM2_C3_LENGTH != 32)
throw new PlatformNotSupportedException($"Expected c3 length: {32}, actual: {SM2_C3_LENGTH}.");
}
private const int SM2_C1_LENGTH = 65;
private const int SM2_C3_LENGTH = 32;
private const int SM2_RS_LENGTH = 32;
private static byte[] ConvertPrivateKeyPkcs8PemToByteArray(string privateKey)
{
@@ -87,7 +74,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
private static ECPrivateKeyParameters ParseECPrivateKeyToPrivateKeyParameters(string ecPrivateKeyHex)
{
BigInteger ecPrivateKeyParamsD = new BigInteger(ecPrivateKeyHex, 16);
return new ECPrivateKeyParameters(ecPrivateKeyParamsD, _ecDomainParameters);
return new ECPrivateKeyParameters(ecPrivateKeyParamsD, SM2_DOMAIN_PARAMS);
}
private static ECPublicKeyParameters ParsePublicKeyPemToPublicKeyParameters(byte[] publicKeyBytes)
@@ -114,7 +101,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
BigInteger ecPublicKeyParamsX = new BigInteger(Hex.ToHexString(ecPublicKeyXBytes), 16);
BigInteger ecPublicKeyParamsY = new BigInteger(Hex.ToHexString(ecPublicKeyYBytes), 16);
return new ECPublicKeyParameters(_ecX9Parameters.Curve.CreatePoint(ecPublicKeyParamsX, ecPublicKeyParamsY), _ecDomainParameters);
return new ECPublicKeyParameters(SM2_ECX9_PARAMS.Curve.CreatePoint(ecPublicKeyParamsX, ecPublicKeyParamsY), SM2_DOMAIN_PARAMS);
}
private static byte[] ConvertC1C3C2ToC1C2C3(byte[] c1c3c2)
@@ -170,7 +157,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
byte[] c3 = Asn1OctetString.GetInstance(sequence[2]).GetOctets();
byte[] c2 = Asn1OctetString.GetInstance(sequence[3]).GetOctets();
ECPoint c1Point = _ecX9Parameters.Curve.CreatePoint(x, y);
ECPoint c1Point = SM2_ECX9_PARAMS.Curve.CreatePoint(x, y);
byte[] c1 = c1Point.GetEncoded(false);
return Arrays.ConcatenateAll(c1, c3, c2);
@@ -790,8 +777,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
if (certificate == null) throw new ArgumentNullException(nameof(certificate));
X509Certificate cert = ConvertCertificatePemToX509(certificate);
return cert.SerialNumber.ToString(16);
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
return x509cert.SerialNumber.ToString(16);
}
/// <summary>
@@ -803,8 +790,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
if (certificate == null) throw new ArgumentNullException(nameof(certificate));
X509Certificate cert = ConvertCertificatePemToX509(certificate);
return new DateTimeOffset(cert.NotBefore);
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
return new DateTimeOffset(x509cert.NotBefore);
}
/// <summary>
@@ -816,8 +803,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
if (certificate == null) throw new ArgumentNullException(nameof(certificate));
X509Certificate cert = ConvertCertificatePemToX509(certificate);
return new DateTimeOffset(cert.NotAfter);
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
return new DateTimeOffset(x509cert.NotAfter);
}
/// <summary>

View File

@@ -26,12 +26,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// <summary>
/// 获取是否自动加密请求中的敏感信息字段。
/// </summary>
protected bool AutoEncryptRequestSensitiveProperty { get; }
protected internal bool AutoEncryptRequestSensitiveProperty { get; }
/// <summary>
/// 获取是否自动解密请求中的敏感信息字段。
/// </summary>
protected bool AutoDecryptResponseSensitiveProperty { get; }
protected internal bool AutoDecryptResponseSensitiveProperty { get; }
/// <summary>
/// 用指定的配置项初始化 <see cref="WechatTenpayClient"/> 类的新实例。
@@ -165,11 +165,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
where TResponse : WechatTenpayResponse, new()
{
TResponse result = await base.WrapResponseWithJsonAsync<TResponse>(flurlResponse, cancellationToken);
result.WechatpayRequestId = flurlResponse.Headers.GetAll("Request-ID").FirstOrDefault() ?? string.Empty;
result.WechatpayNonce = flurlResponse.Headers.GetAll("Wechatpay-Nonce").FirstOrDefault() ?? string.Empty;
result.WechatpayTimestamp = flurlResponse.Headers.GetAll("Wechatpay-Timestamp").FirstOrDefault() ?? string.Empty;
result.WechatpaySignature = flurlResponse.Headers.GetAll("Wechatpay-Signature").FirstOrDefault() ?? string.Empty;
result.WechatpayCertificateSerialNumber = flurlResponse.Headers.GetAll("Wechatpay-Serial").FirstOrDefault() ?? string.Empty;
result.WechatpayRequestId = flurlResponse.Headers.FirstOrDefault("Request-ID") ?? string.Empty;
result.WechatpayNonce = flurlResponse.Headers.FirstOrDefault("Wechatpay-Nonce") ?? string.Empty;
result.WechatpayTimestamp = flurlResponse.Headers.FirstOrDefault("Wechatpay-Timestamp") ?? string.Empty;
result.WechatpaySignatureType = flurlResponse.Headers.FirstOrDefault("Wechatpay-Signature-Type") ?? string.Empty;
result.WechatpaySignature = flurlResponse.Headers.FirstOrDefault("Wechatpay-Signature") ?? string.Empty;
result.WechatpayCertificateSerialNumber = flurlResponse.Headers.FirstOrDefault("Wechatpay-Serial") ?? string.Empty;
if (AutoDecryptResponseSensitiveProperty && result.IsSuccessful())
{

View File

@@ -34,9 +34,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
/// <summary>
/// 获取或设置微信支付 API 签名认证方式。
/// <para>默认值:<see cref="Constants.SignSchemes.WECHATPAY2_SHA256_RSA2048"/></para>
/// <para>默认值:<see cref="Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256"/></para>
/// </summary>
public string SignScheme { get; set; } = Constants.SignSchemes.WECHATPAY2_SHA256_RSA2048;
public string SignScheme { get; set; } = Constants.SignSchemes.WECHATPAY2_RSA_2048_WITH_SHA256;
/// <summary>
/// 获取或设置微信支付商户号。

View File

@@ -77,6 +77,13 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
[System.Text.Json.Serialization.JsonIgnore]
public string WechatpayNonce { get; internal set; } = default!;
/// <summary>
/// 获取微信应答签名类型。
/// </summary>
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
public string WechatpaySignatureType { get; internal set; } = default!;
/// <summary>
/// 获取微信应答签名。
/// </summary>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
@@ -8,11 +8,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
[Fact(DisplayName = "测试用例:`CertificateEntry` 序列化")]
public void TestCertificateEntrySerialization()
{
var entry = new Settings.CertificateEntry("SN", "-----BEGIN CERTIFICATE-----END CERTIFICATE-----", DateTimeOffset.Now, DateTimeOffset.Now);
var entry = new Settings.CertificateEntry("RSA", "FAKE SERIAL NUMBER", "-----BEGIN CERTIFICATE-----FAKE CERTIFICATE-----END CERTIFICATE-----", DateTimeOffset.Now, DateTimeOffset.Now);
var serialized1 = Newtonsoft.Json.JsonConvert.SerializeObject(entry);
var deserialized1 = Newtonsoft.Json.JsonConvert.DeserializeObject<Settings.CertificateEntry>(serialized1);
Assert.Equal(entry.AlgorithmType, deserialized1.AlgorithmType);
Assert.Equal(entry.SerialNumber, deserialized1.SerialNumber);
Assert.Equal(entry.Certificate, deserialized1.Certificate);
Assert.Equal(entry.EffectiveTime, deserialized1.EffectiveTime);
@@ -21,6 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
var serialized2 = System.Text.Json.JsonSerializer.Serialize(entry);
var deserialized2 = System.Text.Json.JsonSerializer.Deserialize<Settings.CertificateEntry>(serialized2);
Assert.Equal(entry.AlgorithmType, deserialized2.AlgorithmType);
Assert.Equal(entry.SerialNumber, deserialized2.SerialNumber);
Assert.Equal(entry.Certificate, deserialized2.Certificate);
Assert.Equal(entry.EffectiveTime, deserialized2.EffectiveTime);

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Xunit;
@@ -12,8 +12,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
private const string MockText = "mock_text";
private readonly Lazy<WechatTenpayClient> MockClientInstance = new Lazy<WechatTenpayClient>(() =>
{
var certManager = new Settings.InMemoryCertificateManager();
certManager.AddEntry(new Settings.CertificateEntry(
var manager = new Settings.InMemoryCertificateManager();
manager.AddEntry(new Settings.CertificateEntry(
algorithmType: "RSA",
serialNumber: RSA_CERTSN,
certificate: RSA_CERTIFICATE,
effectiveTime: DateTimeOffset.MinValue,
@@ -21,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
));
return new WechatTenpayClient(new WechatTenpayClientOptions()
{
PlatformCertificateManager = certManager
PlatformCertificateManager = manager
});
}, isThreadSafe: false);
@@ -35,7 +36,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
};
var data = MockClientInstance.Value.EncryptRequestSensitiveProperty(mock);
Assert.Equal(RSA_CERTSN, data.WechatpayCertificateSerialNumber);
Assert.Equal(RSA_CERTSN, data.WechatpayCertificateSerialNumber, ignoreCase: true);
Assert.Equal(MockText, data.Account);
Assert.Equal(MockText, Utilities.RSAUtility.DecryptWithECB(RSA_PRIVATE_KEY, data.Name!));
}
@@ -56,7 +57,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
};
var data = MockClientInstance.Value.EncryptRequestSensitiveProperty(mock);
Assert.Equal(RSA_CERTSN, data.WechatpayCertificateSerialNumber);
Assert.Equal(RSA_CERTSN, data.WechatpayCertificateSerialNumber, ignoreCase: true);
Assert.Equal(MockText, data.ReceiverList[0].Account);
Assert.Equal(MockText, Utilities.RSAUtility.DecryptWithECB(RSA_PRIVATE_KEY, data.ReceiverList[0].Name!));
}

View File

@@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
@@ -17,6 +17,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
Assert.True(response.RawHeaders.Count > 0);
Assert.True(response.RawBytes.Length > 0);
Assert.True(TestClients.Instance.VerifyResponseSignature(response));
Assert.NotNull(response.WechatpayRequestId);
Assert.NotNull(response.WechatpayNonce);
Assert.NotNull(response.WechatpayTimestamp);
Assert.NotNull(response.WechatpaySignature);
Assert.NotNull(response.WechatpaySignatureType);
Assert.NotNull(response.WechatpayCertificateSerialNumber);
}
}
}