Example #1
0
        public XResult <PersonalInfoQueryResponse> GetAccountInfo(PersonalInfoQueryRequest request)
        {
            if (request == null)
            {
                return(new XResult <PersonalInfoQueryResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.GetAccountInfo(...)";

            if (!request.IsValid)
            {
                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(request)}.IsValid", LogPhase.ACTION, $"请求参数验证失败:{request.ErrorMessage}", request);
                return(new XResult <PersonalInfoQueryResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            var requestHash = $"getaccountinfo:{request.PayeeId}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <PersonalInfoQueryResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <PersonalInfoQueryResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existedRegisterInfo = _personalSubAccountRepository.QueryProvider.FirstOrDefault(x => x.UID == request.PayeeId);
                if (existedRegisterInfo == null)
                {
                    return(new XResult <PersonalInfoQueryResponse>(null, ErrorCode.UN_REGISTERED));
                }

                if (existedRegisterInfo.Status != PersonalInfoRegisterStatus.SUCCESS.ToString())
                {
                    var queryResult = Bill99UtilYZT.Execute <RawPersonalInfoQueryRequest, RawPersonalInfoQueryResponse>("/person/info", new RawPersonalInfoQueryRequest()
                    {
                        PayeeId = request.PayeeId
                    });

                    if (queryResult.Success && queryResult.Value != null && queryResult.Value.AuditStatus == "03")
                    {
                        existedRegisterInfo.Status = PersonalInfoRegisterStatus.SUCCESS.ToString();
                        _personalSubAccountRepository.Update(existedRegisterInfo);
                        var updateStatusResult = _personalSubAccountRepository.SaveChanges();
                        if (!updateStatusResult.Success)
                        {
                            _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_personalSubAccountRepository)}.SaveChanges()", "更新开户状态失败", updateStatusResult.FirstException, existedRegisterInfo);
                        }
                    }
                }

                return(new XResult <PersonalInfoQueryResponse>(new PersonalInfoQueryResponse()
                {
                    PayeeId = existedRegisterInfo.UID,
                    Email = existedRegisterInfo.Email,
                    IDCardNo = existedRegisterInfo.IDCardNo,
                    IDCardType = existedRegisterInfo.IDCardType,
                    Mobile = existedRegisterInfo.Mobile,
                    RealName = existedRegisterInfo.RealName,
                    Status = existedRegisterInfo.Status,
                    Msg = GetRegisterAuditStatusMsg(existedRegisterInfo.Status)
                }));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
        public XResult <SingleSettlementPaymentApplyResponse> Pay(SingleSettlementPaymentApplyRequest request)
        {
            if (request == null)
            {
                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException($"{nameof(request)}为null")));
            }

            if (!request.IsValid)
            {
                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.{nameof(Pay)}(...)";

            var requestHash = $"{nameof(Pay)}:{request.OrderNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                Boolean existOrder = true;
                try
                {
                    existOrder = (from t0 in _fundOutOrderRepository.QueryProvider
                                  where t0.OutTradeNo == request.OrderNo
                                  select t0.Id).Count() > 0;
                }
                catch (Exception ex)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "existOrder", "查询订单失败", ex, request);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DB_QUERY_FAILED, new DbQueryException($"查询订单号失败,订单号:{request.OrderNo}")));
                }

                if (existOrder)
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                Int64  newId   = IDGenerator.GenerateID();
                String tradeNo = newId.ToString();

                var fundoutOrder = new FundOutOrder()
                {
                    Id         = newId,
                    AppId      = request.AppId,
                    TradeNo    = tradeNo,
                    OutTradeNo = request.OrderNo,
                    Amount     = request.Amount,
                    RealName   = request.CreditName,
                    PayStatus  = PayStatus.PROCESSING.ToString(),
                    FeeAction  = request.FeeAction,
                    BankCardNo = request.BankCardNo,
                    BankName   = request.BankName,
                    Mobile     = request.Mobile,
                    CreateTime = DateTime.Now,
                    Remark     = request.Remark
                };

                //入库
                _fundOutOrderRepository.Add(fundoutOrder);
                var saveResult = _fundOutOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存订单失败", saveResult.FirstException, fundoutOrder);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException($"保存订单失败,订单编号:{fundoutOrder.OutTradeNo}")));
                }

                //开始执行代付
                var requestBuilder = new RequestBuilder(_serializer, _logger)
                {
                    EncryptKey      = CryptoHelper.GenerateRandomKey(),
                    RequestType     = "pay2BankRequest",
                    RequestHead     = "pay2bankHead",
                    RequestBodyType = "requestBody",
                    RequestBody     = request
                };

                var postXml = requestBuilder.Build(doc =>
                {
                    var amountEl = doc.Root.Element("amount");
                    if (amountEl != null)
                    {
                        var amountText = amountEl.Value;
                        if (Decimal.TryParse(amountText, out Decimal amount))
                        {
                            amountEl.Value = Convert.ToInt32(amount * 100m).ToString();
                        }
                    }
                });

                //更新申请时间
                fundoutOrder.ApplyTime = DateTime.Now;

                String callMethod = $"{nameof(_client)}.PostXml(...)";

                _logger.Trace(TraceType.BLL.ToString(), nameof(CallResultStatus.OK), service, callMethod, LogPhase.BEGIN, $"开始调用{callMethod}", new Object[] { ApiConfig.Bill99FOSinglePayApplyRequestUrl, postXml });

                var postResult = _client.PostXml(ApiConfig.Bill99FOSinglePayApplyRequestUrl, postXml);

                _logger.Trace(TraceType.BLL.ToString(), (postResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, callMethod, LogPhase.ACTION, $"完成调用{callMethod}");

                if (!postResult.Success)
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, postResult.FirstException));
                }

                String resp = null;
                try
                {
                    resp = postResult.Value.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    _logger.Trace(TraceType.BLL.ToString(), nameof(CallResultStatus.OK), service, callMethod, LogPhase.END, $"调用{callMethod}结果", resp);
                }
                catch (Exception ex)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, callMethod, "读取第三方返回的消息内容失败", ex, postXml);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, ex));
                }

                if (String.IsNullOrWhiteSpace(resp))
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                //更新结束时间
                fundoutOrder.EndTime = DateTime.Now;

                var parseResult = ParseXml(resp);
                if (!parseResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, "ParseXml(...)", "解析返回数据失败", parseResult.FirstException, resp);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.XML_PARSE_FAILED, new SystemException("解析返回数据失败")));
                }

                var root = parseResult.Value.Root;

                var memberCodeEl = root.Descendants("memberCode").FirstOrDefault();
                if (memberCodeEl == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, "memberCodeEl", "返回数据中未包含<memberCode></memberCode>元素");
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.XML_ELEMENT_NOT_EXIST, new RemoteException("<memberCode> not found")));
                }

                var decodeResult = Decode(root, "responseBody");
                if (!decodeResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"Decode(...)", "解码失败");
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DECODE_FAILED, decodeResult.FirstException));
                }

                var deserializeResult = Deserialize <SingleSettlementPaymentApplyResponse>(decodeResult.Value);
                if (deserializeResult.Success && deserializeResult.Value != null)
                {
                    var result = deserializeResult.Value;
                    result.MemberCode = memberCodeEl.Value;

                    var errorCodeEl = root.Descendants("errorCode").FirstOrDefault();
                    if (errorCodeEl != null)
                    {
                        result.ErrorCode = errorCodeEl.Value;
                    }

                    var errorMsgEl = root.Descendants("errorMsg").FirstOrDefault();
                    if (errorMsgEl != null)
                    {
                        result.ErrorMessage = errorMsgEl.Value;
                    }

                    //将以分为单位的金额转成以元为单位
                    result.Amount *= 0.01m;

                    //更新时间
                    fundoutOrder.UpdateTime = DateTime.Now;
                    //将申请时间、结束时间和更新时间更新到数据库
                    _fundOutOrderRepository.Update(fundoutOrder);
                    var updateResult = _fundOutOrderRepository.SaveChanges();
                    if (!updateResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "更新代付订单申请时间|结束时间|更新时间失败", updateResult.FirstException, fundoutOrder);
                    }

                    return(new XResult <SingleSettlementPaymentApplyResponse>(result));
                }

                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DESERIALIZE_FAILED, deserializeResult.FirstException));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Example #3
0
        public XResult <PayResponse> Pay(PayRequest request)
        {
            if (request == null)
            {
                return(new XResult <PayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.Pay(...)";

            if (!request.IsValid)
            {
                return(new XResult <PayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            var requestHash = $"pay:{request.AppId}.{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <PayResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <PayResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existsOutTradeNo = _fundOutOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <PayResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //申请冻结商户放款余额
                var applyFreezeLoanParas = new Dictionary <String, String>(4);
                applyFreezeLoanParas["MerchantNo"]        = request.MerchantNo;
                applyFreezeLoanParas["OrderNo"]           = request.OutTradeNo;
                applyFreezeLoanParas["FrozenLoanBalance"] = request.Amount;
                applyFreezeLoanParas["Sign"] = MerchantUtil.MD5Sign(applyFreezeLoanParas);

                var client = GetClient();

                String traceMethod = $"{nameof(client)}.PostForm(...)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, "开始请求商户系统冻结放款余额", new Object[] { ApiConfig.SystemMerchantAccountBalanceFreezeRequestUrl, applyFreezeLoanParas });

                var freezeResult = client.PostForm <ApiResult>(ApiConfig.SystemMerchantAccountBalanceFreezeRequestUrl, applyFreezeLoanParas);

                _logger.Trace(TraceType.BLL.ToString(), (freezeResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.END, "结束请求商户系统冻结放款余额", freezeResult.Value);

                if (!freezeResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "商户系统冻结放款余额失败", freezeResult.FirstException, applyFreezeLoanParas);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException("商户系统冻结放款余额失败")));
                }

                if (freezeResult.Value == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "商户系统冻结放款余额返回的业务数据为空", null, applyFreezeLoanParas);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException("商户系统冻结放款余额返回的业务数据为空")));
                }

                if (freezeResult.Value.Status != "SUCCESS")
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, LogPhase.ACTION, "商户系统冻结放款余额失败", freezeResult.Value);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException("商户系统冻结放款余额失败")));
                }

                var now   = DateTime.Now;
                var newId = IDGenerator.GenerateID();

                var fundoutOrder = new FundOutOrder()
                {
                    Id         = newId,
                    TradeNo    = newId.ToString(),
                    AppId      = request.AppId,
                    OutTradeNo = request.OutTradeNo,
                    Amount     = request.Amount.ToDecimal(),
                    RealName   = request.RealName,
                    BankCardNo = request.BankCardNo,
                    Mobile     = request.Mobile,
                    Remark     = request.Remark,
                    PayStatus  = PayStatus.APPLY.ToString(),
                    CreateTime = DateTime.Now
                };

                _fundOutOrderRepository.Add(fundoutOrder);
                var saveResult = _fundOutOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存代付订单数据失败", saveResult.FirstException, fundoutOrder);
                    return(new XResult <PayResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException("保存订单数据失败")));
                }

                var dic = new Dictionary <String, String>(6);
                dic["LoanJsonList"] = JsonUtil.SerializeObject(new FundOutLoanInfo()
                {
                    Amount           = request.Amount,
                    CardNumber       = CryptoHelper.RSAEncrypt(request.BankCardNo, KeyConfig.EPay95_FundOut_PublicKey).Value,
                    IdentificationNo = request.IDCardNo,
                    Mobile           = request.Mobile,
                    OrderNo          = request.OutTradeNo,
                    RealName         = request.RealName,
                    Type             = "0"
                }).Value;
                dic["PlatformMoneymoremore"] = GlobalConfig.X95epay_FundOut_Hehua_PlatformMoneymoremore;
                dic["BatchNo"]   = request.OutTradeNo;
                dic["Remark"]    = request.Remark;
                dic["NotifyURL"] = ApiConfig.EPay95_FundOut_Pay_NotifyUrl;

                var signResult = EPay95Util.MakeSign(dic);
                if (signResult.IsNullOrWhiteSpace())
                {
                    return(new XResult <PayResponse>(null, ErrorCode.SIGN_FAILED));
                }

                dic["LoanJsonList"] = HttpUtility.UrlEncode(dic["LoanJsonList"]);
                dic["SignInfo"]     = signResult;

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, $"开始调用{ApiConfig.EPay95_FundOut_Pay_RequestUrl}", new Object[] { ApiConfig.EPay95_FundOut_Pay_RequestUrl, dic });

                //记录请求开始时间
                fundoutOrder.ApplyTime = DateTime.Now;
                var respMsgResult = client.PostForm(ApiConfig.EPay95_FundOut_Pay_RequestUrl, dic);

                _logger.Trace(TraceType.BLL.ToString(), (respMsgResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.ACTION, $"结束调用{ApiConfig.EPay95_FundOut_Pay_RequestUrl}");

                if (!respMsgResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "代付失败", respMsgResult.FirstException, dic);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RequestException(respMsgResult.ErrorMessage)));
                }

                String respContent = null;
                try
                {
                    respContent = respMsgResult.Value.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.END, $"调用{ApiConfig.EPay95_FundOut_Pay_RequestUrl}返回结果", respContent);
                }
                catch (Exception ex)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "读取代付返回的消息内容出现异常", ex, dic);
                    return(new XResult <PayResponse>(null, ErrorCode.RESPONSE_READ_FAILED, ex));
                }

                if (respContent.IsNullOrWhiteSpace())
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "双乾未返回任何数据", null, dic);
                    return(new XResult <PayResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                EPay95PayReturnResult respResult = JsonUtil.DeserializeObject <EPay95PayReturnResult>(respContent).Value;
                if (respResult == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "respResult", "无法将代付结果反序列化为EPay95PayReturnResult对象", null, respContent);
                    return(new XResult <PayResponse>(null, ErrorCode.DESERIALIZE_FAILED));
                }

                //记录请求结束时间
                fundoutOrder.EndTime = DateTime.Now;

                switch (respResult.ResultCode)
                {
                case "88":
                case "90":
                case "15":
                    //修改支付状态为正在处理中
                    fundoutOrder.PayStatus = PayStatus.PROCESSING.ToString();
                    break;

                default:
                    //修改支付状态为正在处理中
                    fundoutOrder.PayStatus = PayStatus.FAILURE.ToString();
                    break;
                }

                fundoutOrder.UpdateTime = DateTime.Now;
                _fundOutOrderRepository.Update(fundoutOrder);
                var updateResult = _fundOutOrderRepository.SaveChanges();
                if (!updateResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "更新支付状态失败", updateResult.FirstException, fundoutOrder);
                }

                var payResp = new PayResponse()
                {
                    Status = fundoutOrder.PayStatus,
                    Msg    = respResult.Message.HasValue() ? respResult.Message : PayStatus.PROCESSING.GetDescription()
                };

                if (respResult.LoanJsonList != null)
                {
                    payResp.Amount     = respResult.LoanJsonList.Amount;
                    payResp.BankCardNo = respResult.LoanJsonList.CardNumber;
                    payResp.OutTradeNo = respResult.LoanJsonList.OrderNo;
                }

                return(new XResult <PayResponse>(payResp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Example #4
0
        public XResult <YeePayAgreePayApplyResponse> Apply(YeePayAgreePayApplyRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.{nameof(Apply)}(...)";

            var requestHash = $"{nameof(Apply)}:{request.PayerId}.{request.BankCardNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                DateTime applyTime = DateTime.Now;

                // 如果未保存绑卡信息则添加到数据库
                var existedBankCard = _bankCardInfoRepository.QueryProvider.FirstOrDefault(x => x.IDCardNo == request.IDCardNo && x.BankCardNo == request.BankCardNo);
                if (existedBankCard == null)
                {
                    // 先将绑卡的银行卡数据入库
                    var bankCardInfo = new AgreePayBankCardInfo()
                    {
                        Id         = IDGenerator.GenerateID(),
                        AppId      = request.AppId,
                        RealName   = request.RealName,
                        IDCardNo   = request.IDCardNo,
                        BankCardNo = request.BankCardNo,
                        Mobile     = request.Mobile,
                        BankCode   = request.BankCode,
                        UpdateTime = applyTime
                    };

                    _bankCardInfoRepository.Add(bankCardInfo);
                    var saveResult = _bankCardInfoRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_bankCardInfoRepository)}.SaveChanges()", "快钱协议支付:保存绑卡信息失败", saveResult.FirstException, bankCardInfo);
                        return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                    }
                }

                var execResult = YeePayAgreePayUtil.Execute <RawYeePayApplyBindCardRequest, RawYeePayApplyBindCardResponse>("/rest/v1.0/paperorder/unified/auth/request", new RawYeePayApplyBindCardRequest()
                {
                    merchantno   = GlobalConfig.YeePay_AgreePay_MerchantNo,
                    requestno    = request.OutTradeNo,
                    identityid   = request.PayerId,
                    identitytype = "USER_ID",
                    idcardno     = request.IDCardNo,
                    cardno       = request.BankCardNo,
                    idcardtype   = "ID",
                    username     = request.RealName,
                    phone        = request.Mobile,
                    issms        = "true",
                    requesttime  = applyTime.ToString("yyyy/MM/dd HH:mm:ss"),
                    authtype     = "COMMON_FOUR"
                });

                String traceMethod = $"{nameof(YeePayAgreePayUtil)}.{nameof(YeePayAgreePayUtil.Execute)}(...)";

                if (!execResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "协议支付失败", execResult.FirstException, execResult);
                    return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RequestException(execResult.ErrorMessage)));
                }

                var respResult = execResult.Value;
                if (respResult.status != "TO_VALIDATE")
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "respResult", $"{respResult.errorcode}:{respResult.errormsg}", null, respResult);

                    _bankCardInfoRepository.Remove(existedBankCard);
                    var removeResult = _bankCardInfoRepository.SaveChanges();
                    if (!removeResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "removeResult", "无法删除申请绑卡失败的记录", removeResult.FirstException, existedBankCard);
                    }
                    else
                    {
                        _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, "removeResult", LogPhase.ACTION, "成功删除申请绑卡失败的记录", existedBankCard);
                    }

                    return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respResult.errormsg)));
                }

                var resp = new YeePayAgreePayApplyResponse()
                {
                    OutTradeNo = respResult.requestno,
                    ApplyTime  = applyTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    PayerId    = request.PayerId,
                    Status     = CommonStatus.SUCCESS.ToString(),
                    Msg        = $"申请{CommonStatus.SUCCESS.GetDescription()}"
                };

                return(new XResult <YeePayAgreePayApplyResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
        public XResult <CPIEntrustPayPaymentResponse> Pay(CPIEntrustPayPaymentRequest request)
        {
            if (request == null)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            if (request.Amount < GlobalConfig.X99bill_EntrustPay_PayMinAmount)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"支付金额至少为{GlobalConfig.X99bill_EntrustPay_PayMinAmount.ToString()}元")));
            }

            var parseSharingInfoResult = JsonUtil.DeserializeObject <SharingInfo>(request.SharingInfo);

            if (!parseSharingInfoResult.Success)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DESERIALIZE_FAILED, new ArgumentException("解析SharingInfo参数失败")));
            }

            var sharingInfo = parseSharingInfoResult.Value;

            String service = $"{this.GetType().FullName}.{nameof(Pay)}(...)";

            var requestHash = $"{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existsOutTradeNo = _payOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //生成全局唯一的ID号
                String tradeNo = IDGenerator.GenerateID().ToString();

                // 1. 添加交易记录
                var newOrder = new PayOrder()
                {
                    Id             = IDGenerator.GenerateID(),
                    AppId          = request.AppId,
                    OutTradeNo     = request.OutTradeNo,
                    TradeNo        = tradeNo,
                    PayAmount      = request.Amount,
                    BankCardNo     = request.BankCardNo,
                    PayerId        = request.PayerId,
                    PayChannelCode = GlobalConfig.X99BILL_PAYCHANNEL_CODE,
                    PayStatus      = PayStatus.APPLY.ToString(),
                    PayType        = PayType.ENTRUSTPAY.ToString(),
                    CreateTime     = DateTime.Now
                };

                _payOrderRepository.Add(newOrder);
                var saveResult = _payOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "支付单保存失败", saveResult.FirstException, newOrder);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                //添加分账记录
                var allotAmountOrder = new AllotAmountOrder()
                {
                    Id          = IDGenerator.GenerateID(),
                    AppId       = request.AppId,
                    PayeeId     = request.PayerId,
                    TradeNo     = tradeNo,
                    OutTradeNo  = request.OutTradeNo,
                    TotalAmount = request.Amount,
                    FeePayerId  = sharingInfo.FeePayerId,
                    SharingType = sharingInfo.SharingType == "0" ? AllotAmountType.Pay.ToString() : AllotAmountType.Refund.ToString(),
                    SharingInfo = sharingInfo.SharingData,
                    ApplyTime   = DateTime.Now,
                    Status      = AllotAmountOrderStatus.APPLY.ToString()
                };

                _allotAmountOrderRepository.Add(allotAmountOrder);
                saveResult = _allotAmountOrderRepository.SaveChanges();

                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_allotAmountOrderRepository)}.SaveChanges()", "分账数据保存失败", saveResult.FirstException, allotAmountOrder);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                //构造分账参数
                ExtDate sharingExtDate = null;
                if (sharingInfo.SharingType == "0")
                {
                    //构造消费分账数据
                    var sharingDic = new Dictionary <String, String>(5);
                    sharingDic["sharingFlag"] = "1";
                    sharingDic["feeMode"]     = sharingInfo.FeeMode;
                    sharingDic["feePayer"]    = sharingInfo.FeePayerId;
                    sharingDic["sharingData"] = sharingInfo.SharingData;

                    sharingExtDate = new ExtDate()
                    {
                        Key   = "sharingInfo",
                        Value = JsonUtil.SerializeObject(sharingDic).Value
                    };
                }
                else if (sharingInfo.SharingType == "1")
                {
                    //构造退款分账数据
                    var sharingDic = new Dictionary <String, String>(5);
                    sharingDic["sharingFlag"] = "1";
                    sharingDic["feeMode"]     = sharingInfo.FeeMode;
                    sharingDic["feePayer"]    = sharingInfo.FeePayerId;
                    sharingDic["sharingData"] = sharingInfo.SharingData;

                    sharingExtDate = new ExtDate()
                    {
                        Key   = "refundSharingInfo",
                        Value = JsonUtil.SerializeObject(sharingDic).Value
                    };
                }

                var tradeTime = DateTime.Now;

                var payRequest = new EntrustPayRequest()
                {
                    Version = "1.0",
                    EntrustPayRequestContent = new EntrustPayRequestContent()
                    {
                        Amount            = request.Amount.ToString(),
                        CardHolderId      = request.IDCardNo,
                        CardHolderName    = request.RealName,
                        CardNo            = request.BankCardNo,
                        EntryTime         = tradeTime.ToString("yyyyMMddHHmmss"),
                        ExternalRefNumber = request.OutTradeNo,
                        IdType            = "0",
                        InteractiveStatus = "TR1",
                        TxnType           = "PUR",
                        ExtMap            = new ExtMap()
                        {
                            ExtDates = new ExtDate[] {
                                new ExtDate()
                                {
                                    Key = "phone", Value = request.Mobile
                                },
                                sharingExtDate
                            }
                        }
                    }
                };

                String callMethod = $"{_api.GetType().FullName}.{nameof(_api.EntrustPay)}(...)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, callMethod, LogPhase.BEGIN, $"开始调用{callMethod}", new Object[] { ApiConfig.Bill99_EntrustPay_Pay_RequestUrl, payRequest });

                var result = _api.EntrustPay(ApiConfig.Bill99_EntrustPay_Pay_RequestUrl, payRequest);

                _logger.Trace(TraceType.BLL.ToString(), (result.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, callMethod, LogPhase.END, $"完成调用{callMethod}", result.Value);

                if (!result.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, "支付失败", result.FirstException, payRequest);
                    UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, result.FirstException));
                }

                if (result.Value == null || result.Value.EntrustPayResponseContent == null)
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, LogPhase.ACTION, "快钱未返回任何数据");
                    UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respContent = result.Value.EntrustPayResponseContent;
                if (respContent.ResponseCode != "00")
                {
                    UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respContent.ResponseTextMessage)));
                }

                UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.SUCCESS);

                //判断是否有该付款人的绑卡信息,如果没有则创建
                var existesBankCardInfo = (from t0 in _agreePayBankCardInfoRepository.QueryProvider
                                           where t0.IDCardNo == request.IDCardNo && t0.BankCardNo == request.BankCardNo
                                           select t0).Count() > 0;
                if (!existesBankCardInfo)
                {
                    var bankcardInfo = new AgreePayBankCardInfo()
                    {
                        Id         = IDGenerator.GenerateID(),
                        AppId      = request.AppId,
                        RealName   = request.RealName,
                        BankCardNo = request.BankCardNo,
                        IDCardNo   = request.IDCardNo,
                        Mobile     = request.Mobile,
                        BankCode   = "-",
                        UpdateTime = DateTime.Now
                    };

                    _agreePayBankCardInfoRepository.Add(bankcardInfo);

                    saveResult = _agreePayBankCardInfoRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_agreePayBankCardInfoRepository)}.SaveChanges()", "保存付款人信息失败", saveResult.FirstException, bankcardInfo);
                    }
                }

                var resp = new CPIEntrustPayPaymentResponse()
                {
                    OutTradeNo = respContent.ExternalRefNumber,
                    TradeNo    = tradeNo,
                    PayTime    = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status     = PayStatus.SUCCESS.ToString(),
                    Msg        = PayStatus.SUCCESS.GetDescription()
                };

                //根据返回码计算对应的支付状态,并更新到数据库
                var payStatus = Bill99Util.GetAgreepayPayStatus(respContent.ResponseCode);
                var payOrder  = (from t0 in _payOrderRepository.QueryProvider
                                 where t0.TradeNo == tradeNo
                                 select t0).FirstOrDefault();

                //如果支付单存在,并且状态不是最终状态,才更新状态
                if (newOrder != null &&
                    newOrder.PayStatus != PayStatus.SUCCESS.ToString() &&
                    newOrder.PayStatus != PayStatus.FAILURE.ToString())
                {
                    newOrder.PayStatus  = payStatus.ToString();
                    newOrder.UpdateTime = DateTime.Now;
                    _payOrderRepository.Update(newOrder);
                    saveResult = _payOrderRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "更新支付结果失败", saveResult.FirstException, newOrder);
                    }
                }

                return(new XResult <CPIEntrustPayPaymentResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Example #6
0
        public XResult <YeePaySinglePayResponse> Pay(YeePaySinglePayRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service     = $"{this.GetType().FullName}.Pay(...)";
            var    requestHash = $"pay:{request.AppId}.{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existsOutTradeNo = _fundOutOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                var now   = DateTime.Now;
                var newId = IDGenerator.GenerateID();

                var fundoutOrder = new FundOutOrder()
                {
                    Id         = newId,
                    TradeNo    = newId.ToString(),
                    AppId      = request.AppId,
                    OutTradeNo = request.OutTradeNo,
                    Amount     = request.Amount.ToDecimal(),
                    RealName   = request.AccountName,
                    BankCardNo = request.BankCardNo,
                    Remark     = request.Remark,
                    PayStatus  = PayStatus.APPLY.ToString(),
                    CreateTime = DateTime.Now
                };

                _fundOutOrderRepository.Add(fundoutOrder);
                var saveResult = _fundOutOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存代付订单数据失败", saveResult.FirstException, fundoutOrder);
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException("保存代付订单数据失败")));
                }

                String traceMethod = $"{nameof(YeePayFundOutUtil)}.Execute(...)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, "开始调用易宝代付支付接口", request);

                //记录请求开始时间
                fundoutOrder.ApplyTime = DateTime.Now;

                var execResult = YeePayFundOutUtil.Execute <RawYeePaySinglePayRequest, RawYeePaySinglePayResult>("/rest/v1.0/balance/transfer_send", new RawYeePaySinglePayRequest()
                {
                    orderId        = request.OutTradeNo,
                    accountName    = request.AccountName,
                    accountNumber  = request.BankCardNo,
                    amount         = request.Amount,
                    bankCode       = request.BankCode,
                    batchNo        = fundoutOrder.TradeNo,
                    customerNumber = GlobalConfig.YeePay_FundOut_MerchantNo,
                    groupNumber    = GlobalConfig.YeePay_FundOut_MerchantNo,
                    feeType        = request.FeeType
                });

                //记录请求结束时间
                fundoutOrder.EndTime = DateTime.Now;

                _logger.Trace(TraceType.BLL.ToString(), (execResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.ACTION, "结束调用易宝代付支付接口");

                if (!execResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "代付失败", execResult.FirstException, execResult);
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RequestException(execResult.ErrorMessage)));
                }

                var respResult = execResult.Value;
                if (respResult.errorCode != "BAC001")
                {
                    fundoutOrder.PayStatus = PayStatus.FAILURE.ToString();
                    UpdateFundOutOrder(fundoutOrder);
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.FAILURE, new RemoteException(respResult.errorMsg.HasValue() ? respResult.errorMsg : "发送请求失败")));
                }

                fundoutOrder.PayStatus = PayStatus.PROCESSING.ToString();
                switch (respResult.transferStatusCode)
                {
                case "0028":
                    fundoutOrder.PayStatus = PayStatus.FAILURE.ToString();
                    break;
                }

                UpdateFundOutOrder(fundoutOrder);

                var payResp = new YeePaySinglePayResponse()
                {
                    BatchNo    = respResult.batchNo,
                    OutTradeNo = request.OutTradeNo,
                    Status     = fundoutOrder.PayStatus,
                    Msg        = GetPayStatusDescription(fundoutOrder.PayStatus)
                };

                return(new XResult <YeePaySinglePayResponse>(payResp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Example #7
0
        public XResult <CPIAgreePayApplyResponse> Apply(CPIAgreePayApplyRequest request)
        {
            if (request == null)
            {
                return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.Apply(...)";

            var requestHash = $"apply:{request.PayerId}.{request.BankCardNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                // 如果未保存绑卡信息则添加到数据库
                var existsBankCard = _bankCardInfoRepository.Exists(x => x.BankCardNo == request.BankCardNo);
                AgreePayBankCardInfo bankCardInfo = null;
                if (!existsBankCard)
                {
                    // 先将绑卡的银行卡数据入库
                    bankCardInfo = new AgreePayBankCardInfo()
                    {
                        Id         = IDGenerator.GenerateID(),
                        AppId      = request.AppId,
                        RealName   = request.RealName,
                        IDCardNo   = request.IDCardNo,
                        BankCardNo = request.BankCardNo,
                        Mobile     = request.Mobile,
                        BankCode   = request.BankCode,
                        UpdateTime = DateTime.Now
                    };

                    _bankCardInfoRepository.Add(bankCardInfo);
                    var saveResult = _bankCardInfoRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_bankCardInfoRepository)}.SaveChanges()", "快钱协议支付:保存绑卡信息失败", saveResult.FirstException, bankCardInfo);
                        return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                    }
                }

                var tradeTime = DateTime.Now;

                // 入库成功之后才开始调第三方申请接口
                var applyRequest = new AgreementApplyRequest()
                {
                    Version        = "1.0",
                    IndAuthContent = new IndAuthRequestContent()
                    {
                        BindType          = "0",
                        CustomerId        = request.PayerId,
                        ExternalRefNumber = request.OutTradeNo,
                        Pan            = request.BankCardNo,
                        CardHolderName = request.RealName,
                        CardHolderId   = request.IDCardNo,
                        PhoneNO        = request.Mobile
                    }
                };

                String callMethod = $"{nameof(_api)}.AgreementApply(...)";
                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, callMethod, LogPhase.BEGIN, $"开始调用{callMethod}", new Object[] { ApiConfig.Bill99_AgreePay_ApplyBindCard_RequestUrl, applyRequest });

                var result = _api.AgreementApply(ApiConfig.Bill99_AgreePay_ApplyBindCard_RequestUrl, applyRequest);

                _logger.Trace(TraceType.BLL.ToString(), (result.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, callMethod, LogPhase.END, $"完成调用{callMethod}", result.Value);

                if (!result.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, "申请绑卡失败", result.FirstException, applyRequest);
                    DeleteFailedBankCardInfo(service, callMethod, bankCardInfo);
                    return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, result.FirstException));
                }

                if (result.Value == null)
                {
                    DeleteFailedBankCardInfo(service, callMethod, bankCardInfo);
                    return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                if (result.Value.IndAuthContent == null)
                {
                    DeleteFailedBankCardInfo(service, callMethod, bankCardInfo);
                    return(result.Value.ErrorMsgContent != null
                        ? new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(result.Value.ErrorMsgContent.ErrorMessage))
                        : new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respContent = result.Value.IndAuthContent;
                if (respContent.ResponseCode != "00")
                {
                    DeleteFailedBankCardInfo(service, callMethod, bankCardInfo);
                    return(new XResult <CPIAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respContent.ResponseTextMessage)));
                }

                var resp = new CPIAgreePayApplyResponse()
                {
                    PayerId    = respContent.CustomerId,
                    OutTradeNo = respContent.ExternalRefNumber,
                    ApplyToken = respContent.Token,
                    ApplyTime  = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status     = CommonStatus.SUCCESS.ToString(),
                    Msg        = CommonStatus.SUCCESS.GetDescription()
                };

                return(new XResult <CPIAgreePayApplyResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Example #8
0
        public XResult <WithdrawResponse> Withdraw(WithdrawRequest request)
        {
            if (request == null)
            {
                return(new XResult <WithdrawResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.Withdraw(...)";

            if (!request.IsValid)
            {
                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(request)}.IsValid", LogPhase.ACTION, $"请求参数验证失败:{request.ErrorMessage}", request);
                return(new XResult <WithdrawResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            if (request.Amount < GlobalConfig.X99bill_YZT_WithdrawMinAmount)
            {
                return(new XResult <WithdrawResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"提现金额至少为{GlobalConfig.X99bill_YZT_WithdrawMinAmount.ToString()}元")));
            }

            var requestHash = $"withdraw:{request.PayeeId}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <WithdrawResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <WithdrawResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existedOrder = _allotAmountWithdrawOrderRepository.QueryProvider.FirstOrDefault(x => x.OutTradeNo == request.OutTradeNo);
                if (existedOrder == null)
                {
                    var newId = IDGenerator.GenerateID();
                    existedOrder = new AllotAmountWithdrawOrder()
                    {
                        Id           = newId,
                        AppId        = request.AppId,
                        TradeNo      = newId.ToString(),
                        PayeeId      = request.PayeeId,
                        OutTradeNo   = request.OutTradeNo,
                        Amount       = request.Amount,
                        SettlePeriod = request.SettlePeriod,
                        CustomerFee  = request.CustomerFee,
                        MerchantFee  = request.MerchantFee,
                        Status       = WithdrawOrderStatus.APPLY.ToString(),
                        ApplyTime    = DateTime.Now
                    };

                    _allotAmountWithdrawOrderRepository.Add(existedOrder);

                    var saveResult = _allotAmountWithdrawOrderRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_allotAmountWithdrawOrderRepository)}.SaveChanges()", "保存分账提现记录失败", saveResult.FirstException, existedOrder);
                        return(new XResult <WithdrawResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                    }
                }

                if (existedOrder.Status == WithdrawOrderStatus.SUCCESS.ToString() ||
                    existedOrder.Status == WithdrawOrderStatus.FAILURE.ToString())
                {
                    return(new XResult <WithdrawResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                String traceMethod = $"Bill99Util.Execute(/account/withdraw)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN);

                var execResult = Bill99UtilYZT.Execute <RawWithdrawRequest, RawWithdrawResponse>("/account/withdraw", new RawWithdrawRequest()
                {
                    uId         = request.PayeeId,
                    outTradeNo  = request.OutTradeNo,
                    amount      = request.Amount,
                    customerFee = request.CustomerFee,
                    merchantFee = request.MerchantFee
                });

                _logger.Trace(TraceType.BLL.ToString(), (execResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.END);

                if (!execResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "申请分账提现失败", execResult.FirstException, request);
                    return(new XResult <WithdrawResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, execResult.FirstException));
                }

                var resp = execResult.Value;

                if (resp == null)
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(execResult)}.Value", LogPhase.ACTION, "快钱未返回任何数据");
                    return(new XResult <WithdrawResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                if (resp.ResponseCode != "0000")
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(resp)}.ResponseCode", $"申请分账提现失败:{resp.ResponseCode}:{resp.ResponseMessage}");
                    return(new XResult <WithdrawResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException($"{resp.ResponseCode}:{resp.ResponseMessage}")));
                }

                Boolean statusHasChanged = false;

                switch (resp.status)
                {
                case "1":
                    existedOrder.Status       = WithdrawOrderStatus.SUCCESS.ToString();
                    existedOrder.CompleteTime = DateTime.Now;
                    statusHasChanged          = true;
                    break;

                case "2":
                    existedOrder.Status       = WithdrawOrderStatus.FAILURE.ToString();
                    existedOrder.CompleteTime = DateTime.Now;
                    statusHasChanged          = true;
                    break;

                case "3":
                    existedOrder.Status = WithdrawOrderStatus.PROCESSING.ToString();
                    statusHasChanged    = true;
                    break;
                }

                if (statusHasChanged)
                {
                    _allotAmountWithdrawOrderRepository.Update(existedOrder);
                    var updateResult = _allotAmountWithdrawOrderRepository.SaveChanges();
                    if (!updateResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_allotAmountWithdrawOrderRepository)}.SaveChanges()", "更新申请提交结果失败", updateResult.FirstException, existedOrder);
                    }
                }

                return(new XResult <WithdrawResponse>(new WithdrawResponse()
                {
                    Status = existedOrder.Status,
                    Msg = GetWithdrawOrderStatusMsg(existedOrder.Status)
                }));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
        //private readonly IWithdrawService _withdrawService = null;

        public XResult <AllotAmountWithdrawApplyResponse> Apply(AllotAmountWithdrawApplyRequest request)
        {
            if (request == null)
            {
                return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.Apply(...)";

            if (!request.IsValid)
            {
                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(request)}.IsValid", LogPhase.ACTION, $"快钱盈帐通:{request.ErrorMessage}", request);
                return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            if (request.Amount < GlobalConfig.X99bill_YZT_WithdrawMinAmount)
            {
                return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"提现金额至少为{GlobalConfig.X99bill_YZT_WithdrawMinAmount.ToString()}元")));
            }

            var requestHash = $"withdraw:{request.PayeeId}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                //检查是否已开户
                if (!_personalSubAccountRepository.Exists(x => x.AppId == request.AppId && x.UID == request.PayeeId))
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "__CheckPersonalAccountRegisterInfo", LogPhase.ACTION, "该用户尚未开户", request);
                    return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.UN_REGISTERED));
                }

                //检查是否已绑卡
                if (!_withdrawBankCardBindInfoRepository.Exists(x => x.AppId == request.AppId && x.PayeeId == request.PayeeId))
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "__CheckBankCardBindInfo", LogPhase.ACTION, "该用户尚未绑卡", request);
                    return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.NO_BANKCARD_BOUND));
                }

                var existsOrder = _allotAmountWithdrawOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOrder)
                {
                    return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                var newId            = IDGenerator.GenerateID();
                var newWithdrawOrder = new AllotAmountWithdrawOrder()
                {
                    Id           = newId,
                    AppId        = request.AppId,
                    TradeNo      = newId.ToString(),
                    PayeeId      = request.PayeeId,
                    OutTradeNo   = request.OutTradeNo,
                    Amount       = request.Amount,
                    CustomerFee  = request.CustomerFee,
                    MerchantFee  = request.MerchantFee,
                    SettlePeriod = request.SettlePeriod,
                    Status       = WithdrawOrderStatus.APPLY.ToString(),
                    ApplyTime    = DateTime.Now
                };

                _allotAmountWithdrawOrderRepository.Add(newWithdrawOrder);

                var saveResult = _allotAmountWithdrawOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_allotAmountWithdrawOrderRepository)}.SaveChanges()", "保存分账提现记录失败", saveResult.FirstException, newWithdrawOrder);
                    return(new XResult <AllotAmountWithdrawApplyResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                var resp = new AllotAmountWithdrawApplyResponse()
                {
                    PayeeId    = newWithdrawOrder.PayeeId,
                    OutTradeNo = newWithdrawOrder.OutTradeNo,
                    Amount     = newWithdrawOrder.Amount,
                    Status     = CommonStatus.SUCCESS.ToString(),
                    Msg        = $"申请{CommonStatus.SUCCESS.GetDescription()}"
                };

                return(new XResult <AllotAmountWithdrawApplyResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }