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); } }
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); } }
public void AddPayOrder(PayOrderDTO payOrder) { var pay = payOrder.MappingPayOrder(); payOrderRepository.Add(pay); }