Пример #1
0
        private ResponseParseItem ParseRespItem <T>(IAlipayRequest <T> request, string respBody, IAlipayParser <T> parser, string encryptKey, string encryptType) where T : AlipayResponse
        {
            string realContent;

            if (request.GetNeedEncrypt())
            {
                realContent = parser.EncryptSourceData(request, respBody, encryptType, encryptKey);
            }
            else
            {
                realContent = respBody;
            }

            return(new ResponseParseItem
            {
                RealContent = realContent,
                RespContent = respBody
            });
        }
Пример #2
0
        private void CheckResponseSign <T>(IAlipayRequest <T> request, string responseBody, bool isError, IAlipayParser <T> parser, AlipayOptions options) where T : AlipayResponse
        {
            var signItem = parser.GetSignItem(request, responseBody);

            if (signItem == null)
            {
                throw new AlipayException("sign check fail: Body is Empty!");
            }

            if (!isError || isError && !string.IsNullOrEmpty(signItem.Sign))
            {
                var rsaCheckContent = AlipaySignature.RSACheckContent(signItem.SignSourceDate, signItem.Sign, options.AlipayPublicKey, options.SignType);
                if (!rsaCheckContent)
                {
                    if (!string.IsNullOrEmpty(signItem.SignSourceDate) && signItem.SignSourceDate.Contains("\\/"))
                    {
                        var srouceData = signItem.SignSourceDate.Replace("\\/", "/");
                        var jsonCheck  = AlipaySignature.RSACheckContent(srouceData, signItem.Sign, options.AlipayPublicKey, options.SignType);
                        if (!jsonCheck)
                        {
                            throw new AlipayException("sign check fail: check Sign and Data Fail JSON also");
                        }
                    }
                    else
                    {
                        throw new AlipayException("sign check fail: check Sign and Data Fail!");
                    }
                }
            }
        }
Пример #3
0
        private async Task CheckResponseCertSignAsync <T>(IAlipayRequest <T> request, string responseBody, bool isError, IAlipayParser <T> parser, AlipayOptions options) where T : AlipayResponse
        {
            if (request is AlipayOpenAppAlipaycertDownloadRequest)
            {
                return;
            }

            var certItem = parser.GetCertItem(request, responseBody);

            if (certItem == null)
            {
                throw new AlipayException("sign check fail: Body is Empty!");
            }

            if (!isError || isError && !string.IsNullOrEmpty(certItem.Sign))
            {
                var currentAlipayPublicKey = await LoadAlipayPublicKeyAsync(certItem, options);

                var rsaCheckContent = AlipaySignature.RSACheckContent(certItem.SignSourceDate, certItem.Sign, currentAlipayPublicKey, options.SignType);
                if (!rsaCheckContent)
                {
                    if (!string.IsNullOrEmpty(certItem.SignSourceDate) && certItem.SignSourceDate.Contains("\\/"))
                    {
                        var srouceData = certItem.SignSourceDate.Replace("\\/", "/");
                        var jsonCheck  = AlipaySignature.RSACheckContent(srouceData, certItem.Sign, currentAlipayPublicKey, options.SignType);
                        if (!jsonCheck)
                        {
                            throw new AlipayException("sign check fail: check Sign and Data Fail JSON also");
                        }
                    }
                    else
                    {
                        throw new AlipayException("sign check fail: check Sign and Data Fail!");
                    }
                }
            }
        }
Пример #4
0
        public async Task <T> PageExecuteAsync <T>(IAlipayRequest <T> request, string accessToken, string reqMethod) where T : AlipayResponse
        {
            string apiVersion = null;

            if (!string.IsNullOrEmpty(request.GetApiVersion()))
            {
                apiVersion = request.GetApiVersion();
            }
            else
            {
                apiVersion = Options.Version;
            }

            var txtParams = new AlipayDictionary(request.GetParameters())
            {
                // 序列化BizModel
                { BIZ_CONTENT, JsonConvert.SerializeObject(request.GetBizModel(), new JsonSerializerSettings()
                    {
                        NullValueHandling = NullValueHandling.Ignore
                    }) },
                // 添加协议级请求参数
                { METHOD, request.GetApiName() },
                { VERSION, apiVersion },
                { APP_ID, Options.AppId },
                { FORMAT, Options.Format },
                { TIMESTAMP, DateTime.Now },
                { ACCESS_TOKEN, accessToken },
                { SIGN_TYPE, Options.SignType },
                { TERMINAL_TYPE, request.GetTerminalType() },
                { TERMINAL_INFO, request.GetTerminalInfo() },
                { PROD_CODE, request.GetProdCode() },
                { NOTIFY_URL, request.GetNotifyUrl() },
                { CHARSET, Options.Charset },
                { RETURN_URL, request.GetReturnUrl() }
            };

            // 添加签名参数
            txtParams.Add(SIGN, AlipaySignature.RSASign(txtParams, Options.RsaPrivateKey, Options.SignType));

            // 是否需要上传文件
            string body;

            if (request is IAlipayUploadRequest <T> uRequest)
            {
                var fileParams = AlipayUtility.CleanupDictionary(uRequest.GetFileParameters());
                body = await Client.DoPostAsync(Options.ServerUrl, txtParams, fileParams);
            }
            else
            {
                if (reqMethod.Equals("GET"))
                {
                    //拼接get请求的url
                    var tmpUrl = Options.ServerUrl;
                    if (txtParams != null && txtParams.Count > 0)
                    {
                        if (tmpUrl.Contains("?"))
                        {
                            tmpUrl = tmpUrl + "&" + HttpClientEx.BuildQuery(txtParams);
                        }
                        else
                        {
                            tmpUrl = tmpUrl + "?" + HttpClientEx.BuildQuery(txtParams);
                        }
                    }
                    body = tmpUrl;
                }
                else
                {
                    //输出post表单
                    body = BuildHtmlRequest(txtParams, reqMethod, reqMethod);
                }
            }

            T rsp = null;
            IAlipayParser <T> parser = null;

            if ("json".Equals(Options.Format))
            {
                parser = new AlipayJsonParser <T>();
                rsp    = parser.Parse(body);
            }
            return(rsp);
        }
Пример #5
0
        public async Task <T> ExecuteAsync <T>(IAlipayRequest <T> request, string accessToken, string appAuthToken) where T : AlipayResponse
        {
            string apiVersion = null;

            if (!string.IsNullOrEmpty(request.GetApiVersion()))
            {
                apiVersion = request.GetApiVersion();
            }
            else
            {
                apiVersion = Options.Version;
            }

            // 添加协议级请求参数
            var txtParams = new AlipayDictionary(request.GetParameters())
            {
                { BIZ_CONTENT, JsonConvert.SerializeObject(request.GetBizModel(), new JsonSerializerSettings()
                    {
                        NullValueHandling = NullValueHandling.Ignore
                    }) },
                { METHOD, request.GetApiName() },
                { VERSION, apiVersion },
                { APP_ID, Options.AppId },
                { FORMAT, Options.Format },
                { TIMESTAMP, DateTime.Now },
                { ACCESS_TOKEN, accessToken },
                { SIGN_TYPE, Options.SignType },
                { TERMINAL_TYPE, request.GetTerminalType() },
                { TERMINAL_INFO, request.GetTerminalInfo() },
                { PROD_CODE, request.GetProdCode() },
                { CHARSET, Options.Charset }
            };

            if (!string.IsNullOrEmpty(request.GetNotifyUrl()))
            {
                txtParams.Add(NOTIFY_URL, request.GetNotifyUrl());
            }

            if (!string.IsNullOrEmpty(appAuthToken))
            {
                txtParams.Add(APP_AUTH_TOKEN, appAuthToken);
            }

            if (request.GetNeedEncrypt())
            {
                if (string.IsNullOrEmpty(txtParams[BIZ_CONTENT]))
                {
                    throw new AlipayException("api request Fail ! The reason: encrypt request is not supported!");
                }

                if (string.IsNullOrEmpty(Options.EncyptKey) || string.IsNullOrEmpty(Options.EncyptType))
                {
                    throw new AlipayException("encryptType or encryptKey must not null!");
                }

                if (!"AES".Equals(Options.EncyptType))
                {
                    throw new AlipayException("api only support Aes!");
                }

                var encryptContent = AlipayUtility.AesEncrypt(Options.EncyptKey, txtParams[BIZ_CONTENT]);
                txtParams.Remove(BIZ_CONTENT);
                txtParams.Add(BIZ_CONTENT, encryptContent);
                txtParams.Add(ENCRYPT_TYPE, Options.EncyptType);
            }

            // 添加签名参数
            txtParams.Add(SIGN, AlipaySignature.RSASign(txtParams, Options.RsaPrivateKey, Options.SignType));

            // 是否需要上传文件
            string body;

            if (request is IAlipayUploadRequest <T> uRequest)
            {
                var fileParams = AlipayUtility.CleanupDictionary(uRequest.GetFileParameters());
                body = await Client.DoPostAsync(Options.ServerUrl, txtParams, fileParams);
            }
            else
            {
                body = await Client.DoPostAsync(Options.ServerUrl, txtParams);
            }

            T rsp = null;
            IAlipayParser <T> parser = null;

            if ("json".Equals(Options.Format))
            {
                parser = new AlipayJsonParser <T>();
            }

            var item = ParseRespItem(request, body, parser, Options.EncyptKey, Options.EncyptType);

            rsp = parser.Parse(item.realContent);

            CheckResponseSign(request, item.respContent, rsp.IsError, parser, Options.RsaPublicKey, Options.SignType);

            return(rsp);
        }
Пример #6
0
        public async Task <T> ExecuteAsync <T>(IAlipayRequest <T> request, string accessToken, string appAuthToken) where T : AlipayResponse
        {
            var apiVersion = string.Empty;

            if (!string.IsNullOrEmpty(request.GetApiVersion()))
            {
                apiVersion = request.GetApiVersion();
            }
            else
            {
                apiVersion = Options.Version;
            }

            // 添加协议级请求参数
            var txtParams = new AlipayDictionary(request.GetParameters())
            {
                // 序列化BizModel
                { BIZ_CONTENT, Serialize(request.GetBizModel()) },
                // 添加协议级请求参数
                { METHOD, request.GetApiName() },
                { VERSION, apiVersion },
                { APP_ID, Options.AppId },
                { FORMAT, Options.Format },
                { TIMESTAMP, DateTime.Now },
                { ACCESS_TOKEN, accessToken },
                { SIGN_TYPE, Options.SignType },
                { TERMINAL_TYPE, request.GetTerminalType() },
                { TERMINAL_INFO, request.GetTerminalInfo() },
                { PROD_CODE, request.GetProdCode() },
                { CHARSET, Options.Charset }
            };

            if (!string.IsNullOrEmpty(request.GetNotifyUrl()))
            {
                txtParams.Add(NOTIFY_URL, request.GetNotifyUrl());
            }

            if (!string.IsNullOrEmpty(appAuthToken))
            {
                txtParams.Add(APP_AUTH_TOKEN, appAuthToken);
            }

            if (request.GetNeedEncrypt())
            {
                if (string.IsNullOrEmpty(txtParams[BIZ_CONTENT]))
                {
                    throw new Exception("api request Fail ! The reason: encrypt request is not supported!");
                }

                if (string.IsNullOrEmpty(Options.EncyptKey) || string.IsNullOrEmpty(Options.EncyptType))
                {
                    throw new Exception("encryptType or encryptKey must not null!");
                }

                if (!"AES".Equals(Options.EncyptType))
                {
                    throw new Exception("api only support Aes!");
                }

                var encryptContent = AES.Encrypt(txtParams[BIZ_CONTENT], Options.EncyptKey, AlipaySignature.AES_IV, AESCipherMode.CBC, AESPaddingMode.PKCS7);
                txtParams.Remove(BIZ_CONTENT);
                txtParams.Add(BIZ_CONTENT, encryptContent);
                txtParams.Add(ENCRYPT_TYPE, Options.EncyptType);
            }

            // 添加签名参数
            var signContent = AlipaySignature.GetSignContent(txtParams);

            txtParams.Add(SIGN, AlipaySignature.RSASignContent(signContent, PrivateRSAParameters, Options.SignType));

            var query = HttpClientEx.BuildQuery(txtParams);

            Logger?.LogTrace(0, "Request:{query}", query);

            // 是否需要上传文件
            var body = string.Empty;

            if (request is IAlipayUploadRequest <T> uRequest)
            {
                var fileParams = AlipayUtility.CleanupDictionary(uRequest.GetFileParameters());
                body = await Client.DoPostAsync(Options.ServerUrl, txtParams, fileParams);
            }
            else
            {
                body = await Client.DoPostAsync(Options.ServerUrl, query);
            }

            Logger?.LogTrace(1, "Response:{body}", body);

            T rsp = null;
            IAlipayParser <T> parser = null;

            if ("xml".Equals(Options.Format))
            {
                parser = new AlipayXmlParser <T>();
                rsp    = parser.Parse(body);
            }
            else
            {
                parser = new AlipayJsonParser <T>();
                rsp    = parser.Parse(body);
            }

            var item = ParseRespItem(request, body, parser, Options.EncyptKey, Options.EncyptType);

            rsp = parser.Parse(item.realContent);

            CheckResponseSign(request, item.respContent, rsp.IsError, parser, PublicRSAParameters, Options.SignType);

            return(rsp);
        }
Пример #7
0
        private async Task CheckResponseCertSignAsync <T>(IAlipayRequest <T> request, string responseBody, bool isError, IAlipayParser <T> parser, AlipayOptions options) where T : AlipayResponse
        {
            var certItem = parser.GetCertItem(request, responseBody);

            if (certItem == null)
            {
                throw new AlipayException("cert check fail: Body is Empty!");
            }

            if (!string.IsNullOrEmpty(certItem.CertSN))
            {
                // 为空时添加本地支付宝公钥证书密钥
                if (_alipayPublicKeyManager.IsEmpty)
                {
                    _alipayPublicKeyManager.TryAdd(options.AlipayPublicCertSN, options.AlipayPublicKey);
                }

                // 如果返回的支付宝公钥证书序列号与本地支付宝公钥证书序列号不匹配,通过返回的支付宝公钥证书序列号去网关拉取新的支付宝公钥证书
                if (!_alipayPublicKeyManager.ContainsKey(certItem.CertSN))
                {
                    var model = new AlipayOpenAppAlipaycertDownloadModel
                    {
                        AlipayCertSn = certItem.CertSN
                    };

                    var req = new AlipayOpenAppAlipaycertDownloadRequest();
                    req.SetBizModel(model);

                    var response = await CertificateExecuteAsync(req, options);

                    if (response.IsError)
                    {
                        throw new AlipayException("支付宝公钥证书校验失败,请确认是否为支付宝签发的有效公钥证书");
                    }

                    if (!AntCertificationUtil.IsTrusted(response.AlipayCertContent, options.RootCert))
                    {
                        throw new AlipayException("支付宝公钥证书校验失败,请确认是否为支付宝签发的有效公钥证书");
                    }

                    var alipayCert          = AntCertificationUtil.ParseCert(response.AlipayCertContent);
                    var alipayCertSN        = AntCertificationUtil.GetCertSN(alipayCert);
                    var alipayCertPublicKey = AntCertificationUtil.ExtractPemPublicKeyFromCert(alipayCert);

                    _alipayPublicKeyManager.TryAdd(alipayCertSN, alipayCertPublicKey);
                }

                // 针对成功结果且有支付宝公钥的进行验签
                if (_alipayPublicKeyManager.TryGetValue(certItem.CertSN, out var alipayPublicKey))
                {
                    if (!isError || isError && !string.IsNullOrEmpty(certItem.Sign))
                    {
                        var rsaCheckContent = AlipaySignature.RSACheckContent(certItem.SignSourceDate, certItem.Sign, alipayPublicKey, options.Charset, options.SignType);
                        if (!rsaCheckContent)
                        {
                            // 针对JSON \/问题,替换/后再尝试做一次验证
                            if (!string.IsNullOrEmpty(certItem.SignSourceDate) && certItem.SignSourceDate.Contains("\\/"))
                            {
                                var srouceData = certItem.SignSourceDate.Replace("\\/", "/");
                                var jsonCheck  = AlipaySignature.RSACheckContent(srouceData, certItem.Sign, alipayPublicKey, options.Charset, options.SignType);
                                if (!jsonCheck)
                                {
                                    throw new AlipayException("cert check fail: check Cert and Data Fail JSON also");
                                }
                            }
                            else
                            {
                                throw new AlipayException("cert check fail: check Cert and Data Fail!");
                            }
                        }
                    }
                }
                else
                {
                    throw new AlipayException("cert check fail: check Cert and Data Fail! CertSN non-existent");
                }
            }
        }
Пример #8
0
        public async Task<T> PageExecuteAsync<T>(IAlipayRequest<T> request, string accessToken, string reqMethod) where T : AlipayResponse
        {
            string apiVersion = null;

            if (!string.IsNullOrEmpty(request.GetApiVersion()))
            {
                apiVersion = request.GetApiVersion();
            }
            else
            {
                apiVersion = Options.Version;
            }

            var txtParams = new AlipayDictionary(request.GetParameters())
            {
                // 序列化BizModel
                { BIZ_CONTENT, Serialize(request.GetBizModel()) },
                // 添加协议级请求参数
                { METHOD, request.GetApiName() },
                { VERSION, apiVersion },
                { APP_ID, Options.AppId },
                { FORMAT, Options.Format },
                { TIMESTAMP, DateTime.Now },
                { ACCESS_TOKEN, accessToken },
                { SIGN_TYPE, Options.SignType },
                { TERMINAL_TYPE, request.GetTerminalType() },
                { TERMINAL_INFO, request.GetTerminalInfo() },
                { PROD_CODE, request.GetProdCode() },
                { NOTIFY_URL, request.GetNotifyUrl() },
                { CHARSET, Options.Charset },
                { RETURN_URL, request.GetReturnUrl() }
            };

            // 添加签名参数
            var signContent = AlipaySignature.GetSignContent(txtParams);
            txtParams.Add(SIGN, AlipaySignature.RSASignContent(signContent, Options.PrivateRSAParameters, Options.SignType));

            // 是否需要上传文件
            var body = string.Empty;

            if (request is IAlipayUploadRequest<T> uRequest)
            {
                var fileParams = AlipayUtility.CleanupDictionary(uRequest.GetFileParameters());

                using (var client = ClientFactory.CreateClient(AlipayOptions.DefaultClientName))
                {
                    body = await HttpClientUtility.DoPostAsync(client, Options.ServerUrl, txtParams, fileParams);
                }
            }
            else
            {

                if (reqMethod.ToUpper() == "GET")
                {
                    //拼接get请求的url
                    var tmpUrl = Options.ServerUrl;
                    if (txtParams != null && txtParams.Count > 0)
                    {
                        if (tmpUrl.Contains("?"))
                        {
                            tmpUrl = tmpUrl + "&" + AlipayUtility.BuildQuery(txtParams);
                        }
                        else
                        {
                            tmpUrl = tmpUrl + "?" + AlipayUtility.BuildQuery(txtParams);
                        }
                    }
                    body = tmpUrl;
                    Logger?.LogTrace(0, "Request Url:{body}", body);
                }
                else
                {
                    //输出post表单
                    body = BuildHtmlRequest(txtParams, reqMethod);
                    Logger?.LogTrace(0, "Request Html:{body}", body);
                }
            }

            T rsp = null;
            IAlipayParser<T> parser = null;
            if ("xml".Equals(Options.Format))
            {
                parser = new AlipayXmlParser<T>();
                rsp = parser.Parse(body);
            }
            else
            {
                parser = new AlipayJsonParser<T>();
                rsp = parser.Parse(body);
            }
            return rsp;
        }
Пример #9
0
        private void CheckResponseSign <T>(IAlipayRequest <T> request, string responseBody, bool isError, IAlipayParser <T> parser, RSAParameters parameters, string signType) where T : AlipayResponse
        {
            try
            {
                logger?.LogDebug($"{DateTime.Now} 支付宝CheckResponseSign");

                var signItem = parser.GetSignItem(request, responseBody);
                if (signItem == null)
                {
                    throw new Exception("sign check fail: Body is Empty!");
                }

                if (!isError || (isError && !string.IsNullOrEmpty(signItem.Sign)))
                {
                    var rsaCheckContent = AlipaySignature.RSACheckContent(signItem.SignSourceDate, signItem.Sign, parameters, signType);
                    if (!rsaCheckContent)
                    {
                        if (!string.IsNullOrEmpty(signItem.SignSourceDate) && signItem.SignSourceDate.Contains("\\/"))
                        {
                            var srouceData = signItem.SignSourceDate.Replace("\\/", "/");
                            var jsonCheck  = AlipaySignature.RSACheckContent(srouceData, signItem.Sign, parameters, signType);
                            if (!jsonCheck)
                            {
                                throw new Exception("sign check fail: check Sign and Data Fail JSON also");
                            }
                        }
                        else
                        {
                            throw new Exception("sign check fail: check Sign and Data Fail!");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                logger?.LogError($"{DateTime.Now} 支付宝CheckResponseSign报错", ex.Message);
            }
        }
Пример #10
0
        private ResponseParseItem ParseRespItem <T>(IAlipayRequest <T> request, string respBody, IAlipayParser <T> parser, string encryptKey, string encryptType) where T : AlipayResponse
        {
            try
            {
                logger?.LogDebug($"{DateTime.Now} 支付宝ParseRespItem");

                string realContent = null;

                if (request.GetNeedEncrypt())
                {
                    realContent = parser.EncryptSourceData(request, respBody, encryptType, encryptKey);
                }
                else
                {
                    realContent = respBody;
                }

                var item = new ResponseParseItem()
                {
                    realContent = realContent,
                    respContent = respBody
                };
                return(item);
            }
            catch (Exception ex)
            {
                logger?.LogError($"{DateTime.Now} 支付宝ParseRespItem报错", ex.Message);
                return(null);
            }
        }