| | |
| | | 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 static IdentityServer4.Models.IdentityResources; |
| | | using Volo.Abp.Data; |
| | | using Z.EntityFramework.Plus; |
| | | using ZeroD.Util; |
| | | using Alipay.EasySDK.Payment.Common.Models; |
| | | using static LifePayment.Domain.Shared.LifePaymentConstant; |
| | | using ZeroD.Util.Fadd; |
| | | using Nest; |
| | | |
| | | namespace LifePayment.Application; |
| | | |
| | |
| | | private readonly ILogger<LifePayService> _logger; |
| | | |
| | | private readonly IRepository<LifePayRate, Guid> _lifePayRateRepository; |
| | | private readonly IRepository<LifePayPremium, Guid> _lifePayPremiumRepository; |
| | | private readonly IRepository<LifePayOrder, Guid> _lifePayOrderRepository; |
| | | private readonly IRepository<LifePayUser, Guid> _lifePayUserRepository; |
| | | private readonly IRepository<LifePayIntroInfo, Guid> _lifePayIntroInfoRepository; |
| | | private readonly IRepository<LifePayChannles, Guid> _lifePayChannlesRep; |
| | | private readonly IRepository<LifePayAccount, Guid> _lifePayAccount; |
| | | private readonly IDataFilter dataFilter; |
| | | |
| | | private readonly IChannelFilter _channelFilter; |
| | | private readonly IAliPayApi _aliPayApi; |
| | | private readonly IWxPayApi _wxPayApi; |
| | | private readonly WxPayOption _wxPayOptions; |
| | |
| | | IRepository<LifePayRate, Guid> lifePayRateRepository, |
| | | IRepository<LifePayOrder, Guid> lifePayOrderRepository, |
| | | IRepository<LifePayUser, Guid> lifePayUserRepository, |
| | | IRepository<LifePayPremium, Guid> lifePayPremiumRepository, |
| | | IRepository<LifePayIntroInfo, Guid> lifePayIntroInfoRepository, |
| | | IAliPayApi aliPayApi, |
| | | IWxPayApi wxPayApi, |
| | | IOptions<WxPayOption> wxPayOptions, |
| | | IRepository<LifePayChannles, Guid> lifePayChannlesRep, |
| | | IRepository<LifePayAccount, Guid> lifePayAccount, |
| | | IDataFilter dataFilter) |
| | | IDataFilter dataFilter, |
| | | IChannelFilter channelFilter) |
| | | { |
| | | _logger = logger; |
| | | _aCOOLYManager = aCOOLYManager; |
| | | _lifePayRateRepository = lifePayRateRepository; |
| | | _lifePayOrderRepository = lifePayOrderRepository; |
| | | _lifePayUserRepository = lifePayUserRepository; |
| | | _lifePayPremiumRepository = lifePayPremiumRepository; |
| | | _lifePayIntroInfoRepository = lifePayIntroInfoRepository; |
| | | _aliPayApi = aliPayApi; |
| | | _wxPayApi = wxPayApi; |
| | | _wxPayOptions = wxPayOptions.Value; |
| | |
| | | _lifePayChannlesRep = lifePayChannlesRep; |
| | | _lifePayAccount = lifePayAccount; |
| | | this.dataFilter = dataFilter; |
| | | _channelFilter = channelFilter; |
| | | } |
| | | |
| | | #region 查询 |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取手续费费率 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public async Task<List<LifePayPremiumListOutput>> GetPremium() |
| | | { |
| | | return await _lifePayPremiumRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayPremiumListOutput() { Id = x.Id, Rate = x.Rate, PremiumType = x.PremiumType }) |
| | | .ToListAsync(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 须知配置 |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | 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 }) |
| | | .ToListAsync(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取用户分页数据 |
| | | /// </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, |
| | | LifePayOrderStatus = 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, |
| | | LifePayOrderStatus = 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, |
| | | RefundTime = order.RefundTime, |
| | | 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> |
| | |
| | | |
| | | public async Task<PageOutput<CreateEditPayChannelsInput>> GetLifePayChannlesPage(PageInput input) |
| | | { |
| | | return await GetLifePayChannlesListFilter().GetPageResult(input.PageModel); |
| | | } |
| | | |
| | | return await _lifePayChannlesRep.Select(x => |
| | | new CreateEditPayChannelsInput |
| | | { |
| | | Id = x.Id, |
| | | ChannlesRate = x.ChannlesRate, |
| | | ChannlesName = x.ChannlesName, |
| | | ChannlesNum = x.ChannlesNum, |
| | | Status = x.Status, |
| | | SwitchType = x.SwitchType, |
| | | ChannlesType = x.ChannlesType, |
| | | }) |
| | | .GetPageResult(input.PageModel); |
| | | public async Task<List<CreateEditPayChannelsInput>> GetLifePayChannlesAllList() |
| | | { |
| | | return await GetLifePayChannlesListFilter().Where(x => x.Status == LifePayChannelsStatsEnum.启用).ToListAsync(); |
| | | } |
| | | |
| | | public async Task<CreateEditPayChannelsInput> GetLifePayChannlesDto(Guid id) |
| | |
| | | { |
| | | Id = x.Id, |
| | | ChannlesRate = x.ChannlesRate, |
| | | ChannlesRakeRate = x.ChannlesRakeRate, |
| | | ChannlesName = x.ChannlesName, |
| | | ChannlesNum = x.ChannlesNum, |
| | | Status = x.Status, |
| | |
| | | { |
| | | 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, |
| | |
| | | |
| | | 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); |
| | |
| | | /// <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("当前订单状态无法退款"); |
| | | } |
| | | |
| | | order.PayStatus = LifePayStatusEnum.已退款; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; |
| | | 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.已退款; |
| | | } |
| | | else if (wxRefundResult.Status == "PROCESSING") |
| | | { |
| | | order.PayStatus = LifePayStatusEnum.退款中; |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; |
| | | } |
| | | else |
| | | { |
| | | throw new UserFriendlyException("退款失败"); |
| | | } |
| | | |
| | | 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); |
| | | |
| | |
| | | |
| | | order.LifePayOrderStatus = LifePayOrderStatusEnum.退款待审核; |
| | | order.RefundApplyRemark = input.RefundApplyRemark; |
| | | order.RefundTime = DateTime.Now; |
| | | order.RefundApplyTime = DateTime.Now; |
| | | |
| | | await _lifePayOrderRepository.UpdateAsync(order); |
| | | } |
| | | |
| | | /// <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 = outRefundNo, |
| | | Reason = reason, |
| | | Amount = new Model_WxPayDomesticRefunds_Amount |
| | | { |
| | | Refund = refund, |
| | | Total = total, |
| | | Currency = "CNY" |
| | | }, |
| | | NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxPayDomesticRefundsNotifySectionUrl}", |
| | | }; |
| | | |
| | | var res = await _wxPayApi.WxPayDomesticRefunds(req); |
| | | 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) |
| | |
| | | } |
| | | else |
| | | { |
| | | |
| | | var repeatAccountContent = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.LifePayType == input.LifePayType && x.Content == input.Content) |
| | | .FirstOrDefaultAsync(); |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(repeatAccountContent != null, "户号已存在"); |
| | |
| | | }; |
| | | 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; |
| | | } |
| | |
| | | dto.ChannlesName = input.ChannlesName; |
| | | dto.ChannlesNum = input.ChannlesNum; |
| | | dto.ChannlesRate = input.ChannlesRate; |
| | | dto.ChannlesRakeRate = input.ChannlesRakeRate; |
| | | dto.SwitchType = input.SwitchType; |
| | | dto.ChannlesType = input.ChannlesType; |
| | | dto.Status = input.Status; |
| | |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(dto.Status == LifePayChannelsStatsEnum.禁用, "当前渠道商已禁用"); |
| | | return true; |
| | | } |
| | | |
| | | public async Task CreateEditLifePayRate(List<LifePayRateInput> input) |
| | | { |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate <= 0).Any(), "折扣不得小于等于0"); |
| | |
| | | { |
| | | await _lifePayRateRepository.InsertManyAsync(listData); |
| | | } |
| | | |
| | | } |
| | | |
| | | public async Task CreateEditLifePayPremium(List<LifePayPremiumInput> input) |
| | | { |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate < 0).Any(), "折扣不得小于0"); |
| | | var listData = new List<LifePayPremium>(); |
| | | foreach (var item in input) |
| | | { |
| | | var tmpDto = await _lifePayPremiumRepository.FirstOrDefaultAsync(r => r.PremiumType == item.PremiumType); |
| | | if (tmpDto != null) |
| | | { |
| | | tmpDto.Rate = item.Rate; |
| | | } |
| | | else |
| | | { |
| | | listData.Add(new LifePayPremium |
| | | { |
| | | CreationTime = DateTime.Now, |
| | | Rate = item.Rate, |
| | | PremiumType = item.PremiumType, |
| | | Id = Guid.NewGuid(), |
| | | }); |
| | | } |
| | | } |
| | | |
| | | if (listData.Any()) |
| | | { |
| | | await _lifePayPremiumRepository.InsertManyAsync(listData); |
| | | } |
| | | } |
| | | |
| | | public async Task EditIntroInfo(LifePayIntroInfoInput input) |
| | | { |
| | | var listData = new List<LifePayIntroInfo>(); |
| | | foreach (var item in input.Data) |
| | | { |
| | | var tmpDto = await _lifePayIntroInfoRepository.Where(r => r.LifePayType == input.LifePayType).DeleteAsync(); |
| | | |
| | | listData.Add(new LifePayIntroInfo |
| | | { |
| | | LifePayType = input.LifePayType, |
| | | CreationTime = DateTime.Now, |
| | | Type = item.Type, |
| | | ContentSummary = item.ContentSummary, |
| | | Content = item.Content, |
| | | Path = item.Path, |
| | | Sequence = item.Sequence, |
| | | Id = Guid.NewGuid(), |
| | | }); |
| | | } |
| | | |
| | | if (listData.Any()) |
| | | { |
| | | await _lifePayIntroInfoRepository.InsertManyAsync(listData); |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | #region 私有 |
| | |
| | | return "JF" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GlobalRandom.GetRandomNum(4); |
| | | } |
| | | |
| | | private string CreateRefundOrderNo() |
| | | { |
| | | return "JFTK" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + GlobalRandom.GetRandomNum(4); |
| | | } |
| | | |
| | | private (decimal PayAmont, decimal DiscountAmount, decimal RechargeAmount) CalculateAmount(decimal amount, decimal rate) |
| | | { |
| | | /// 正常支付 |
| | | var payAmount = decimal.Round(amount * rate / 100, 2, MidpointRounding.AwayFromZero); |
| | | //var payAmount = decimal.Round(amount * rate / 100, 2, MidpointRounding.AwayFromZero); |
| | | |
| | | /// 1分钱支付 |
| | | //decimal payAmount = 0.01m; |
| | | decimal payAmount = 0.01m; |
| | | |
| | | CheckExtensions.IfTrueThrowUserFriendlyException(payAmount < 0.01m, "支付金额错误"); |
| | | |
| | |
| | | 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 |
| | | { |
| | |
| | | return result; |
| | | } |
| | | |
| | | private IQueryable<CreateEditPayChannelsInput> GetLifePayChannlesListFilter() |
| | | { |
| | | return _lifePayChannlesRep.Select(x => |
| | | new CreateEditPayChannelsInput |
| | | { |
| | | Id = x.Id, |
| | | ChannlesRate = x.ChannlesRate, |
| | | ChannlesRakeRate = x.ChannlesRakeRate, |
| | | ChannlesName = x.ChannlesName, |
| | | ChannlesNum = x.ChannlesNum, |
| | | Status = x.Status, |
| | | SwitchType = x.SwitchType, |
| | | ChannlesType = x.ChannlesType, |
| | | }); |
| | | } |
| | | |
| | | #endregion |
| | | } |