Пример #1
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);
            }
        }
Пример #2
0
        public XResult <YeePaySinglePayResultQueryResponse> QueryStatus(YeePaySinglePayResultQueryRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePaySinglePayResultQueryResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

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

            String service     = $"{this.GetType().FullName}.QueryStatus(...)";
            var    requestHash = $"QueryStatus:{request.OutTradeNo}{request.PageIndex}{request.PageSize}".GetHashCode();

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

            try
            {
                var q = _fundOutOrderRepository.QueryProvider;

                if (request.OutTradeNo.HasValue())
                {
                    if (request.OutTradeNo.IndexOf(",") > 0)
                    {
                        var outTradeNos = request.OutTradeNo.Split(new Char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        q = from t0 in q
                            where outTradeNos.Contains(t0.OutTradeNo)
                            select t0;
                    }
                    else
                    {
                        q = from t0 in q
                            where t0.OutTradeNo == request.OutTradeNo
                            select t0;
                    }
                }

                if (request.From.HasValue() && DateTime.TryParse(request.From, out DateTime fromDate))
                {
                    fromDate = fromDate.Date;
                    q        = from t0 in q
                               where t0.CreateTime >= fromDate
                               select t0;
                }

                if (request.To.HasValue() && DateTime.TryParse(request.To, out DateTime toDate))
                {
                    toDate = toDate.Date.AddDays(1);
                    q      = from t0 in q
                             where t0.CreateTime < toDate
                             select t0;
                }

                var pagedList = new PagedList <FundOutOrder>(q.OrderByDescending(x => x.CreateTime), request.PageIndex.ToInt32(), request.PageSize.ToInt32());
                if (pagedList.Exception != null)
                {
                    return(new XResult <YeePaySinglePayResultQueryResponse>(null, ErrorCode.DB_QUERY_FAILED, pagedList.Exception));
                }

                if (String.Compare(request.QueryMode, "PULL", true) == 0)
                {
                    if (_lockProvider.Lock(requestHash))
                    {
                        var needPullOrders = pagedList.Where(x => x.PayStatus != PayStatus.SUCCESS.ToString() && x.PayStatus != PayStatus.FAILURE.ToString());
                        if (needPullOrders != null && needPullOrders.Count() > 0)
                        {
                            Boolean statusChanged = false;
                            foreach (var pullOrder in needPullOrders)
                            {
                                var pullResult = YeePayFundOutUtil.Execute <RawYeePaySinglePayResultQueryStatusRequest, RawYeePaySinglePayResultQueryStatusResult>("/rest/v1.0/balance/transfer_query", new RawYeePaySinglePayResultQueryStatusRequest()
                                {
                                    batchNo        = pullOrder.TradeNo,
                                    customerNumber = GlobalConfig.YeePay_FundOut_MerchantNo,
                                    orderId        = pullOrder.OutTradeNo,
                                    pageNo         = request.PageIndex,
                                    pageSize       = request.PageSize,
                                    product        = String.Empty
                                });

                                if (pullResult.Success && pullResult.Value != null)
                                {
                                    var orderResult = pullResult.Value;
                                    if (orderResult.errorCode == "BAC000048")
                                    {
                                        pullOrder.PayStatus  = PayStatus.FAILURE.ToString();
                                        pullOrder.UpdateTime = DateTime.Now;
                                        statusChanged        = true;
                                    }
                                    else if (orderResult.errorCode == "BAC001" && orderResult.list != null && orderResult.list.Count() == 1)
                                    {
                                        var orderResultDetail = orderResult.list.FirstOrDefault();
                                        if (orderResultDetail.transferStatusCode == "0028" ||
                                            orderResultDetail.transferStatusCode == "0027")
                                        {
                                            pullOrder.PayStatus  = PayStatus.FAILURE.ToString();
                                            pullOrder.UpdateTime = DateTime.Now;
                                            statusChanged        = true;
                                        }
                                        else if (orderResultDetail.transferStatusCode == "0026")
                                        {
                                            switch (orderResultDetail.bankTrxStatusCode)
                                            {
                                            case "S":
                                                pullOrder.Fee        = orderResultDetail.fee.ToDecimal();
                                                pullOrder.FeeAction  = orderResultDetail.feeType;
                                                pullOrder.Remark     = orderResultDetail.leaveWord;
                                                pullOrder.PayStatus  = PayStatus.SUCCESS.ToString();
                                                pullOrder.UpdateTime = DateTime.Now;
                                                statusChanged        = true;
                                                break;

                                            case "F":
                                                pullOrder.PayStatus  = PayStatus.FAILURE.ToString();
                                                pullOrder.UpdateTime = DateTime.Now;
                                                statusChanged        = true;
                                                break;
                                            }
                                        }
                                    }
                                }

                                if (statusChanged)
                                {
                                    _fundOutOrderRepository.Update(pullOrder);
                                    var updateResult = _fundOutOrderRepository.SaveChanges();
                                    if (!updateResult.Success)
                                    {
                                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存代付订单数据失败", updateResult.FirstException, new Object[] { pullOrder, pullResult.Value });
                                    }
                                }
                            }
                        }
                    }
                }

                var pageInfo = pagedList.PageInfo;

                var resp = new YeePaySinglePayResultQueryResponse()
                {
                    PageIndex  = pageInfo.PageIndex,
                    PageSize   = pageInfo.PageSize,
                    TotalCount = pageInfo.TotalCount,
                    Orders     = pagedList.Select(x => new YeePaySinglePayStatusResult()
                    {
                        OutTradeNo = x.OutTradeNo,
                        BankCardNo = x.BankCardNo,
                        Amount     = x.Amount,
                        Fee        = x.Fee,
                        CreateTime = x.CreateTime,
                        Status     = x.PayStatus,
                        Msg        = GetPayStatusDescription(x.PayStatus)
                    })
                };

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