public Task <T> ExecuteAsync <T>(string body, WeChatPayOptions options) where T : WeChatPayNotify
        {
            if (string.IsNullOrEmpty(body))
            {
                throw new ArgumentNullException(nameof(body));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (string.IsNullOrEmpty(options.Key))
            {
                throw new ArgumentNullException(nameof(options.Key));
            }

            var parser = new WeChatPayNotifyXmlParser <T>();
            var notify = parser.Parse(body);

            if (notify is Notify.WeChatPayRefundNotify)
            {
                var key  = MD5.Compute(options.Key).ToLowerInvariant();
                var data = AesHelper.Decrypt((notify as Notify.WeChatPayRefundNotify).ReqInfo, key); //todo  PKCS7  Encrypt
                notify = parser.Parse(body, data);
            }
            else
            {
                CheckNotifySign(notify, options);
            }

            return(Task.FromResult(notify));
        }
        /// <summary>
        /// 计算指定证书的序列号
        /// </summary>
        /// <param name="certificate">证书</param>
        public static string GetCertSN(X509Certificate2 certificate)
        {
            // 删除逗号后面的空格
            var issuer = certificate.Issuer.ToString().Replace(", ", ",");

            //提取出的证书的issuerDN本身是以CN开头的,则无需逆序,直接返回
            if (issuer.StartsWith("CN", StringComparison.Ordinal))
            {
                return(MD5.Compute(issuer + BigInteger.Parse(certificate.SerialNumber, NumberStyles.HexNumber).ToString()).ToLowerInvariant());
            }
            else
            {
                var attributes = issuer.Split(',').ToList();
                attributes.Reverse();

                return(MD5.Compute(string.Join(",", attributes.ToArray()) + BigInteger.Parse(certificate.SerialNumber, NumberStyles.HexNumber).ToString()).ToLowerInvariant());
            }
        }