mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-09-18 17:48:12 +08:00
feat(tenpayv3): 适配国密接入模式
This commit is contained in:
@@ -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; }
|
||||
}
|
||||
```
|
||||
|
@@ -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("刷新微信商户平台证书成功。");
|
||||
|
@@ -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("刷新微信商户平台证书成功。");
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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";
|
||||
}
|
||||
}
|
||||
|
@@ -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";
|
||||
}
|
||||
}
|
||||
|
@@ -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";
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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>()
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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}\"";
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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!;
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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!;
|
||||
}
|
||||
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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!;
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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>
|
||||
|
@@ -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; }
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -10,8 +10,8 @@
|
||||
|
||||
- 基于微信支付 v3 版 API 封装。
|
||||
- 支持直连商户、服务商两种模式。
|
||||
- 请求时自动生成签名,无需开发者手动干预。
|
||||
- 提供了微信支付所需的 RSA、AES、SHA-256 等算法工具类。
|
||||
- 请求时自动生成签名(同时支持国际 RSA 算法或国密 SM 算法),无需开发者手动干预。
|
||||
- 提供了微信支付所需的 RSA、AES、SM2/SM3/SM4、SHA-256 等算法工具类。
|
||||
- 提供了调起支付签名、解析响应敏感数据、解析回调通知事件敏感数据等扩展方法。
|
||||
|
||||
---
|
||||
|
@@ -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)
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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())
|
||||
{
|
||||
|
@@ -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>
|
||||
/// 获取或设置微信支付商户号。
|
||||
|
@@ -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>
|
||||
|
@@ -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);
|
||||
|
@@ -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!));
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user