using System;
using System.Linq;
using System.Xml;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV2
{
///
/// 为 提供回调通知事件签名验证的扩展方法。
///
public static class WechatTenpayClientEventVerificationExtensions
{
///
/// 验证回调通知事件签名。
///
///
/// 微信回调通知中请求正文。
///
///
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackBody)
{
return VerifyEventSignature(client, callbackBody, out _);
}
///
/// 验证回调通知事件签名。
///
///
/// 微信回调通知中请求正文。
///
///
///
public static bool VerifyEventSignature(this WechatTenpayClient client, string callbackBody, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (callbackBody == null) throw new ArgumentNullException(nameof(callbackBody));
try
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(callbackBody);
XmlNode xmlNode = xmlDocument.ChildNodes.OfType().Single();
string? signType = xmlNode["sign_type"]?.InnerText;
string? expectedSign = xmlNode["sign"]?.InnerText;
xmlNode["sign"]?.RemoveAll();
string xml = xmlDocument.InnerXml;
string json = Utilities.XmlUtility.ConvertToJson(xml);
string signData = Utilities.JsonUtility.ParseToSortedQueryString(json);
string actualSign = Utilities.RequestSigner.SignFromSortedQueryString(signData, client.Credentials.MerchantSecret, signType);
error = null;
return string.Equals(expectedSign, actualSign, StringComparison.OrdinalIgnoreCase);
}
catch (Exception ex)
{
error = new Exceptions.WechatTenpayEventVerificationException("Verify signature of event failed. Please see the inner exception for more details.", ex);
return false;
}
}
}
}