mirror of
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat.git
synced 2025-04-05 17:37:54 +08:00
refactor: clean code
This commit is contained in:
parent
6010c202e8
commit
23d144fef7
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Ads.Exceptions
|
||||
{
|
||||
public class WechatAdsRequestAgencyTokenException : WechatAdsException
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
internal WechatAdsRequestAgencyTokenException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
internal WechatAdsRequestAgencyTokenException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
internal WechatAdsRequestAgencyTokenException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -6,12 +6,12 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.Ads.Interceptors
|
||||
{
|
||||
internal class WechatAdsAgencyTokenInterceptor : FlurlHttpCallInterceptor
|
||||
internal class WechatAdsRequestAgencyTokenInterceptor : FlurlHttpCallInterceptor
|
||||
{
|
||||
private readonly string _agencyId;
|
||||
private readonly string _agencyApiKey;
|
||||
|
||||
public WechatAdsAgencyTokenInterceptor(string agencyId, string agencyApiKey)
|
||||
public WechatAdsRequestAgencyTokenInterceptor(string agencyId, string agencyApiKey)
|
||||
{
|
||||
_agencyId = agencyId;
|
||||
_agencyApiKey = agencyApiKey;
|
||||
@ -20,6 +20,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads.Interceptors
|
||||
public override async Task BeforeCallAsync(FlurlCall flurlCall)
|
||||
{
|
||||
if (flurlCall == null) throw new ArgumentNullException(nameof(flurlCall));
|
||||
if (flurlCall.Completed) throw new Exceptions.WechatAdsRequestAgencyTokenException("This interceptor must be called before request completed.");
|
||||
|
||||
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
|
||||
string nonce = Guid.NewGuid().ToString("N");
|
@ -30,7 +30,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads
|
||||
FlurlClient.BaseUrl = options.Endpoints ?? WechatAdsEndpoints.DEFAULT;
|
||||
FlurlClient.WithTimeout(TimeSpan.FromMilliseconds(options.Timeout));
|
||||
|
||||
Interceptors.Add(new Interceptors.WechatAdsAgencyTokenInterceptor(
|
||||
Interceptors.Add(new Interceptors.WechatAdsRequestAgencyTokenInterceptor(
|
||||
agencyId: options.AgencyId,
|
||||
agencyApiKey: options.AgencyApiKey
|
||||
));
|
||||
|
@ -19,13 +19,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <param name="callbackSignature">微信回调通知中的 Wechatpay-Signature 字段。</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 callbackSerialNumber)
|
||||
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 _);
|
||||
}
|
||||
@ -44,14 +38,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
/// <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 callbackSerialNumber,
|
||||
out Exception? error)
|
||||
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber, out Exception? error)
|
||||
{
|
||||
if (client == null) throw new ArgumentNullException(nameof(client));
|
||||
if (callbackTimestamp == null) throw new ArgumentNullException(nameof(callbackTimestamp));
|
||||
|
@ -40,11 +40,55 @@ 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);
|
||||
}
|
||||
|
||||
/// <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="responseSerialNumber"></param>
|
||||
/// <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 _);
|
||||
}
|
||||
|
||||
/// <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="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 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 (responseSerialNumber == null) throw new ArgumentNullException(nameof(responseSerialNumber));
|
||||
|
||||
if (client.PlatformCertificateManager != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cert = client.PlatformCertificateManager.GetEntry(response.WechatpayCertificateSerialNumber)!;
|
||||
var cert = client.PlatformCertificateManager.GetEntry(responseSerialNumber)!;
|
||||
if (!cert.HasValue)
|
||||
{
|
||||
error = new Exceptions.WechatTenpayResponseVerificationException("Verify signature of response failed, because there is no platform certificate matched the serial number.");
|
||||
@ -54,8 +98,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
error = null;
|
||||
return Utilities.RSAUtility.VerifyWithSHA256ByCertificate(
|
||||
certificate: cert.Value.Certificate,
|
||||
plainText: GetPlainTextForSignature(response),
|
||||
signature: response.WechatpaySignature
|
||||
plainText: GetPlainTextForSignature(timestamp: responseTimestamp, nonce: responseNonce, body: responseBody),
|
||||
signature: responseSignature
|
||||
);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -69,11 +113,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
return false;
|
||||
}
|
||||
|
||||
private static string GetPlainTextForSignature(WechatTenpayResponse response)
|
||||
private static string GetPlainTextForSignature(string timestamp, string nonce, string body)
|
||||
{
|
||||
string timestamp = response.WechatpayTimestamp;
|
||||
string nonce = response.WechatpayNonce;
|
||||
string body = Encoding.UTF8.GetString(response.RawBytes);
|
||||
return $"{timestamp}\n{nonce}\n{body}\n";
|
||||
}
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ using Flurl.Http;
|
||||
|
||||
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
|
||||
{
|
||||
internal class WechatTenpaySignInterceptor : FlurlHttpCallInterceptor
|
||||
internal class WechatTenpayRequestSignatureInterceptor : FlurlHttpCallInterceptor
|
||||
{
|
||||
private readonly string _scheme;
|
||||
private readonly string _mchId;
|
||||
private readonly string _mchCertSn;
|
||||
private readonly string _mchCertPk;
|
||||
|
||||
public WechatTenpaySignInterceptor(string scheme, string mchId, string mchCertSn, string mchCertPk)
|
||||
public WechatTenpayRequestSignatureInterceptor(string scheme, string mchId, string mchCertSn, string mchCertPk)
|
||||
{
|
||||
_scheme = scheme;
|
||||
_mchId = mchId;
|
||||
@ -24,6 +24,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
|
||||
public override async Task BeforeCallAsync(FlurlCall flurlCall)
|
||||
{
|
||||
if (flurlCall == null) throw new ArgumentNullException(nameof(flurlCall));
|
||||
if (flurlCall.Completed) throw new Exceptions.WechatTenpayRequestSignatureException("This interceptor must be called before request completed.");
|
||||
|
||||
string method = flurlCall.HttpRequestMessage.Method.ToString().ToUpper();
|
||||
string url = flurlCall.HttpRequestMessage.RequestUri?.PathAndQuery ?? string.Empty;
|
||||
@ -68,8 +69,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
|
||||
}
|
||||
|
||||
string auth = $"mchid=\"{_mchId}\",nonce_str=\"{nonce}\",signature=\"{signText}\",timestamp=\"{timestamp}\",serial_no=\"{_mchCertSn}\"";
|
||||
flurlCall.Request.Headers.Remove("Authorization");
|
||||
flurlCall.Request.WithHeader("Authorization", $"{_scheme} {auth}");
|
||||
flurlCall.Request.Headers.Remove(Contants.HttpHeaders.Authorization);
|
||||
flurlCall.Request.WithHeader(Contants.HttpHeaders.Authorization, $"{_scheme} {auth}");
|
||||
}
|
||||
}
|
||||
}
|
@ -55,7 +55,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
|
||||
FlurlClient.WithHeader(Contants.HttpHeaders.UserAgent, options.UserAgent);
|
||||
FlurlClient.WithTimeout(TimeSpan.FromMilliseconds(options.Timeout));
|
||||
|
||||
Interceptors.Add(new Interceptors.WechatTenpaySignInterceptor(
|
||||
Interceptors.Add(new Interceptors.WechatTenpayRequestSignatureInterceptor(
|
||||
scheme: options.SignAlgorithm,
|
||||
mchId: options.MerchantId,
|
||||
mchCertSn: options.MerchantCertificateSerialNumber,
|
||||
|
Loading…
Reference in New Issue
Block a user