private XResult <CPIAgreePayPaymentRequest> BuildCPIAgreePayPaymentRequest(CommonPayRequest request) { if (request == null) { return(new XResult <CPIAgreePayPaymentRequest>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request)))); } if (!request.IsValid) { return(new XResult <CPIAgreePayPaymentRequest>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage))); } var queryResult = _bindInfoService.GetBankCardBindDetails(request.PayerId, request.BankCardNo, GlobalConfig.X99BILL_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.X99BILL_PAYCHANNEL_CODE }); return(new XResult <CPIAgreePayPaymentRequest>(null, ErrorCode.NO_BANKCARD_BOUND, new DbQueryException("未查询到该用户的绑卡信息"))); } // 默认取第一条绑卡信息 var boundInfo = queryResult.Value.FirstOrDefault(); var result = new CPIAgreePayPaymentRequest() { PayerId = request.PayerId, Amount = request.Amount, OutTradeNo = request.OutTradeNo, BankCardNo = boundInfo.BankCardNo, PayToken = boundInfo.PayToken, Mobile = boundInfo.Mobile, SharingInfo = request.SharingInfo }; return(new XResult <CPIAgreePayPaymentRequest>(result)); }
public XResult <CPIAgreePayPaymentResponse> Pay(CPIAgreePayPaymentRequest request) { if (request == null) { return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request)))); } if (!request.IsValid) { return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage))); } if (request.Amount < GlobalConfig.X99bill_AgreePay_PayMinAmount) { return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"支付总金额必须大于{GlobalConfig.X99bill_AgreePay_PayMinAmount.ToString()}"))); } var parseSharingInfoResult = JsonUtil.DeserializeObject <SharingInfo>(request.SharingInfo); if (!parseSharingInfoResult.Success) { return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.DESERIALIZE_FAILED, new ArgumentException("解析SharingInfo参数失败"))); } var sharingInfo = parseSharingInfoResult.Value; String service = $"{this.GetType().FullName}.Pay(...)"; var requestHash = $"pay:{request.OutTradeNo}".GetHashCode(); if (_lockProvider.Exists(requestHash)) { return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT)); } try { if (!_lockProvider.Lock(requestHash)) { return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT)); } // 保证外部交易号不重复 var existsOutTradeNo = _payOrderRepository.Exists(x => x.AppId == request.AppId && x.OutTradeNo == request.OutTradeNo); if (existsOutTradeNo) { return(new XResult <CPIAgreePayPaymentResponse>(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.X99BILL_PAYCHANNEL_CODE, PayStatus = PayStatus.APPLY.ToString(), PayType = PayType.AGREEMENTPAY.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 <CPIAgreePayPaymentResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException)); } //添加分账记录 var allotAmountOrder = new AllotAmountOrder() { Id = newId, 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 = tradeTime, Status = AllotAmountOrderStatus.APPLY.ToString() }; _allotAmountOrderRepository.Add(allotAmountOrder); saveResult = _allotAmountOrderRepository.SaveChanges(); if (!saveResult.Success) { _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_allotAmountOrderRepository)}.SaveChanges()", "分账数据保存失败", saveResult.FirstException, allotAmountOrder); return(new XResult <CPIAgreePayPaymentResponse>(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 payRequest = new AgreementPayRequest() { Version = "1.0", TxnMsgContent = new TxnMsgRequestContent() { Amount = request.Amount.ToString(), CustomerId = request.PayerId, EntryTime = tradeTime.ToString("yyyyMMddHHmmss"), ExternalRefNumber = request.OutTradeNo, InteractiveStatus = "TR1", NotifyUrl = request.NotifyUrl, PayToken = request.PayToken, SpFlag = "QPay02", TxnType = "PUR", ExtMap = new ExtMap() { ExtDates = new ExtDate[] { new ExtDate() { Key = "phone", Value = request.Mobile }, sharingExtDate } } } }; String callMethod = $"{_api.GetType().FullName}.AgreementPay(...)"; _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, callMethod, LogPhase.BEGIN, $"开始调用{callMethod}", new Object[] { ApiConfig.Bill99_AgreePay_Pay_RequestUrl, payRequest }); var result = _api.AgreementPay(ApiConfig.Bill99_AgreePay_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, result); UpdateAllotAmountOrderStatus(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE); return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, result.FirstException)); } if (result.Value == null) { UpdateAllotAmountOrderStatus(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE); return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING)); } if (result.Value.TxnMsgContent == null) { UpdateAllotAmountOrderStatus(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE); return(result.Value.ErrorMsgContent != null ? new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(result.Value.ErrorMsgContent.ErrorMessage)) : new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING)); } var respContent = result.Value.TxnMsgContent; if (respContent.ResponseCode != "00") { UpdateAllotAmountOrderStatus(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE); return(new XResult <CPIAgreePayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respContent.ResponseTextMessage))); } UpdateAllotAmountOrderStatus(service, allotAmountOrder, AllotAmountOrderStatus.SUCCESS); var resp = new CPIAgreePayPaymentResponse() { 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.AppId == request.AppId && t0.TradeNo == tradeNo select t0).FirstOrDefault(); //如果支付单存在,并且状态不是最终状态,才更新状态 if (payOrder != null && payOrder.PayStatus != PayStatus.SUCCESS.ToString() && payOrder.PayStatus != PayStatus.FAILURE.ToString()) { payOrder.PayStatus = payStatus.ToString(); payOrder.UpdateTime = DateTime.Now; _payOrderRepository.Update(payOrder); saveResult = _payOrderRepository.SaveChanges(); if (!saveResult.Success) { _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "更新协议支付结果失败", saveResult.FirstException, payOrder); } } return(new XResult <CPIAgreePayPaymentResponse>(resp)); } finally { _lockProvider.UnLock(requestHash); } }