コード例 #1
0
        private XResult <YeePayAgreePayPaymentRequest> BuildCPIAgreePayPaymentRequest(CommonPayRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayPaymentRequest>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

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

            var queryResult = _bindInfoService.GetBankCardBindDetails(request.PayerId, request.BankCardNo, GlobalConfig.YEEPAY_PAYCHANNEL_CODE);

            if (!queryResult.Success || queryResult.Value == null || queryResult.Value.Count() == 0)
            {
                _logger.Error(TraceType.ROUTE.ToString(), CallResultStatus.ERROR.ToString(), $"{nameof(BuildCPIAgreePayPaymentRequest)}(...)", "构造协议支付请求参数", "未查询到该用户的绑卡信息", queryResult.FirstException, new
                {
                    request.PayerId,
                    request.BankCardNo,
                    PayChannelCode = GlobalConfig.YEEPAY_PAYCHANNEL_CODE
                });
                return(new XResult <YeePayAgreePayPaymentRequest>(null, ErrorCode.NO_BANKCARD_BOUND, new DbQueryException("未查询到该用户的绑卡信息")));
            }

            // 默认取第一条绑卡信息
            var boundInfo = queryResult.Value.FirstOrDefault();

            var result = new YeePayAgreePayPaymentRequest()
            {
                PayerId    = request.PayerId,
                Amount     = request.Amount,
                OutTradeNo = request.OutTradeNo,
                BankCardNo = boundInfo.BankCardNo,
                TerminalNo = request.TerminalNo
            };

            return(new XResult <YeePayAgreePayPaymentRequest>(result));
        }
コード例 #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);
            }
        }