| | |
| | | using DynamicQuery.Net.Dto.Input; |
| | | using LifePayment.Application.Contracts; |
| | | using LifePayment.Application.Contracts; |
| | | using LifePayment.Domain; |
| | | using LifePayment.Domain.LifePay; |
| | | using LifePayment.Domain.Models; |
| | | using LifePayment.Domain.Shared; |
| | | using MailKit.Search; |
| | | using Microsoft.EntityFrameworkCore; |
| | | using Microsoft.Extensions.Logging; |
| | | using Microsoft.Extensions.Options; |
| | | using Nest; |
| | | using Newtonsoft.Json; |
| | | using NPOI.OpenXmlFormats.Dml.Chart; |
| | | using NPOI.SS.Formula.Functions; |
| | | using StackExchange.Redis; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | | using System.Security.Cryptography; |
| | | using System.Linq.Dynamic.Core; |
| | | using System.Threading.Tasks; |
| | | using Volo.Abp; |
| | | using Volo.Abp.Application.Services; |
| | | using Volo.Abp.Domain.Entities; |
| | | using Volo.Abp.Data; |
| | | using Volo.Abp.Domain.Repositories; |
| | | using Volo.Abp.EventBus.Distributed; |
| | | using ZeroD.Util; |
| | | using ZeroD.Util.Fadd; |
| | | using static LifePayment.Domain.Shared.LifePaymentConstant; |
| | | using Volo.Abp.Data; |
| | | using Z.EntityFramework.Plus; |
| | | using LifePayment.Domain.LifePay; |
| | | using pingan.openbank.api.sdk.enums; |
| | | using ZeroD.Util; |
| | | using Alipay.EasySDK.Payment.Common.Models; |
| | | using static LifePayment.Domain.Shared.LifePaymentConstant; |
| | | using ZeroD.Util.Fadd; |
| | | using Nest; |
| | | using Volo.Abp.Domain.Entities; |
| | | using Volo.Abp.ObjectMapping; |
| | | using NPOI.SS.Formula.Functions; |
| | | |
| | | namespace LifePayment.Application; |
| | | |
| | |
| | | private readonly IRepository<LifePayOrder, Guid> _lifePayOrderRepository; |
| | | private readonly IRepository<LifePayUser, Guid> _lifePayUserRepository; |
| | | private readonly IRepository<LifePayIntroInfo, Guid> _lifePayIntroInfoRepository; |
| | | private readonly IRepository<DallyStatistics, Guid> _dallyStatisticsRepository; |
| | | private readonly IRepository<LifePayChannles, Guid> _lifePayChannlesRep; |
| | | private readonly IRepository<LifePayAccount, Guid> _lifePayAccount; |
| | | private readonly IRepository<OperateHistory, Guid> _operateHistory; |
| | | private readonly IDataFilter dataFilter; |
| | | |
| | | private readonly IChannelFilter _channelFilter; |
| | | private readonly IAliPayApi _aliPayApi; |
| | | private readonly IAlipayInterfaceManager _alipayInterfaceManager; |
| | | private readonly IWxPayApi _wxPayApi; |
| | | private readonly WxPayOption _wxPayOptions; |
| | | |
| | |
| | | IRepository<LifePayUser, Guid> lifePayUserRepository, |
| | | IRepository<LifePayPremium, Guid> lifePayPremiumRepository, |
| | | IRepository<LifePayIntroInfo, Guid> lifePayIntroInfoRepository, |
| | | IRepository<DallyStatistics, Guid> dallyStatisticsRepository, |
| | | IRepository<OperateHistory, Guid> operateHistory, |
| | | IAliPayApi aliPayApi, |
| | | IAlipayInterfaceManager aliPayInterfaceManager, |
| | | IWxPayApi wxPayApi, |
| | | IOptions<WxPayOption> wxPayOptions, |
| | | IRepository<LifePayChannles, Guid> lifePayChannlesRep, |
| | | IRepository<LifePayAccount, Guid> lifePayAccount, |
| | | IDataFilter dataFilter) |
| | | IDataFilter dataFilter, |
| | | IChannelFilter channelFilter) |
| | | { |
| | | _logger = logger; |
| | | _aCOOLYManager = aCOOLYManager; |
| | |
| | | _lifePayUserRepository = lifePayUserRepository; |
| | | _lifePayPremiumRepository = lifePayPremiumRepository; |
| | | _lifePayIntroInfoRepository = lifePayIntroInfoRepository; |
| | | _dallyStatisticsRepository = dallyStatisticsRepository; |
| | | _aliPayApi = aliPayApi; |
| | | _alipayInterfaceManager = aliPayInterfaceManager; |
| | | _wxPayApi = wxPayApi; |
| | | _wxPayOptions = wxPayOptions.Value; |
| | | _distributedEventBus = distributedEventBus; |
| | | _lifePayChannlesRep = lifePayChannlesRep; |
| | | _lifePayAccount = lifePayAccount; |
| | | this.dataFilter = dataFilter; |
| | | _channelFilter = channelFilter; |
| | | _operateHistory = operateHistory; |
| | | } |
| | | |
| | | #region 查询 |
| | | |
| | | public async Task<TopStatisticsOutput> GetTopStatistics() |
| | | { |
| | | var today = DateTime.Now.ToString("yyyy-MM-dd"); |
| | | var statistics = await _dallyStatisticsRepository.Where(x => x.CreationTime.ToString("yyyy-MM-dd") == today).FirstOrDefaultAsync(); |
| | | if (statistics == null) |
| | | { |
| | | //var accumulatedReceipts = await _lifePayOrderRepository.Where(x => x.CreationTime < today).SumAsync(x => x.PayAmount); |
| | | |
| | | var entity = new DallyStatistics() |
| | | { |
| | | Id = GuidGenerator.Create(), |
| | | CreationTime = DateTime.Now, |
| | | Amount = "0", |
| | | AccumulatedReceipts = "0", |
| | | ReceiptsYesterda = "0", |
| | | AccumulatedOrders = "0", |
| | | OrdersNumYesterda = "0", |
| | | YesterdaSuccess = "0", |
| | | YesterdaFail = "0", |
| | | AccumulatedUsers = "0", |
| | | }; |
| | | |
| | | return new TopStatisticsOutput(); |
| | | } |
| | | else |
| | | { |
| | | var result = ObjectMapper.Map<DallyStatistics,TopStatisticsOutput>(statistics); |
| | | return result; |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取电费面值 |
| | |
| | | public async Task<List<LifePayIntroInfoOutput>> GetIntroInfo(LifePayOrderTypeEnum lifePayType) |
| | | { |
| | | return await _lifePayIntroInfoRepository.Where(x => x.IsDeleted == false && x.LifePayType == lifePayType).OrderBy(x => x.Sequence) |
| | | .Select(x => new LifePayIntroInfoOutput() { Type = x.Type, ContentSummary = x.ContentSummary, Content = x.Content, LifePayType = x.LifePayType,Path = x.Path,Sequence = x.Sequence }) |
| | | .Select(x => new LifePayIntroInfoOutput() { Type = x.Type, ContentSummary = x.ContentSummary, Content = x.Content, LifePayType = x.LifePayType, Path = x.Path, Sequence = x.Sequence }) |
| | | .ToListAsync(); |
| | | } |
| | | |
| | |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | /// <returns></returns> |
| | | public async Task<PageOutput<UserListOutput>> GetUserPage(PageInput input) |
| | | public async Task<PageOutput<UserListOutput>> GetUserPage(QueryUserPageInput input) |
| | | { |
| | | return await _lifePayUserRepository.Select(x => |
| | | return await _channelFilter.GetChannelLifePayUserFilter(_lifePayUserRepository).Where(x => x.IsDeleted == false) |
| | | .WhereIf(!string.IsNullOrEmpty(input.QueryCondition), x => x.PhoneNumber.Contains(input.QueryCondition) || x.Name.Contains(input.QueryCondition)) |
| | | .WhereIf(input.CreationTimeBegin.HasValue, x => x.CreationTime >= input.CreationTimeBegin) |
| | | .WhereIf(input.CreationTimeEnd.HasValue, x => x.CreationTime <= input.CreationTimeEnd) |
| | | .Select(x => |
| | | new UserListOutput() |
| | | { |
| | | Id = x.Id, |
| | | CreationChannle = string.IsNullOrEmpty(x.CreationChannleNum) ? "" : _lifePayChannlesRep.Where(c => c.ChannlesNum == x.CreationChannleNum).FirstOrDefault().ChannlesName, |
| | | LastLoginChannle = string.IsNullOrEmpty(x.LastLoginChannleNum) ? "" : _lifePayChannlesRep.Where(c => c.ChannlesNum == x.LastLoginChannleNum).FirstOrDefault().ChannlesName, |
| | | PhoneNumber = x.PhoneNumber, |
| | | Name = string.IsNullOrEmpty(x.Name) ? "" : x.Name, |
| | | CreationTime = x.CreationTime, |
| | | LastLoginTime = x.LastLoginTime |
| | | }) |
| | |
| | | }) |
| | | .GetPageResult(input.PageModel); |
| | | } |
| | | |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <returns></returns> |
| | | public async Task<PageOutput<LifePayOrderListOutput>> GetLifePayOrderPage(QueryLifePayOrderListInput input) |
| | | { |
| | | var result = await (from a in _lifePayOrderRepository.Where(x => x.PayStatus != LifePayStatusEnum.未支付) |
| | | var result = await (from a in _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository) |
| | | .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) |
| | | .WhereIf(input.EndFinishTime.HasValue, x => x.FinishTime <= input.EndFinishTime) |
| | | .WhereIf(input.BeginPayTime.HasValue, x => x.PayTime >= input.BeginPayTime) |
| | |
| | | .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayOrderType == input.LifePayOrderType.Value) |
| | | .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) |
| | | .WhereIf(input.KeyWords.IsNotNullOrEmpty(), x => x.PhoneNumber.Contains(input.KeyWords) || x.OrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords)) |
| | | join b in _lifePayChannlesRep on a.ChannelId equals b.Id into temp |
| | | join b in _lifePayChannlesRep on a.ChannelId equals b.ChannlesNum into temp |
| | | from b in temp.DefaultIfEmpty() |
| | | select new LifePayOrderListOutput |
| | | { |
| | |
| | | RefundCheckRemark = a.RefundCheckRemark, |
| | | RefundApplyRemark = a.RefundApplyRemark, |
| | | RefundTime = a.RefundTime, |
| | | ChannelName = b.ChannlesName |
| | | ChannelName = b.ChannlesName, |
| | | ActualRechargeAmount = a.ActualRechargeAmount, |
| | | PlatformDeductionAmount = a.PlatformDeductionAmount, |
| | | ACOOLYStatus = a.ACOOLYStatus, |
| | | LifePayRefundStatus = a.LifePayRefundStatus, |
| | | }).GetPageResult(input.PageModel); |
| | | |
| | | return result; |
| | | } |
| | | |
| | | public async Task<LifePayOrderOutput> GetLifePayOrderDetail(string orderNo) |
| | | { |
| | | var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); |
| | | var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); |
| | | var channle = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == order.ChannelId); |
| | | var premium = await _lifePayPremiumRepository.Where(x => x.IsDeleted == false && x.PremiumType == order.LifePayType).FirstOrDefaultAsync(); |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); |
| | | var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == order.UserId); |
| | | |
| | | var channlesRakePrice = (order.PayAmount - (order.PlatformDeductionAmount == null ? 0 : order.PlatformDeductionAmount)) * channle.ChannlesRakeRate / 100; |
| | | var result = new LifePayOrderOutput() |
| | | { |
| | | UserName = user.Name, |
| | | UserPhoneNumber = user.PhoneNumber, |
| | | DiscountAmount = order.DiscountAmount, |
| | | FinishTime = order.FinishTime, |
| | | Id = order.Id, |
| | | OutOrderNo = order.OutOrderNo, |
| | | LifePayChannle = channle.ChannlesName, |
| | | Status = order.LifePayOrderStatus, |
| | | LifePayOrderType = order.LifePayOrderType, |
| | | LifePayType = order.LifePayType, |
| | | OrderNo = order.OrderNo, |
| | | PayAmount = order.PayAmount, |
| | | RechargeAmount = order.RechargeAmount, |
| | | PayStatus = order.PayStatus, |
| | | PayTime = order.PayTime, |
| | | OrderParamDetailJsonStr = order.OrderParamDetailJsonStr, |
| | | RefundCredentialsImgUrl = order.RefundCredentialsImgUrl.GetOssPath(), |
| | | CreationTime = order.CreationTime, |
| | | RefundCheckRemark = order.RefundCheckRemark, |
| | | RefundApplyRemark = order.RefundApplyRemark, |
| | | RefundTime = order.RefundTime, |
| | | ACOOLYOrderNo = order.ACOOLYOrderNo, |
| | | LifePayRefundStatus = order.LifePayRefundStatus, |
| | | ActualRechargeAmount = order.ActualRechargeAmount, |
| | | RefundPrice = order.RefundPrice, |
| | | PlatformRate = platformRate.Rate, |
| | | PlatformPrice = order.PlatformDeductionAmount, |
| | | ChannleRate = channle.ChannlesRate, |
| | | ChannlesRakeRate = channle.ChannlesRakeRate, |
| | | ChannlesRakePrice = channlesRakePrice.HasValue ? 0 : Math.Round(channlesRakePrice.Value, 2), |
| | | PremiumRate = premium == null ? 0 : premium.Rate, |
| | | PremiumPrice = premium == null ? 0 : Math.Round(order.PayAmount * premium.Rate, 2), |
| | | Profit = (order.PayAmount - order.PlatformDeductionAmount) * (1.00m - channle.ChannlesRakeRate / 100) - (premium == null ? 0 : Math.Round(order.PayAmount * premium.Rate, 2)) |
| | | }; |
| | | |
| | | return result; |
| | | } |
| | | |
| | | public async Task<LifePayRefundOrderOutput> GetLifePayRefundOrderDetail(string orderNo) |
| | | { |
| | | var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); |
| | | var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); |
| | | var channle = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == order.ChannelId); |
| | | var premium = await _lifePayPremiumRepository.Where(x => x.IsDeleted == false && x.PremiumType == order.LifePayType).FirstOrDefaultAsync(); |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); |
| | | var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == order.UserId); |
| | | |
| | | var channlesRakePrice = (order.PayAmount - (order.PlatformDeductionAmount == null ? 0 : order.PlatformDeductionAmount)) * channle.ChannlesRakeRate / 100; |
| | | var result = new LifePayRefundOrderOutput() |
| | | { |
| | | UserName = user.Name, |
| | | UserPhoneNumber = user.PhoneNumber, |
| | | DiscountAmount = order.DiscountAmount, |
| | | FinishTime = order.FinishTime, |
| | | Id = order.Id, |
| | | OutOrderNo = order.OutOrderNo, |
| | | LifePayChannle = channle.ChannlesName, |
| | | Status = order.LifePayOrderStatus, |
| | | LifePayOrderType = order.LifePayOrderType, |
| | | LifePayType = order.LifePayType, |
| | | OrderNo = order.OrderNo, |
| | | PayAmount = order.PayAmount, |
| | | RechargeAmount = order.RechargeAmount, |
| | | PayStatus = order.PayStatus, |
| | | PayTime = order.PayTime, |
| | | RefundCredentialsImgUrl = order.RefundCredentialsImgUrl.GetOssPath(), |
| | | CreationTime = order.CreationTime, |
| | | RefundCheckRemark = order.RefundCheckRemark, |
| | | RefundApplyRemark = order.RefundApplyRemark, |
| | | RefundApplyTime = order.RefundApplyTime, |
| | | RefundTime = order.RefundTime, |
| | | RefundOrderNo = order.RefundOrderNo, |
| | | ACOOLYOrderNo = order.ACOOLYOrderNo, |
| | | LifePayRefundStatus = order.LifePayRefundStatus, |
| | | ActualRechargeAmount = order.ActualRechargeAmount, |
| | | RefundPrice = order.RefundPrice, |
| | | }; |
| | | |
| | | return result; |
| | | } |
| | |
| | | return new PageOutput<UserLifePayOrderOutput>(); |
| | | } |
| | | |
| | | return await _lifePayOrderRepository.Where(x => x.PayStatus != LifePayStatusEnum.未支付) |
| | | return await _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository).Where(x => x.PayStatus != LifePayStatusEnum.未支付) |
| | | .WhereIf(input.BeginFinishTime.HasValue, x => x.FinishTime >= input.BeginFinishTime) |
| | | .WhereIf(input.EndFinishTime.HasValue, x => x.FinishTime <= input.EndFinishTime) |
| | | .WhereIf(input.BeginPayTime.HasValue, x => x.PayTime >= input.BeginPayTime) |
| | |
| | | return result; |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 根据订单号获取支付状态 |
| | | /// </summary> |
| | |
| | | { |
| | | Id = x.Id, |
| | | ChannlesRate = x.ChannlesRate, |
| | | ChannlesRakeRate = x.ChannlesRakeRate, |
| | | ChannlesName = x.ChannlesName, |
| | | ChannlesNum = x.ChannlesNum, |
| | | Status = x.Status, |
| | |
| | | |
| | | public async Task<UserLifePayOrderRefundOutput> GetUserLifePayOrderRefund(Guid id) |
| | | { |
| | | var order = await _lifePayOrderRepository.Where(x => x.Id == id).Select(x => |
| | | var order = await _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository).Where(x => x.Id == id).Select(x => |
| | | new UserLifePayOrderRefundOutput |
| | | { |
| | | Id = x.Id, |
| | |
| | | }); |
| | | return result; |
| | | } |
| | | public async Task<string> GetBillErceiptExport(string orderNo) |
| | | { |
| | | try |
| | | { |
| | | var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); |
| | | |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "未找到订单信息"); |
| | | if (order.LifePayType == LifePayTypeEnum.AliPay) |
| | | { |
| | | var elecInfoInput = new DataBillErceiptApplyInput |
| | | { |
| | | Type = "FUND_DETAIL", |
| | | Key = orderNo |
| | | }; |
| | | |
| | | var elecInfoOutput = await _alipayInterfaceManager.DataBillErceiptApply(elecInfoInput); |
| | | if (elecInfoOutput != null) |
| | | { |
| | | var elecFileInput = new DataBillEreceiptQueryInput |
| | | { |
| | | FileId = elecInfoOutput.FileId, |
| | | }; |
| | | var elecFileOutput = await _alipayInterfaceManager.DataBillEreceiptQuery(elecFileInput); |
| | | if (!string.IsNullOrEmpty(elecFileOutput.DownloadUrl)) |
| | | { |
| | | return elecFileOutput.DownloadUrl; |
| | | } |
| | | return ""; |
| | | } |
| | | return ""; |
| | | } |
| | | else |
| | | { |
| | | WxPayTradeBillApplyRequest req = new WxPayTradeBillApplyRequest |
| | | { |
| | | OutBillNo = order.OutOrderNo, |
| | | }; |
| | | |
| | | var res = await _wxPayApi.WxPayTradeBillApply(req); |
| | | return ""; |
| | | } |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | _logger.LogError("获取订单号为{0}电子回单出现错误:{1}", orderNo, ex.Message); |
| | | return ""; |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | #region 操作 |
| | |
| | | |
| | | var orderInput = new CreateLifePayOrderInput |
| | | { |
| | | OrderNo = CreateOrderNo(), |
| | | OrderNo = channle.ChannlesNum + CreateOrderNo(), |
| | | LifePayOrderStatus = LifePayOrderStatusEnum.待确认, |
| | | LifePayOrderType = LifePayOrderTypeEnum.话费订单, |
| | | //LifePayType = input.LifePayType, |
| | |
| | | PayAmount = amount.PayAmont, |
| | | DiscountAmount = amount.DiscountAmount, |
| | | RechargeAmount = amount.RechargeAmount, |
| | | ChannelId = channle.Id |
| | | ChannelId = channle.ChannlesNum |
| | | }; |
| | | |
| | | await CreateLifePayOrder(orderInput); |
| | |
| | | |
| | | var orderInput = new CreateLifePayOrderInput |
| | | { |
| | | OrderNo = CreateOrderNo(), |
| | | OrderNo = channle.ChannlesNum + CreateOrderNo(), |
| | | LifePayOrderStatus = LifePayOrderStatusEnum.待确认, |
| | | LifePayOrderType = LifePayOrderTypeEnum.电费订单, |
| | | // LifePayType = input.LifePayType, |
| | |
| | | PayAmount = amount.PayAmont, |
| | | DiscountAmount = amount.DiscountAmount, |
| | | RechargeAmount = amount.RechargeAmount, |
| | | ChannelId = channle.Id |
| | | ChannelId = channle.ChannlesNum |
| | | }; |
| | | |
| | | await CreateLifePayOrder(orderInput); |
| | |
| | | |
| | | var orderInput = new CreateLifePayOrderInput |
| | | { |
| | | OrderNo = CreateOrderNo(), |
| | | OrderNo = channle.ChannlesNum + CreateOrderNo(), |
| | | LifePayOrderStatus = LifePayOrderStatusEnum.待确认, |
| | | LifePayOrderType = LifePayOrderTypeEnum.燃气订单, |
| | | // LifePayType = input.LifePayType, |
| | |
| | | PayAmount = amount.PayAmont, |
| | | DiscountAmount = amount.DiscountAmount, |
| | | RechargeAmount = amount.RechargeAmount, |
| | | ChannelId = channle.Id |
| | | ChannelId = channle.ChannlesNum |
| | | }; |
| | | |
| | | await CreateLifePayOrder(orderInput); |
| | |
| | | OpenId = openid |
| | | } |
| | | }; |
| | | Logger.LogError("调用请求:" + req.ToJson()); |
| | | var timestamp = DateTimeOffset.Now.ToUnixTimeSeconds(); |
| | | string nonce = Guid.NewGuid().ToString(); |
| | | |
| | | var res = await _wxPayApi.PayTransactionsJsAPI(req); |
| | | Logger.LogError("调用结果:" + res.ToJson()); |
| | | string package = "prepay_id=" + res.PrepayId; |
| | | ModelPaymentMiniPay info = new ModelPaymentMiniPay(); |
| | | if (res != null) |
| | |
| | | /// <param name="orderNo"></param> |
| | | /// <param name="outOrderNo"></param> |
| | | /// <returns></returns> |
| | | public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status) |
| | | public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status, ACOOLYStatusEnum acoolyStatus, decimal payAmount) |
| | | { |
| | | var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); |
| | |
| | | } |
| | | |
| | | order.LifePayOrderStatus = status; |
| | | order.ACOOLYStatus = acoolyStatus; |
| | | order.PlatformDeductionAmount = payAmount; |
| | | if (acoolyOrderNo.IsNotNullOrEmpty()) |
| | | { |
| | | order.ACOOLYOrderNo = acoolyOrderNo; |
| | |
| | | { |
| | | order.PayStatus = LifePayStatusEnum.待退款; |
| | | } |
| | | |
| | | |
| | | await _lifePayOrderRepository.UpdateAsync(order); |
| | | } |
| | |
| | | throw new UserFriendlyException("当前订单状态无法退款"); |
| | | } |
| | | |
| | | /// TODO 退款请求完成后如何操作 |
| | | /// var refundResult = await WxPayDomesticRefunds(order.OrderNo, order.RefundApplyRemark, Convert.ToInt32(order.PayAmount * 100), Convert.ToInt32(order.PayAmount * 100)); |
| | | var outRefundNo = order.ChannelId + CreateRefundOrderNo(); |
| | | order.RefundOrderNo = outRefundNo; |
| | | switch (order.LifePayType) |
| | | { |
| | | case LifePayTypeEnum.WxPay: |
| | | var wxRefundResult = await WxPayDomesticRefunds(order.OrderNo, outRefundNo,order.RefundApplyRemark, Convert.ToInt32(order.PayAmount * 100), Convert.ToInt32(order.PayAmount * 100)); |
| | | if (wxRefundResult.Status == "SUCCESS") |
| | | { |
| | | order.PayStatus = LifePayStatusEnum.已退款; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; |
| | | order.LifePayRefundStatus = LifePayRefundStatusEnum.已退款; |
| | | } |
| | | else if (wxRefundResult.Status == "PROCESSING") |
| | | { |
| | | order.PayStatus = LifePayStatusEnum.退款中; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; |
| | | order.LifePayRefundStatus = LifePayRefundStatusEnum.退款中; |
| | | } |
| | | else |
| | | { |
| | | order.PayStatus = LifePayStatusEnum.待退款; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.退款失败; |
| | | order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款; |
| | | } |
| | | |
| | | order.PayStatus = LifePayStatusEnum.已退款; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; |
| | | break; |
| | | case LifePayTypeEnum.AliPay: |
| | | var aliRefundResult = await AliTradeRefund(new AlipayTradeRefundRequest() { OutTradeNo = order.OrderNo, RefundAmount = order.PayAmount.ToString() }); |
| | | if (aliRefundResult.Code != AlipayResultCode.Success) |
| | | { |
| | | throw new UserFriendlyException("退款失败"); |
| | | } |
| | | |
| | | order.PayStatus = LifePayStatusEnum.已退款; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; |
| | | break; |
| | | default: throw new UserFriendlyException("退款失败"); |
| | | } |
| | | |
| | | order.RefundCredentialsImgUrl = input.RefundCredentialsImgUrl; |
| | | order.RefundCheckRemark = input.RefundCheckRemark; |
| | | order.RefundTime = DateTime.Now; |
| | | order.RefundCheckUserId = CurrentUser.Id; |
| | | order.RefundPrice = order.PayAmount; |
| | | |
| | | await _lifePayOrderRepository.UpdateAsync(order); |
| | | |
| | | #region 记录日志 |
| | | |
| | | await PublishLifePayOrderHistoryEvent("退款", "退款", order.Id); |
| | | await LifePayOrderHistory("退款", "退款", order.Id, (int)OperateHistoryTypeEnum.LifePayRefund); |
| | | |
| | | #endregion |
| | | |
| | |
| | | |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.退款待审核; |
| | | order.RefundApplyRemark = input.RefundApplyRemark; |
| | | order.RefundTime = DateTime.Now; |
| | | order.RefundApplyTime = DateTime.Now; |
| | | |
| | | await _lifePayOrderRepository.UpdateAsync(order); |
| | | } |
| | | |
| | | public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(string outTradeNo, string reason, int refund, int total, string currency = "CNY") |
| | | /// <summary> |
| | | /// 微信退款 |
| | | /// </summary> |
| | | /// <param name="outTradeNo"></param> |
| | | /// <param name="reason"></param> |
| | | /// <param name="refund"></param> |
| | | /// <param name="total"></param> |
| | | /// <param name="currency"></param> |
| | | /// <returns></returns> |
| | | public async Task<WxPayDomesticRefundsReponse> WxPayDomesticRefunds(string outTradeNo,string outRefundNo, string reason, int refund, int total, string currency = "CNY") |
| | | { |
| | | WxPayDomesticRefundsRequest req = new WxPayDomesticRefundsRequest |
| | | { |
| | | OutTradeNo = outTradeNo, |
| | | OutRefundNo = CreateRefundOrderNo(), |
| | | OutRefundNo = outRefundNo, |
| | | Reason = reason, |
| | | Amount = new Model_WxPayDomesticRefunds_Amount |
| | | { |
| | |
| | | return res; |
| | | } |
| | | |
| | | private async Task<AlipayTradeRefundResponse> AliTradeRefund(AlipayTradeRefundRequest input) |
| | | { |
| | | return await _aliPayApi.TradeRefund(input); |
| | | } |
| | | |
| | | public async Task<int> AddUpdateUserAccount(AddUpdateUserAccountInput input) |
| | | { |
| | | var user = await _lifePayUserRepository.Where(r => r.Id == input.UserId && !r.IsDeleted).FirstOrDefaultAsync(); |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "用户不存在"); |
| | | |
| | | if (input.Id.HasValue) |
| | | { |
| | | var userAccount = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.Id == input.Id) |
| | |
| | | }; |
| | | await _lifePayAccount.InsertAsync(userAccount); |
| | | } |
| | | |
| | | if (input.LifePayType == LifePayOrderTypeEnum.话费订单) |
| | | { |
| | | var extraProperties = JsonConvert.DeserializeObject<Model_UserAccountExtraProperties>(input.ExtraProperties); |
| | | if (!string.IsNullOrEmpty(extraProperties.Name)) |
| | | { |
| | | user.Name = extraProperties.Name; |
| | | } |
| | | } |
| | | |
| | | |
| | | return Constant.SUCCESS; |
| | | } |
| | |
| | | await _distributedEventBus.PublishAsync(recordEto, false); |
| | | } |
| | | |
| | | private async Task LifePayOrderHistory(string operateContent, string operateName, Guid relationId, int? tableType = (int)OperateHistoryTypeEnum.LifePayRefund) |
| | | { |
| | | var operateHistory = new OperateHistory |
| | | { |
| | | CreatorName = CurrentUser.Name, |
| | | OperateContent = operateName, |
| | | OperateName = operateName, |
| | | RelationId = relationId, |
| | | TableType = tableType |
| | | |
| | | }; |
| | | await _operateHistory.InsertAsync(operateHistory); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取支付二维码 |
| | | /// </summary> |
| | |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(amount <= 0, |
| | | CustomeErrorMessage.SometingMustSometing, |
| | | "获取支付二维码时金额", "大于0"); |
| | | |
| | | var res = await _wxPayApi.PayTransactionsH5(new PayTransactionsNativeH5 |
| | | { |
| | | Appid = _wxPayOptions.AppID, |
| | |
| | | |
| | | return res.QrCode; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 构造待签名字符串 |
| | | /// </summary> |
| | |
| | | .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayOrderType == input.LifePayOrderType.Value) |
| | | .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) |
| | | .WhereIf(input.KeyWords.IsNotNullOrEmpty(), x => x.PhoneNumber.Contains(input.KeyWords) || x.OrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords)) |
| | | join b in _lifePayChannlesRep on a.ChannelId equals b.Id into temp |
| | | join b in _lifePayChannlesRep on a.ChannelId equals b.ChannlesNum into temp |
| | | from b in temp.DefaultIfEmpty() |
| | | select new LifePayOrderListOutput |
| | | { |
| | |
| | | { |
| | | Id = x.Id, |
| | | ChannlesRate = x.ChannlesRate, |
| | | ChannlesRakeRate = x.ChannlesRakeRate, |
| | | ChannlesName = x.ChannlesName, |
| | | ChannlesNum = x.ChannlesNum, |
| | | Status = x.Status, |
| | |
| | | }); |
| | | } |
| | | |
| | | #endregion |
| | | } |
| | | #endregion |
| | | } |