예제 #1
0
        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);
            }
        }
예제 #2
0
        public XResult <YeePayAgreePayPaymentResponse> Pay(YeePayAgreePayPaymentRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

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

            String terminalPattern = $"^({Resources.YeePayAgreePayTerminalNo})|({Resources.YeePayEntrustPayTerminalNo})$";

            if (!Regex.IsMatch(request.TerminalNo, terminalPattern))
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException("TerminalNo字段传值错误")));
            }

            if (request.Amount < GlobalConfig.YeePay_AgreePay_PayMinAmount)
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"支付总金额必须大于{GlobalConfig.YeePay_AgreePay_PayMinAmount.ToString()}")));
            }

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

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

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

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

                // 保证外部交易号不重复
                var existsOutTradeNo = _payOrderRepository.Exists(x => x.AppId == request.AppId && x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //生成全局唯一的ID号
                Int64  newId     = IDGenerator.GenerateID();
                String tradeNo   = newId.ToString();
                var    tradeTime = DateTime.Now;

                // 添加支付单记录
                var newOrder = new PayOrder()
                {
                    Id             = newId,
                    AppId          = request.AppId,
                    PayerId        = request.PayerId,
                    OutTradeNo     = request.OutTradeNo,
                    TradeNo        = tradeNo,
                    PayAmount      = request.Amount,
                    BankCardNo     = request.BankCardNo,
                    PayChannelCode = GlobalConfig.YEEPAY_PAYCHANNEL_CODE,
                    PayStatus      = PayStatus.APPLY.ToString(),
                    PayType        = request.TerminalNo == Resources.YeePayAgreePayTerminalNo ? PayType.AGREEMENTPAY.ToString() : PayType.ENTRUSTPAY.ToString(),
                    CreateTime     = tradeTime
                };

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

                var result = YeePayAgreePayUtil.Execute <RawYeePayAgreePayPaymentRequest, RawYeePayAgreePayPaymentResponse>("/rest/v1.0/paperorder/unified/pay", new RawYeePayAgreePayPaymentRequest()
                {
                    merchantno   = GlobalConfig.YeePay_AgreePay_MerchantNo,
                    requestno    = request.OutTradeNo,
                    issms        = "false",
                    identityid   = request.PayerId,
                    identitytype = "USER_ID",
                    cardtop      = request.BankCardNo.Substring(0, 6),
                    cardlast     = request.BankCardNo.Substring(request.BankCardNo.Length - 4, 4),
                    amount       = request.Amount.ToString(),
                    productname  = "消费支付",
                    requesttime  = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    terminalno   = request.TerminalNo
                });

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

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

                if (result.Value == null)
                {
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respResult = result.Value;

                //如果易宝返回的不是PROCESSING则表示处理失败
                if (respResult.status != nameof(PayStatus.PROCESSING))
                {
                    newOrder.PayStatus  = PayStatus.FAILURE.ToString();
                    newOrder.UpdateTime = DateTime.Now;
                    UpdatePayOrder(service, newOrder);
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.FAILURE, new RemoteException($"{respResult.errorcode}:{respResult.errormsg}")));
                }

                //如果易宝返回PROCESSING表示已处理
                //并且要将易宝返回的易宝内部交易号更新到数据库
                //这个TradeNo以后可以作为退款接口的原交易号
                newOrder.PayStatus  = PayStatus.PROCESSING.ToString();
                newOrder.TradeNo    = respResult.yborderid;
                newOrder.UpdateTime = DateTime.Now;
                UpdatePayOrder(service, newOrder);

                var resp = new YeePayAgreePayPaymentResponse()
                {
                    OutTradeNo    = respResult.requestno,
                    YeePayTradeNo = respResult.yborderid,
                    ApplyTime     = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status        = PayStatus.PROCESSING.ToString(),
                    Msg           = PayStatus.PROCESSING.GetDescription()
                };

                return(new XResult <YeePayAgreePayPaymentResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
예제 #3
0
        public void AddPayOrder(PayOrderDTO payOrder)
        {
            var pay = payOrder.MappingPayOrder();

            payOrderRepository.Add(pay);
        }