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)); }
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); } }