コード例 #1
0
        private static void AddSign(HttpClient client, String interfaceUrl, String requestBody)
        {
            String requestId     = Guid.NewGuid().ToString("N");
            String timestamp     = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzzz");
            String version       = "yop-auth-v2";
            String expireSeconds = "1800";
            String appKey        = GlobalConfig.YeePay_FundOut_AppKey;

            var signHeaders = new SortedDictionary <String, String>();

            signHeaders["x-yop-appkey"]     = appKey;
            signHeaders["x-yop-request-id"] = requestId;
            signHeaders["x-yop-date"]       = timestamp;

            foreach (var key in signHeaders.Keys)
            {
                client.DefaultRequestHeaders.Remove(key);
                client.DefaultRequestHeaders.Add(key, signHeaders[key]);
            }

            //签名内容的请求头部分
            String signHeaderSignContent = String.Join("\n", signHeaders.Select(x => $"{WebUtil.UrlEncode(x.Key)}:{UrlEncodeToUpper(WebUtil.UrlEncode(x.Value))}"));

            //签名内容
            String signContent = $"{version}/{appKey}/{timestamp}/{expireSeconds}\nPOST\n{interfaceUrl}\n{requestBody}\n{signHeaderSignContent}";

            var sign = SignUtil.MakeSign(signContent, KeyConfig.YeePay_FundOut_Hehua_PrivateKey, PrivateKeyFormat.PKCS1, "RSA2");

            if (sign.Success)
            {
                String signHeaderNames   = String.Join(";", signHeaders.Keys);
                String base64SignContent = EncodeBase64(sign.Value) + "$SHA256";

                client.DefaultRequestHeaders.Remove("Authorization");
                String auth = GetAuthorization(version, appKey, timestamp, expireSeconds, signHeaderNames, base64SignContent);
                _logger.Debug($"Authorization={auth}");
                client.DefaultRequestHeaders.Add("Authorization", auth);
            }
        }
コード例 #2
0
        public static XResult <TResult> Execute <TRequest, TResult>(String interfaceUrl, TRequest request)
        {
            if (request == null)
            {
                return(new XResult <TResult>(default(TResult), new ArgumentNullException(nameof(request))));
            }

            String service = $"{typeof(YeePayFundOutUtil).FullName}.Execute(...)";

            var client = GetClient();

            var requestDic = CommonUtil.ToDictionary(request);

            if (requestDic == null || requestDic.Count == 0)
            {
                return(new XResult <TResult>(default(TResult), ErrorCode.INVALID_CAST, new InvalidCastException("将请求对象转换成字典失败")));
            }

            //签名内容的请求内容部分
            requestDic["method"] = interfaceUrl;
            requestDic["appKey"] = GlobalConfig.YeePay_FundOut_AppKey;
            requestDic["locale"] = "zh_CN";
            requestDic["ts"]     = GetTimeStamp();
            requestDic["v"]      = "1.0";

            var orderedDic = new SortedDictionary <String, String>(requestDic);

            foreach (var key in orderedDic.Keys.ToList())
            {
                orderedDic[key] = UrlEncodeToUpper(WebUtil.UrlEncode(orderedDic[key]));
            }

            String requestBody = String.Join("&",
                                             from t0 in orderedDic
                                             select $"{t0.Key}={t0.Value}");

            AddSign(client, interfaceUrl, requestBody);

            String requestUrl  = $"{ApiConfig.YeePay_FundOut_RequestUrl}{interfaceUrl}";
            String traceMethod = $"{nameof(client)}.PostForm(...)";

            _logger.Trace(TraceType.UTIL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, "开始请求易宝代付接口", new Object[] { requestUrl, requestDic });

            var result = client.PostForm(requestUrl, orderedDic);

            _logger.Trace(TraceType.UTIL.ToString(), (result.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.ACTION, "结束请求易宝代付接口");

            if (!result.Success)
            {
                _logger.Error(TraceType.UTIL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, $"调用易宝代付接口失败:{result.ErrorMessage}", result.FirstException);
                return(new XResult <TResult>(default(TResult), result.FirstException));
            }

            if (result.Value == null)
            {
                _logger.Error(TraceType.UTIL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, $"调用易宝代付接口超时");
                return(new XResult <TResult>(default(TResult), ErrorCode.REQUEST_TIMEOUT));
            }

            try
            {
                String respString = result.Value.Content.ReadAsStringAsync().GetAwaiter().GetResult();

                String compressedRespString = CompressJsonString(respString);

                _logger.Trace(TraceType.UTIL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.END, "易宝代付返回结果", compressedRespString);

                if (respString.IsNullOrWhiteSpace())
                {
                    return(new XResult <TResult>(default(TResult), ErrorCode.REMOTE_RETURN_NOTHING, new RemoteException("支付机构未返回任何数据")));
                }

                var respDic = JsonUtil.GetJToken(compressedRespString);

                var state = respDic.GetValue <String>("state");

                if (state == "FAILURE")
                {
                    var errorDecodeResult = JsonUtil.DeserializeObject <IDictionary <String, String> >(respDic["error"].ToString());
                    if (!errorDecodeResult.Success)
                    {
                        _logger.Error(TraceType.UTIL.ToString(), CallResultStatus.ERROR.ToString(), service, "errorDecodeResult", "易宝返回的数据无法反序列化", errorDecodeResult.FirstException, respDic["error"]);
                        return(new XResult <TResult>(default(TResult), ErrorCode.DESERIALIZE_FAILED, errorDecodeResult.FirstException));
                    }

                    return(new XResult <TResult>(default(TResult), ErrorCode.FAILURE, new RemoteException(respDic["message"].ToString())));
                }

                //验签返回的结果
                String signContent = GetResultJsonValue(compressedRespString);
                if (!VerifySign(signContent, respDic.GetValue <String>("sign"), out String signError))
                {
                    return(new XResult <TResult>(default(TResult), ErrorCode.SIGN_VERIFY_FAILED, new SignException(signError)));
                }

                var payResult = JsonUtil.DeserializeObject <TResult>(signContent);
                if (!payResult.Success)
                {
                    _logger.Error(TraceType.UTIL.ToString(), CallResultStatus.ERROR.ToString(), service, "payResult", "易宝返回的数据无法反序列化", payResult.FirstException, respDic["error"]);
                    return(new XResult <TResult>(default(TResult), ErrorCode.DESERIALIZE_FAILED, new ArgumentException($"参数payResult无法转换成{nameof(TResult)}类型")));
                }

                return(new XResult <TResult>(payResult.Value));
            }
            catch (Exception ex)
            {
                return(new XResult <TResult>(default(TResult), ex));
            }
        }