using LifePayment.Application.Contracts; using LifePayment.Domain; using LifePayment.Domain.LifePay; using LifePayment.Domain.Models; using LifePayment.Domain.Shared; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Services; using Volo.Abp.Data; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; 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; using Volo.Abp.Domain.Entities; using Volo.Abp.ObjectMapping; using NPOI.SS.Formula.Functions; using StackExchange.Redis; using static Volo.Abp.Identity.Settings.IdentitySettingNames; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; using LifePayment.Application.LifePay; using Alipay.AopSdk.Core.Domain; namespace LifePayment.Application; public class LifePayService : ApplicationService, ILifePayService { private readonly IDistributedEventBus _distributedEventBus; private readonly ILogger _logger; private readonly IRepository _lifePayRateRepository; private readonly IRepository _lifePayPremiumRepository; private readonly IRepository _lifePayOrderRepository; private readonly IRepository _lifePayUserRepository; private readonly IRepository _lifePayIntroInfoRepository; private readonly IRepository _dallyStatisticsRepository; private readonly IRepository _lifePayChannlesRep; private readonly IRepository _lifePayAccount; private readonly IRepository _operateHistory; private readonly IRepository _lifePayChannlesRakeRepository; private readonly ILifePayOrderService _lifePayOrderService; private readonly IDataFilter dataFilter; private readonly IChannelFilter _channelFilter; private readonly IAliPayApi _aliPayApi; private readonly IAlipayInterfaceManager _alipayInterfaceManager; private readonly IWxPayApi _wxPayApi; private readonly WxPayOption _wxPayOptions; private readonly InitSetting _initSettingOptions; private readonly IACOOLYManager _aCOOLYManager; public LifePayService(IDistributedEventBus distributedEventBus, ILogger logger, IACOOLYManager aCOOLYManager, IRepository lifePayRateRepository, IRepository lifePayOrderRepository, IRepository lifePayUserRepository, IRepository lifePayPremiumRepository, IRepository lifePayIntroInfoRepository, IRepository lifePayChannlesRakeRepository, IRepository operateHistory, ILifePayOrderService lifePayOrderService, IAliPayApi aliPayApi, IAlipayInterfaceManager aliPayInterfaceManager, IWxPayApi wxPayApi, IOptions wxPayOptions, IOptions initSettingOptions, IRepository lifePayChannlesRep, IRepository lifePayAccount, IDataFilter dataFilter, IChannelFilter channelFilter) { _logger = logger; _aCOOLYManager = aCOOLYManager; _lifePayRateRepository = lifePayRateRepository; _lifePayOrderRepository = lifePayOrderRepository; _lifePayUserRepository = lifePayUserRepository; _lifePayChannlesRakeRepository = lifePayChannlesRakeRepository; _lifePayPremiumRepository = lifePayPremiumRepository; _lifePayIntroInfoRepository = lifePayIntroInfoRepository; _aliPayApi = aliPayApi; _lifePayOrderService = lifePayOrderService; _alipayInterfaceManager = aliPayInterfaceManager; _wxPayApi = wxPayApi; _wxPayOptions = wxPayOptions.Value; _initSettingOptions = initSettingOptions.Value; _distributedEventBus = distributedEventBus; _lifePayChannlesRep = lifePayChannlesRep; _lifePayAccount = lifePayAccount; this.dataFilter = dataFilter; _channelFilter = channelFilter; _operateHistory = operateHistory; } #region 查询 /// /// 获取电费面值 /// /// /// public async Task GetElectricParValue() { return await _aCOOLYManager.ElectricParValue(new ACOOLYRequestBaseInput()); } /// /// 获取电费充值区域 /// /// public async Task GetElectricSupportArea() { return await _aCOOLYManager.GetElectricSupportArea(new ACOOLYRequestBaseInput()); } /// /// 获取话费面值 /// /// /// public async Task GetPhoneParValue() { return await _aCOOLYManager.PhoneParValue(new ACOOLYRequestBaseInput()); } /// /// 获取话费面值 /// /// /// public async Task GetGasParValue() { return await _aCOOLYManager.GasParValue(new GasParValueRequestInput()); } /// /// 获取燃气支持商户 /// /// public async Task GetGasOrgType() { return await _aCOOLYManager.GasOrgType(new GasOrgTypeRequestInput()); } /// /// 获取折扣 /// /// public async Task> GetRate() { return await _lifePayRateRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayRateListOutput() { Id = x.Id, Rate = x.Rate, RateType = x.RateType }) .ToListAsync(); } /// /// 获取渠道折扣 /// /// public async Task GetChannelRate(ChannelsBaseInput input) { return _lifePayChannlesRep.Where(x => x.IsDeleted == false && x.ChannlesNum == input.CheckChannelId).Select(x => new ChannelRateOutput() { ChannlesRate = x.ChannlesRate }) .FirstOrDefault(); } /// /// 获取手续费费率 /// /// public async Task> GetPremium() { return await _lifePayPremiumRepository.Where(x => x.IsDeleted == false).Select(x => new LifePayPremiumListOutput() { Id = x.Id, Rate = x.Rate, PremiumType = x.PremiumType }) .ToListAsync(); } /// /// 须知配置 /// /// public async Task> 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(); } /// /// 获取用户分页数据 /// /// /// public async Task> GetUserPage(QueryUserPageInput input) { 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) .WhereIf(input.LoginTimeBegin.HasValue, x => x.LastLoginTime >= input.LoginTimeBegin) .WhereIf(input.LoginTimeEnd.HasValue, x => x.LastLoginTime <= input.LoginTimeEnd) .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); } /// /// 获取用户户号分页数据 /// /// /// public async Task> GetAccountPage(QueryUserAccountListInput input) { using (dataFilter.Disable()) { return await _lifePayAccount.Where(x => x.UserId == input.UserId) .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayType == input.LifePayOrderType) .OrderByDescending(x => x.CreationTime) .Select(x => new UserAccountOutput { Id = x.Id, LifePayType = x.LifePayType, Content = x.Content, CreationTime = x.CreationTime, Remark = x.Remark, Operators = x.Operators, Province = x.Province, City = x.City, ExtraProperties = x.ExtraProperties, IsDeleted = x.IsDeleted }) .GetPageResult(input.PageModel); } } /// /// 获取订单分页数据 /// /// /// public async Task> GetLifePayOrderPage(QueryLifePayOrderListInput input) { var channles = await _lifePayChannlesRep.Where(x => x.ChannlesName.Contains(input.KeyWords)).Select(x => x.ChannlesNum).ToListAsync(); var result = await (from a in _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) .WhereIf(input.LifePayType.HasValue, x => x.LifePayType == input.LifePayType) .WhereIf(input.EndPayTime.HasValue, x => x.PayTime <= input.EndPayTime) .WhereIf(input.LifePayOrderStatus.HasValue, x => x.LifePayOrderStatus == input.LifePayOrderStatus.Value) .WhereIf(input.PayStatus.HasValue, x => x.PayStatus == input.PayStatus.Value) .WhereIf(input.ACOOLYStatus.HasValue, x => x.ACOOLYStatus == input.ACOOLYStatus.Value) .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.OrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords) || channles.Contains(x.ChannelId)) join b in _lifePayChannlesRep on a.ChannelId equals b.ChannlesNum into temp from b in temp.DefaultIfEmpty() select new LifePayOrderListOutput { DiscountAmount = a.DiscountAmount ?? 0, FinishTime = a.FinishTime, Id = a.Id, LifePayOrderStatus = a.LifePayOrderStatus?? 0, LifePayOrderType = a.LifePayOrderType, LifePayType = a.LifePayType, OrderNo = a.OrderNo, PayAmount = a.PayAmount ?? 0, PhoneNumber = a.PhoneNumber, RechargeAmount = a.RechargeAmount??0, UserId = a.UserId, OutOrderNo = a.OutOrderNo, PayStatus = a.PayStatus?? 0, PayTime = a.PayTime, ACOOLYOrderNo = a.ACOOLYOrderNo, RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(), RefundPrice = a.RefundPrice, CreationTime = a.CreationTime, RefundCheckRemark = a.RefundCheckRemark, RefundApplyRemark = a.RefundApplyRemark, RefundTime = a.RefundTime, ChannelName = b.ChannlesName, ActualRechargeAmount = a.RechargeAmount, PlatformDeductionAmount = a.PlatformDeductionAmount, ACOOLYStatus = a.ACOOLYStatus, LifePayRefundStatus = a.LifePayRefundStatus, }).GetPageResult(input.PageModel); return result; } /// /// 退款订单分页 /// /// /// public async Task> GetLifePayRefundOrderPage(QueryLifePayRefundOrderListInput input) { var result = await (from a in _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository) .Where(x => x.LifePayOrderStatus == LifePayOrderStatusEnum.待退款 || x.LifePayOrderStatus == LifePayOrderStatusEnum.已退款 || x.LifePayOrderStatus == LifePayOrderStatusEnum.退款中 || (x.LifePayRefundStatus > LifePayRefundStatusEnum.无需退款 && x.LifePayRefundStatus != LifePayRefundStatusEnum.退款驳回)) .WhereIf(input.BeginRefundTime.HasValue, x => x.RefundTime >= input.BeginRefundTime) .WhereIf(input.EndRefundTime.HasValue, x => x.RefundTime <= input.EndRefundTime) .WhereIf(input.BeginRefundApplyTime.HasValue, x => x.RefundApplyTime >= input.BeginRefundApplyTime) .WhereIf(input.LifePayType.HasValue, x => x.LifePayType == input.LifePayType) .WhereIf(input.EndRefundApplyTime.HasValue, x => x.RefundApplyTime <= input.EndRefundApplyTime) .WhereIf(input.LifePayRefundStatus.HasValue, x => x.LifePayRefundStatus == input.LifePayRefundStatus.Value) .WhereIf(input.ACOOLYStatus.HasValue, x => x.ACOOLYStatus == input.ACOOLYStatus.Value) .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.RefundOrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords)) join b in _lifePayChannlesRep on a.ChannelId equals b.ChannlesNum into temp from b in temp.DefaultIfEmpty() select new LifePayOrderListOutput { DiscountAmount = a.DiscountAmount ?? 0, FinishTime = a.FinishTime, Id = a.Id, LifePayOrderStatus = a.LifePayOrderStatus ?? 0, LifePayOrderType = a.LifePayOrderType, LifePayType = a.LifePayType, OrderNo = a.OrderNo, PayAmount = a.PayAmount ?? 0, PhoneNumber = a.PhoneNumber, RechargeAmount = a.RechargeAmount ?? 0, UserId = a.UserId, OutOrderNo = a.OutOrderNo, PayStatus = a.PayStatus ?? 0, PayTime = a.PayTime, ACOOLYOrderNo = a.ACOOLYOrderNo, RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(), CreationTime = a.CreationTime, RefundCheckRemark = a.RefundCheckRemark, RefundApplyRemark = a.RefundApplyRemark, RefundApplyTime = a.RefundApplyTime, RefundOrderNo = a.RefundOrderNo, RefundTime = a.RefundTime, RefundPrice = a.RefundPrice, ChannelName = b.ChannlesName, ActualRechargeAmount = a.RechargeAmount, PlatformDeductionAmount = a.PlatformDeductionAmount, ACOOLYStatus = a.ACOOLYStatus, LifePayRefundStatus = a.LifePayRefundStatus, }).GetPageResult(input.PageModel); return result; } /// /// 退款订单分页 /// /// /// public async Task> GetLifePayRefudOrderPageExport(QueryLifePayRefundOrderListInput input) { var result = await (await GetLifePayRefundOrderListFilter(input)).Select(x => new LifePayRefundOrderListTemplate { FinishTime = x.RefundTime, RefundPrice = x.RefundPrice, LifePayOrderType = x.LifePayOrderType, LifePayType = x.LifePayType, PayAmount = x.PayAmount, PhoneNumber = x.PhoneNumber, RefundOrderNo = x.RefundOrderNo, RefundApplyTime = x.RefundApplyTime, ChannelName = x.ChannelName, CreationTime = x.CreationTime, ACOOLYStatus = x.ACOOLYStatus, RefundApplyRemark = x.RefundApplyRemark, RechargeAmount = x.RechargeAmount, ActualReceivedAmount = x.ActualReceivedAmount.ToString("F2"), LifePayRefundStatus = x.LifePayRefundStatus, }).OrderByDescending(r => r.CreationTime).ToListAsync(); var i = 0; result.ForEach(s => { s.SerialNumber = ++i; s.ACOOLYStatusStr = s.ACOOLYStatus.GetDescription(); s.LifePayOrderTypeStr = s.LifePayOrderType.GetDescription(); s.RechargeAmountStr = s.RechargeAmount.ToString("F2"); s.ActualReceivedAmount = s.ActualReceivedAmount; s.LifePayRefundStatusStr = s.LifePayRefundStatus == LifePayRefundStatusEnum.无需退款 ? "" : s.LifePayRefundStatus.GetDescription(); s.PayAmountStr = s.PayAmount.ToString("F2"); s.LifePayTypeStr = s.LifePayType.GetDescription(); s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm); s.RefundApplyTimeStr = !s.RefundApplyTime.HasValue ? string.Empty : s.RefundApplyTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmm); }); return result; } public async Task GetLifePayOrderDetail(string orderNo) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); var channle = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == order.ChannelId); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == order.UserId); CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "用户不存在"); var orderpirce = await GetOrderPrice(order.RechargeAmount ?? 0, order.PayAmount ?? 0, order.PlatformRate ?? 0, order.ChannleRate ?? 0, order.ChannlesRakeRate ?? 0, order.PremiumRate ?? 0); var result = new LifePayOrderOutput() { UserName = user.Name, UserPhoneNumber = user.PhoneNumber, DiscountAmount = order.DiscountAmount ?? 0, FinishTime = order.FinishTime, Id = order.Id, OutOrderNo = order.OutOrderNo, LifePayChannle = channle.ChannlesName, Status = order.LifePayOrderStatus ?? 0, LifePayOrderType = order.LifePayOrderType, LifePayType = order.LifePayType, OrderNo = order.OrderNo, PayAmount = order.PayAmount ?? 0, RechargeAmount = order.RechargeAmount ?? 0, PayStatus = order.PayStatus ?? 0, 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.RechargeAmount, RefundPrice = order.RefundPrice, PlatformRate = order.PlatformRate, PlatformPrice = order.PlatformDeductionAmount, ElecBillUrl = order.ElecBillUrl.GetOssPath(), RefundElecBillUrl = order.RefundElecBillUrl.GetOssPath(), ChannleRate = order.ChannleRate, ChannlesRakeRate = order.ChannlesRakeRate, ChannlesRakePrice = orderpirce.ChannlesRakePrice, PremiumRate = order.PremiumRate, PremiumPrice = orderpirce.PremiumPrice, Profit = orderpirce.Profit, RefundOrderNo = order.RefundOrderNo, }; return result; } public async Task 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 ?? 0, FinishTime = order.FinishTime, Id = order.Id, OutOrderNo = order.OutOrderNo, LifePayChannle = channle.ChannlesName, Status = order.LifePayOrderStatus ?? 0, LifePayOrderType = order.LifePayOrderType, LifePayType = order.LifePayType, OrderNo = order.OrderNo, PayAmount = order.PayAmount ?? 0, RechargeAmount = order.RechargeAmount ?? 0, PayStatus = order.PayStatus ?? 0, 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, ActualReceivedAmount = order.ActualReceivedAmount, RefundPrice = order.RefundPrice, ElecBillUrl = order.ElecBillUrl.GetOssPath(), RefundElecBillUrl = order.RefundElecBillUrl.GetOssPath(), }; return result; } /// /// 获取我的订单分页数据 /// /// /// public async Task> GetUserLifePayOrderPage(QueryLifePayOrderListInput input) { if (!input.UserId.HasValue) { return new PageOutput(); } 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) .WhereIf(input.EndPayTime.HasValue, x => x.PayTime <= input.EndPayTime) .WhereIf(input.LifePayOrderStatus.HasValue, x => x.LifePayOrderStatus == input.LifePayOrderStatus.Value) .WhereIf(input.PayStatus.HasValue, x => x.PayStatus == input.PayStatus.Value) .WhereIf(input.UserId.HasValue, x => x.UserId == input.UserId.Value) .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayOrderType == input.LifePayOrderType) .Select(x => new UserLifePayOrderOutput { DiscountAmount = x.DiscountAmount ?? 0, FinishTime = x.FinishTime, Id = x.Id, LifePayOrderStatus = x.LifePayOrderStatus ?? 0, LifePayOrderType = x.LifePayOrderType, LifePayType = x.LifePayType, OrderNo = x.OrderNo, PayAmount = x.PayAmount ?? 0, RechargeAmount = x.RechargeAmount ?? 0, PayStatus = x.PayStatus ?? 0, PayTime = x.PayTime, OrderParamDetailJsonStr = x.OrderParamDetailJsonStr, RefundCredentialsImgUrl = x.RefundCredentialsImgUrl.GetOssPath(), CreationTime = x.CreationTime, RefundCheckRemark = x.RefundCheckRemark, RefundApplyRemark = x.RefundApplyRemark, RefundApplyTime = x.RefundApplyTime, RefundTime = x.RefundTime, ACOOLYOrderNo = x.ACOOLYOrderNo, LifePayRefundStatus = x.LifePayRefundStatus, ACOOLYStatus = x.ACOOLYStatus, }) .GetPageResult(input.PageModel); } public async Task GetUserLifePayOrderDetail(string orderNo) { var result = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo) .Select(x => new UserLifePayOrderOutput { DiscountAmount = x.DiscountAmount ?? 0, FinishTime = x.FinishTime, Id = x.Id, LifePayOrderStatus = x.LifePayOrderStatus?? 0 , LifePayOrderType = x.LifePayOrderType, LifePayType = x.LifePayType, OrderNo = x.OrderNo, PayAmount = x.PayAmount ?? 0, RechargeAmount = x.RechargeAmount ?? 0, PayStatus = x.PayStatus ?? 0, PayTime = x.PayTime, OrderParamDetailJsonStr = x.OrderParamDetailJsonStr, RefundCredentialsImgUrl = x.RefundCredentialsImgUrl.GetOssPath(), CreationTime = x.CreationTime, RefundCheckRemark = x.RefundCheckRemark, RefundApplyRemark = x.RefundApplyRemark, RefundTime = x.RefundTime, ACOOLYOrderNo = x.ACOOLYOrderNo, }) .FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(result == null, "订单不存在"); return result; } /// /// 根据订单号获取支付状态 /// /// /// public async Task GetPayStatusByOrderNo(string orderNo) { return await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo) .Select(x => x.PayStatus ?? 0) .FirstOrDefaultAsync(); } public async Task> GetLifePayChannlesPage(PageInput input) { return await GetLifePayChannlesListFilter().GetPageResult(input.PageModel); } public async Task> GetLifePayChannlesAllList(QueryLifePayChannlesInput input) { return await GetLifePayChannlesListFilter().WhereIf(input.Status.HasValue,x => x.Status == input.Status).ToListAsync(); } public async Task GetLifePayChannlesDto(Guid id) { return await _lifePayChannlesRep.Where(x => x.Id == id).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, }).FirstOrDefaultAsync(); } public async Task GetLifePayChannlesDtoByNum(string channlesNum) { var result = await _lifePayChannlesRep.Where(x => x.ChannlesNum == channlesNum && x.Status == LifePayChannelsStatsEnum.启用).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, }).FirstOrDefaultAsync(); return result; } public async Task GetUserLifePayOrderRefund(Guid id) { var order = await _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository).Where(x => x.Id == id).Select(x => new UserLifePayOrderRefundOutput { Id = x.Id, OrderNo = x.OrderNo, RefundCheckRemark = x.RefundCheckRemark, RefundApplyRemark = x.RefundApplyRemark, LifePayOrderStatus = x.LifePayOrderStatus ?? 0, }).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "未找到订单信息"); return order; } public async Task> GetUserAccountList(QueryUserAccountListInput input) { if (!input.UserId.HasValue) { return new PageOutput(); } var result = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.IsDeleted == false) .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayType == input.LifePayOrderType) .OrderByDescending(x => x.CreationTime) .Select(x => new UserAccountOutput { Id = x.Id, LifePayType = x.LifePayType, Content = x.Content, CreationTime = x.CreationTime, Remark = x.Remark, Operators = x.Operators, Province = x.Province, City = x.City, ExtraProperties = x.ExtraProperties, }) .GetPageResult(input.PageModel); return result; } public async Task> GetUserAccountAllList(QueryUserAccountAllListInput input) { if (!input.UserId.HasValue) { return new List(); } var result = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.IsDeleted == false) .WhereIf(input.LifePayOrderType.HasValue, x => x.LifePayType == input.LifePayOrderType) .OrderByDescending(x => x.CreationTime) .Select(x => new UserAccountOutput { Id = x.Id, LifePayType = x.LifePayType, Content = x.Content, CreationTime = x.CreationTime, Remark = x.Remark, Operators = x.Operators, Province = x.Province, City = x.City, ExtraProperties = x.ExtraProperties, }).ToListAsync(); return result; } public async Task GetUserAccountDetail(Guid id) { var result = await _lifePayAccount.Where(x => x.Id == id) .OrderByDescending(x => x.CreationTime) .Select(x => new UserAccountOutput { Id = x.Id, LifePayType = x.LifePayType, Content = x.Content, CreationTime = x.CreationTime, Remark = x.Remark, Operators = x.Operators, Province = x.Province, City = x.City, ExtraProperties = x.ExtraProperties, }).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(result == null, "未找到户号信息"); return result; } public async Task> GetLifePayOrderPageExport(QueryLifePayOrderListInput input) { var result = await (await GetLifePayOrderListFilter(input)).Select(x => new LifePayOrderListTemplate { DiscountAmount = x.DiscountAmount, FinishTime = x.FinishTime, LifePayOrderStatus = x.LifePayOrderStatus, LifePayOrderType = x.LifePayOrderType, LifePayType = x.LifePayType, OrderNo = x.OrderNo, PayAmount = x.PayAmount, ActualRechargeAmount = x.RechargeAmount, PhoneNumber = x.PhoneNumber, RechargeAmount = x.RechargeAmount, OutOrderNo = x.OutOrderNo, PayStatus = x.PayStatus, PayTime = x.PayTime, ACOOLYOrderNo = x.ACOOLYOrderNo, CreationTime = x.CreationTime, LifePayRefundStatus = x.LifePayRefundStatus, ACOOLYStatus = x.ACOOLYStatus, //RefundApplyRemark = x.RefundApplyRemark, ChannelName = x.ChannelName, PlatformPrice = x.PlatformDeductionAmount.HasValue ? x.PlatformDeductionAmount.Value : 0.00m }).OrderByDescending(r => r.CreationTime).ToListAsync(); var i = 0; result.ForEach(s => { s.SerialNumber = ++i; s.LifePayOrderTypeStr = s.LifePayOrderType.GetDescription(); s.CreationTimeStr = s.CreationTime.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmmss); s.RechargeAmountStr = s.RechargeAmount.ToString("F2"); s.PayAmountStr = s.PayAmount.ToString("F2"); s.PayTimeStr = !s.PayTime.HasValue ? string.Empty : s.PayTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmmss); s.LifePayTypeStr = s.LifePayType.GetDescription(); s.PayStatusStr = s.PayStatus.GetDescription(); s.ActualRechargeAmountStr = s.ActualRechargeAmount.ToString("F2"); s.LifePayRefundStatusStr = s.LifePayRefundStatus == LifePayRefundStatusEnum.无需退款 ? "" : s.LifePayRefundStatus.GetDescription(); s.ACOOLYStatusStr = s.ACOOLYStatus.GetDescription(); s.LifePayOrderStatusStr = s.LifePayOrderStatus.GetDescription(); s.FinishTimeStr = !s.FinishTime.HasValue ? string.Empty : s.FinishTime.Value.ToString(LifePaymentConstant.DateTimeFormatStr.yyyyMMddHHmmss); }); return result; } public async Task 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 = order.OutOrderNo }; 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 ""; } } /// /// 查询支付宝支付订单信息 /// /// /// public async Task QueryAlipayTrade(OrderInQuiryInput input) { var result = await _aliPayApi.OrderInQuiry(input); return result; } /// /// 查询支付宝退款订单信息 /// /// /// public async Task QueryAlipayTradeRefund(OrderInQuiryInput input) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == input.OutTradeNo || x.RefundOrderNo == input.OutRefundNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "未找到订单信息"); input.OutTradeNo = order.OrderNo; input.OutRefundNo = order.RefundOrderNo; var result = await _aliPayApi.QueryAlipayTradeRefund(input); if (result.Code == AlipayResultCode.Success && result.RefundStatus == AlipayRefundStatus.Success) { order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; order.LifePayRefundStatus = LifePayRefundStatusEnum.已退款; await _lifePayOrderService.AddLifePayExpensesReceipts(new AddLifePayExpensesReceiptsInput() { OrderNo = order.RefundOrderNo, OutOrderNo = result.TradeNo, LifePayType = LifePayTypeEnum.AliPay, ExpensesReceiptsType = ExpensesReceiptsTypeEnum.Receipts }); } return result; } /// /// 查询微信退款订单信息 /// /// /// public async Task WxPayDomesticRefundsQuery(string outTradeNo) { var order = await _lifePayOrderRepository.Where(x => x.RefundOrderNo == outTradeNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "未找到订单信息"); var result = await _wxPayApi.WxPayDomesticRefundsQuery(outTradeNo); if (order.LifePayRefundStatus != LifePayRefundStatusEnum.已退款 && result.Code == WxpayResultCode.Success && result.Status == WxPayRefundStatus.退款成功) { order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; order.LifePayRefundStatus = LifePayRefundStatusEnum.已退款; await _lifePayOrderService.AddLifePayExpensesReceipts(new AddLifePayExpensesReceiptsInput() { OrderNo = order.OrderNo, OutRefundNo = order.RefundOrderNo, OutOrderNo = order.OutOrderNo, LifePayType = LifePayTypeEnum.AliPay, ExpensesReceiptsType = ExpensesReceiptsTypeEnum.Receipts }); } return result; } /// /// 查询微信订单信息 /// /// /// public async Task WxPayTradeQuery(string outTradeNo) { return await _wxPayApi.WxPayTradeQuery(outTradeNo); } #endregion #region 操作 /// /// 创建生活缴费话费订单 /// /// /// public async Task CreateLifePayPhoneOrder(CreateLifePayOrderInput input) { CheckExtensions.IfTrueThrowUserFriendlyException(input.ProductData.IspCode == "dianxin" && string.IsNullOrEmpty(input.ProductData.Name), "电信手机号必填机主名"); var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == input.UserId); CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "用户不存在,请先登录再操作"); var channle = await GetLifePayChannlesDtoByNum(input.ChannelId); CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "渠道不存在"); var repeatOrder = await _lifePayOrderRepository.Where(x => x.LifePayOrderType == LifePayOrderTypeEnum.PhoneOrder && x.PayStatus == LifePayStatusEnum.已支付 && x.LifePayOrderStatus == LifePayOrderStatusEnum.充值中 && x.OrderParamDetailJsonStr.Contains(input.ProductData.Phone)).ToListAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(repeatOrder.Count() > 0, "您有同户号订单正在充值中,请勿重复充值"); //var rate = await GetRate(); //CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "未配置折扣"); var rate = await GetLifePayRate(channle, LifePayRateTypeEnum.默认话费折扣); var amount = CalculateAmount(input.ProductData.ParValue, rate); var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); var orderInput = new CreateLifePayOrderInput { OrderNo = channle.ChannlesNum + CreateOrderNo(), LifePayOrderStatus = LifePayOrderStatusEnum.充值中, LifePayOrderType = LifePayOrderTypeEnum.PhoneOrder, //LifePayType = input.LifePayType, OrderParamDetailJsonStr = JsonConvert.SerializeObject(input.ProductData), UserId = user.Id, PayStatus = LifePayStatusEnum.未支付, PhoneNumber = user.PhoneNumber, PayAmount = amount.PayAmont, DiscountAmount = amount.DiscountAmount, RechargeAmount = amount.RechargeAmount, ChannelId = channle.ChannlesNum, PlatformRate = platformRate.Rate, PlatformDeductionAmount = amount.RechargeAmount * platformRate.Rate / 100, ChannleRate = rate, ChannlesRakeRate = channle.ChannlesRakeRate, //ChannlesRakePrice = amount.RechargeAmount * (channle.ChannlesRate - platformRate.Rate) / 100 * channle.ChannlesRakeRate / 100 }; await CreateLifePayOrder(orderInput); var result = new CreateLifePayOrderOutput() { OrderNo = orderInput.OrderNo, }; return result; } /// /// 创建生活缴费电费订单 /// /// /// public async Task CreateLifePayElectricOrder(CreateLifePayOrderInput input) { var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == input.UserId); CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "用户不存在,请先登录再操作"); var channle = await GetLifePayChannlesDtoByNum(input.ChannelId); CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "渠道不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(channle.Status == LifePayChannelsStatsEnum.禁用, "渠道已被禁用"); //var rate = await GetRate(); //CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "未配置折扣"); var repeatOrder = await _lifePayOrderRepository.Where(x => x.LifePayOrderType == LifePayOrderTypeEnum.ElectricOrder && x.PayStatus == LifePayStatusEnum.已支付 && x.LifePayOrderStatus == LifePayOrderStatusEnum.充值中 && x.OrderParamDetailJsonStr.Contains(input.ProductData.ElectricType) && x.OrderParamDetailJsonStr.Contains(input.ProductData.ElectricAccount)).ToListAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(repeatOrder.Count() > 0, "您有同户号订单正在充值中,请勿重复充值"); var rate = await GetLifePayRate(channle, LifePayRateTypeEnum.默认电费折扣); var amount = CalculateAmount(input.ProductData.ParValue, rate); var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); var orderInput = new CreateLifePayOrderInput { OrderNo = channle.ChannlesNum + CreateOrderNo(), LifePayOrderStatus = LifePayOrderStatusEnum.充值中, LifePayOrderType = LifePayOrderTypeEnum.ElectricOrder, // LifePayType = input.LifePayType, OrderParamDetailJsonStr = JsonConvert.SerializeObject(input.ProductData), UserId = user.Id, PayStatus = LifePayStatusEnum.未支付, PhoneNumber = user.PhoneNumber, PayAmount = amount.PayAmont, DiscountAmount = amount.DiscountAmount, RechargeAmount = amount.RechargeAmount, ChannelId = channle.ChannlesNum, PlatformRate = platformRate.Rate, ChannleRate = rate, ChannlesRakeRate = channle.ChannlesRakeRate, }; await CreateLifePayOrder(orderInput); var result = new CreateLifePayOrderOutput() { OrderNo = orderInput.OrderNo, }; return result; } /// /// 创建生活缴费燃气订单 /// /// /// public async Task CreateLifePayGasOrder(CreateLifePayOrderInput input) { var user = await _lifePayUserRepository.FirstOrDefaultAsync(x => x.Id == input.UserId); CheckExtensions.IfTrueThrowUserFriendlyException(user == null, "用户不存在,请先登录再操作"); var channle = await GetLifePayChannlesDtoByNum(input.ChannelId); CheckExtensions.IfTrueThrowUserFriendlyException(channle == null, "渠道不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(channle.Status == LifePayChannelsStatsEnum.禁用, "渠道已被禁用"); //var rate = await GetRate(); //CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "未配置折扣"); var repeatOrder = await _lifePayOrderRepository.Where(x => x.LifePayOrderType == LifePayOrderTypeEnum.GasOrder && x.PayStatus == LifePayStatusEnum.已支付 && x.LifePayOrderStatus == LifePayOrderStatusEnum.充值中 && x.OrderParamDetailJsonStr.Contains(input.ProductData.GasOrgType) && x.OrderParamDetailJsonStr.Contains(input.ProductData.GasAccount)).ToListAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(repeatOrder.Count() > 0, "您有同户号订单正在充值中,请勿重复充值"); var rate = await GetLifePayRate(channle, LifePayRateTypeEnum.默认燃气折扣); var amount = CalculateAmount(input.ProductData.ParValue, rate); var platformRate = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == LifePayRateTypeEnum.供应商折扣价); var orderInput = new CreateLifePayOrderInput { OrderNo = channle.ChannlesNum + CreateOrderNo(), LifePayOrderStatus = LifePayOrderStatusEnum.充值中, LifePayOrderType = LifePayOrderTypeEnum.GasOrder, // LifePayType = input.LifePayType, OrderParamDetailJsonStr = JsonConvert.SerializeObject(input.ProductData), UserId = user.Id, PayStatus = LifePayStatusEnum.未支付, PhoneNumber = user.PhoneNumber, PayAmount = amount.PayAmont, DiscountAmount = amount.DiscountAmount, RechargeAmount = amount.RechargeAmount, ChannelId = channle.ChannlesNum, PlatformRate = platformRate.Rate, ChannleRate = rate, ChannlesRakeRate = channle.ChannlesRakeRate, }; await CreateLifePayOrder(orderInput); var result = new CreateLifePayOrderOutput() { OrderNo = orderInput.OrderNo, }; return result; } /// /// 设置生活缴费支付类型 /// /// /// public async Task SetLifePayOrderPayType(SetLifePayOrderPayTypeInput input, string ip) { var res = await SetPayType(input.OrderNo, input.LifePayType, ip); #if DEBUG //var payUrl = await GetPayQRCode(order.LifePayType.Value, order.OrderNo, desc, 0.01m, ip, input.H5Type); var payUrl = await GetPayQRCode(res.LifePayType, res.OrderNo, res.Desc, res.PayAmount, ip, input.H5Type); #else //var payUrl = await GetPayQRCode(res.LifePayType, res.OrderNo, res.Desc, 0.01m, ip, input.H5Type); var payUrl = await GetPayQRCode(res.LifePayType, res.OrderNo, res.Desc, res.PayAmount, ip, input.H5Type); #endif return payUrl; } /// /// 获取微信支付的JSAPI /// /// /// public async Task GetPayOrderForJsAPI(GetPayOrderForJsAPIInput input, string ip) { var res = await SetPayType(input.OrderNo, input.LifePayType, ip); var result = await PayTransactionsJsAPI(input.OpenId, input.PayAppId, input.Attach, res.PayAmount, input.OrderNo, res.Desc); return result; } /// /// 修改实际到账金额 /// /// /// public async Task UpdateLifePayOrderActualReceivedAmount(UpdateLifePayOrderInput input) { var order = await _lifePayOrderRepository.Where(x => x.Id == input.Id).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(order.ACOOLYStatus != ACOOLYStatusEnum.部分充值成功, "该订单无法修改到账金额"); order.ActualReceivedAmount = input.ActualReceivedAmount; await _lifePayOrderRepository.UpdateAsync(order); return Constant.SUCCESS; } /// /// 创建生活缴费订单 /// /// /// public async Task CreateLifePayOrder(CreateLifePayOrderInput input) { var entity = ObjectMapper.Map(input); await _lifePayOrderRepository.InsertAsync(entity); } /// /// 创建ACOOLY话费订单 /// /// /// public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYPhoneOrder(LifePhoneData input, string orderNo) { var requestInput = new ConfirmPhoneOrderRequestInput() { IspCode = input.IspCode, ParValue = input.ParValue, Phone = input.Phone, OutOrderNo = orderNo, Name = input.Name }; var result = await _aCOOLYManager.ConfirmPhoneOrder(requestInput); #if DEBUG _logger.LogInformation($"CreateACOOLYPhoneOrder:{JsonConvert.SerializeObject(result)}"); #endif CheckExtensions.IfTrueThrowUserFriendlyException(!result.Success || (result.Code != ACOOLYConstant.Code.SUCCESS && result.Code != ACOOLYConstant.Code.PROCESSING), result.Message); return (result.Code, requestInput.RequestNo, result.PhoneChargeOrder.BusiOrderNo); } /// /// 创建ACOOLY电费订单 /// /// /// public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYElectricOrder(LifeElectricData input, string orderNo) { var requestInput = new ConfirmElectricOrderRequestInput() { City = input.City, ElectricAccount = input.ElectricAccount, ElectricAccountType = input.ElectricAccountType, ElectricType = input.ElectricType, ParValue = input.ParValue, Province = input.Province, SixID = input.SixID, OutOrderNo = orderNo }; var result = await _aCOOLYManager.ConfirmElectricOrder(requestInput); _logger.LogInformation($"CreateACOOLYElectricOrder:{JsonConvert.SerializeObject(result)}"); CheckExtensions.IfTrueThrowUserFriendlyException(!result.Success || (result.Code != ACOOLYConstant.Code.SUCCESS && result.Code != ACOOLYConstant.Code.PROCESSING), result.Message); return (result.Code, requestInput.RequestNo, result.ElectricChargeOrder.BusiOrderNo); } /// /// 创建ACOOLY燃气订单 /// /// /// public async Task<(string Code, string RequestNo, string ACOOLYOrderNo)> CreateACOOLYGasOrder(LifeGasData input, string orderNo) { var requestInput = new ConfirmGasOrderRequestInput() { GasOrgType = input.GasOrgType, ParValue = input.ParValue, GasAccount = input.GasAccount, OutOrderNo = orderNo, AreaName = input.Province + "-" + input.City }; var result = await _aCOOLYManager.ConfirmGasOrder(requestInput); #if DEBUG _logger.LogInformation($"CreateACOOLYGasOrder:{JsonConvert.SerializeObject(result)}"); #endif CheckExtensions.IfTrueThrowUserFriendlyException(!result.Success || (result.Code != ACOOLYConstant.Code.SUCCESS && result.Code != ACOOLYConstant.Code.PROCESSING), result.Message); return (result.Code, requestInput.RequestNo, result.GasChargeOrder.BusiOrderNo); } public async Task PayTransactionsJsAPI(string openid, string appId, string order_guid, decimal amount, string outTradeNo, string description) { string time_expire = DateTime.Now.AddMinutes(5).ToString("yyyy-MM-ddTHH:mm:ss") + "+08:00"; /// 订单失效时间 if (string.IsNullOrEmpty(appId)) { appId = _wxPayOptions.AppID; } ModelMiniPayRequest req = new ModelMiniPayRequest { TimeExpire = time_expire, Appid = appId, Mchid = _wxPayOptions.Mchid, Attach = order_guid, Description = description, OutTradeNo = outTradeNo, Amount = new Model_MiniPay_Amount { Total = Convert.ToInt32(100 * amount), Currency = "CNY" }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxRechargeNotifySectionUrl}", Payer = new Model_MiniPay_Payer { 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) { string paytext = BuildSignByPay(appId, timestamp, nonce, package); string paysign = _wxPayApi.GeneratePaySignByKey(paytext); info.Timestamp = timestamp.ToString(); info.NonceStr = nonce; info.Package = package; info.SignType = "RSA"; info.PaySign = paysign; info.TimeExpire = time_expire; } return info; } /// /// 构造签名串 /// /// 小程序的AppID /// 时间戳 /// 随机字符串 /// package值 /// 签名串 public string BuildSignByPay(string appId, long timestamp, string nonceStr, string package) { string format = $"{appId}\n{timestamp}\n{nonceStr}\n{package}\n"; return format; } /// /// 支付成功回调处理 /// /// /// /// public async Task LifePaySuccessHandler(string orderNo, string outOrderNo) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.PayStatus == LifePayStatusEnum.已支付) { return; } order.PayStatus = LifePayStatusEnum.已支付; order.PayTime = DateTime.Now; order.OutOrderNo = outOrderNo; try { var result = (Code: "Fail", RequestNo: "", ACOOLYOrderNo: ""); switch (order.LifePayOrderType) { case LifePayOrderTypeEnum.PhoneOrder: result = await CreateACOOLYPhoneOrder(JsonConvert.DeserializeObject(order.OrderParamDetailJsonStr), order.OrderNo); break; case LifePayOrderTypeEnum.ElectricOrder: result = await CreateACOOLYElectricOrder(JsonConvert.DeserializeObject(order.OrderParamDetailJsonStr), order.OrderNo); break; case LifePayOrderTypeEnum.GasOrder: result = await CreateACOOLYGasOrder(JsonConvert.DeserializeObject(order.OrderParamDetailJsonStr), order.OrderNo); break; default: break; } order.LifePayRefundStatus = LifePayRefundStatusEnum.无需退款; order.LifePayOrderStatus = LifePayOrderStatusEnum.充值中; //SetOrderStatus(order, result.Code); order.OutRequestNo = result.RequestNo.IsNullOrEmpty() ? null : result.RequestNo; order.ACOOLYOrderNo = result.ACOOLYOrderNo; order.ACOOLYStatus = ACOOLYStatusEnum.充值中; /// 创建生活缴费消费记录 await _lifePayOrderService.CreatLifePayConsumption(ACOOLYStatusEnum.充值中, order.OrderNo, order.ACOOLYOrderNo, order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime); } catch (Exception ex) { _logger.LogError(ex, "处理生活缴费支付成功回调时异常"); order.LifePayOrderStatus = LifePayOrderStatusEnum.待退款; order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款; order.ACOOLYStatus = ACOOLYStatusEnum.充值失败; order.RefundApplyRemark = ex.Message; } _logger.LogError("生活缴费订单状态:" + order.LifePayOrderStatus.ToString()); await _lifePayOrderRepository.UpdateAsync(order); } public async Task LifePayRefundsHandler(string orderNo, LifePayRefundStatusEnum refundStatus) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); order.LifePayRefundStatus = refundStatus; switch (refundStatus) { case LifePayRefundStatusEnum.已退款: order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; order.LifePayRefundStatus = LifePayRefundStatusEnum.已退款; break; case LifePayRefundStatusEnum.退款中: order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; order.LifePayRefundStatus = LifePayRefundStatusEnum.退款中; break; default: break; } } /// /// ACOOLYO订单通知处理 /// /// /// /// public async Task ACOOLYOrderNotifyHandler(string orderNo, string acoolyOrderNo, LifePayOrderStatusEnum status, ACOOLYStatusEnum acoolyStatus, decimal payAmount, string refundApplyRemark) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.LifePayOrderStatus >= LifePayOrderStatusEnum.已完成) { return; } order.PlatformDeductionAmount = payAmount; if (acoolyOrderNo.IsNotNullOrEmpty()) { order.ACOOLYOrderNo = acoolyOrderNo; } if (status == LifePayOrderStatusEnum.待退款) { order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款; } if (refundApplyRemark.IsNotNullOrEmpty()) { order.RefundApplyRemark = refundApplyRemark; } order.LifePayOrderStatus = status; order.ACOOLYStatus = acoolyStatus; order.FinishTime = DateTime.Now; await _lifePayOrderRepository.UpdateAsync(order); if (order.LifePayOrderStatus == LifePayOrderStatusEnum.已完成) { ///结算渠道佣金 /// 毛利 var grossProfit = order.RechargeAmount * (order.ChannleRate - order.PlatformRate) / 100; /// 渠道佣金 ((充值面额 * 渠道折扣比例)-(充值面额 * 平台折扣比例))* 佣金比例 var channlesRakePrice = grossProfit * (order.ChannlesRakeRate) / 100; if (channlesRakePrice.HasValue) { LifePayChannlesRake lifePayChannlesRake = new LifePayChannlesRake() { OrderNo = order.OrderNo, PayAmount = order.RechargeAmount ?? 0, ChannlesRakeRate = order.ChannlesRakeRate ?? 0, ChannlesRakePrice = channlesRakePrice ?? 0, FinishTime = order.FinishTime.Value, ChannelId = order.ChannelId, }; await _lifePayChannlesRakeRepository.InsertAsync(lifePayChannlesRake); } } /// 创建生活缴费消费记录 await _lifePayOrderService.CreatLifePayConsumption(acoolyStatus, order.OrderNo, order.ACOOLYOrderNo, order.PlatformDeductionAmount ?? 0, order.ChannelId, order.CreationTime, order.FinishTime); } /// /// 退款生活缴费订单 /// /// /// /// public async Task RefundLifePayOrder(RefundLifePayOrderInput input) { var order = await _lifePayOrderRepository.FirstOrDefaultAsync(x => x.Id == input.Id); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.LifePayRefundStatus == LifePayRefundStatusEnum.已退款) { return; } if (input.RefundPrice > order.PayAmount) { throw new UserFriendlyException("退款的金额不能大于实付金额"); } if (input.LifePayRefundType == LifePayRefundTypeEnum.全额退款) { input.RefundPrice = order.PayAmount ?? 0; } if (order.LifePayOrderStatus != LifePayOrderStatusEnum.待退款 || order.PayStatus != LifePayStatusEnum.已支付 || order.LifePayRefundStatus != LifePayRefundStatusEnum.待退款) { throw new UserFriendlyException("当前订单状态无法退款"); } var outRefundNo = order.ChannelId + CreateRefundOrderNo(); switch (order.LifePayType) { case LifePayTypeEnum.WxPay: var wxRefundResult = await WxPayDomesticRefunds(order.OrderNo, outRefundNo, order.RefundApplyRemark, Convert.ToInt32(input.RefundPrice * 100), Convert.ToInt32(order.PayAmount * 100)); if (wxRefundResult.Status == WxpayRefundResultStatus.SUCCESS) { order.RefundOrderNo = outRefundNo; order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; order.LifePayRefundStatus = LifePayRefundStatusEnum.退款中; } else if (wxRefundResult.Status == WxpayRefundResultStatus.PROCESSING) { order.RefundOrderNo = outRefundNo; order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; order.LifePayRefundStatus = LifePayRefundStatusEnum.退款中; } else if (wxRefundResult.Status.IsNullOrEmpty() && wxRefundResult.Message == WxpayRefundResultMessage.FullRefund) { order.LifePayOrderStatus = LifePayOrderStatusEnum.已退款; order.LifePayRefundStatus = LifePayRefundStatusEnum.已退款; } else { throw new UserFriendlyException("退款失败:" + wxRefundResult.Message); } break; case LifePayTypeEnum.AliPay: var aliRefundResult = await AliTradeRefund(new AlipayTradeRefundRequest() { OutTradeNo = order.OrderNo, OutRefundNo = outRefundNo, RefundAmount = input.RefundPrice.ToString() }); if (aliRefundResult.Code != AlipayResultCode.Success) { throw new UserFriendlyException("退款失败:" + aliRefundResult.SubMsg); } order.RefundOrderNo = outRefundNo; order.LifePayOrderStatus = LifePayOrderStatusEnum.退款中; order.LifePayRefundStatus = LifePayRefundStatusEnum.退款中; break; default: throw new UserFriendlyException("退款失败"); } order.RefundCredentialsImgUrl = input.RefundCredentialsImgUrl; order.RefundCheckRemark = input.RefundCheckRemark; order.RefundTime = DateTime.Now; order.RefundCheckUserId = CurrentUser.Id; order.RefundPrice = input.RefundPrice; //await _lifePayOrderRepository.UpdateAsync(order); #region 记录日志 await LifePayOrderHistory("退款", "退款", order.Id, (int)OperateHistoryTypeEnum.LifePayRefund); #endregion } /// /// 用户发起生活缴费退款 /// /// /// /// public async Task RefundUserLifePayOrder(RefundUserLifePayOrderInput input) { var order = await _lifePayOrderRepository.FirstOrDefaultAsync(x => x.Id == input.Id); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.UserId != input.UserId) { throw new UserFriendlyException("非用户本人退款"); } if (order.LifePayRefundStatus == LifePayRefundStatusEnum.已退款) { return; } if (order.PayStatus == LifePayStatusEnum.已支付 && order.LifePayOrderStatus != LifePayOrderStatusEnum.已完成 && order.LifePayOrderStatus != LifePayOrderStatusEnum.待退款 && order.LifePayOrderStatus != LifePayOrderStatusEnum.已退款) { order.LifePayOrderStatus = LifePayOrderStatusEnum.待退款; order.LifePayRefundStatus = LifePayRefundStatusEnum.待退款; order.RefundApplyRemark = input.RefundApplyRemark; order.RefundApplyTime = DateTime.Now; await _lifePayOrderRepository.UpdateAsync(order); } else if (order.LifePayOrderStatus == LifePayOrderStatusEnum.待退款 || order.LifePayRefundStatus == LifePayRefundStatusEnum.待退款 || order.LifePayOrderStatus == LifePayOrderStatusEnum.退款中 || order.LifePayRefundStatus == LifePayRefundStatusEnum.退款中 || order.LifePayOrderStatus == LifePayOrderStatusEnum.已退款 || order.LifePayRefundStatus == LifePayRefundStatusEnum.已退款) { throw new UserFriendlyException("当前订单无法重复申请退款"); } else { throw new UserFriendlyException("当前订单状态无法申请退款"); } } /// /// 微信退款 /// /// /// /// /// /// /// public async Task 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 AliTradeRefund(AlipayTradeRefundRequest input) { return await _aliPayApi.TradeRefund(input); } public async Task 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) .FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(userAccount == null, "户号不存在"); var repeatAccountContent = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.LifePayType == input.LifePayType && x.Content == input.Content && x.Id != input.Id && x.IsDeleted == false) .FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(repeatAccountContent != null, "户号已存在"); userAccount.LifePayType = input.LifePayType; userAccount.Content = input.Content; userAccount.Province = input.Province; userAccount.City = input.City; userAccount.Remark = input.Remark; userAccount.Operators = input.Operators; userAccount.ExtraProperties = input.ExtraProperties; } else { var repeatAccountContent = await _lifePayAccount.Where(x => x.UserId == input.UserId && x.LifePayType == input.LifePayType && x.Content == input.Content && x.IsDeleted == false) .FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(repeatAccountContent != null, "户号已存在"); var userAccount = new LifePayAccount { Id = Guid.NewGuid(), UserId = input.UserId, Content = input.Content, Province = input.Province, LifePayType = input.LifePayType, City = input.City, Remark = input.Remark, Operators = input.Operators, ExtraProperties = input.ExtraProperties, }; await _lifePayAccount.InsertAsync(userAccount); } if (input.LifePayType == LifePayOrderTypeEnum.PhoneOrder || input.LifePayType == LifePayOrderTypeEnum.ElectricOrder) { var extraProperties = JsonConvert.DeserializeObject(input.ExtraProperties); if (!string.IsNullOrEmpty(extraProperties.Name) && extraProperties.Phone == user.PhoneNumber) { user.Name = extraProperties.Name; } } return Constant.SUCCESS; } /// /// 用户删除户号信息 /// /// /// public async Task DeleteUserAccount(Guid id) { var userAccount = await _lifePayAccount.Where(x => x.Id == id) .FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(userAccount == null, "户号不存在"); userAccount.DeleterId = userAccount.UserId; userAccount.DeletionTime = DateTime.Now; userAccount.IsDeleted = true; return Constant.SUCCESS; } /// /// 退款驳回 /// /// /// /// public async Task RejectRefundLifePayOrder(RefundLifePayOrderInput input) { var order = await _lifePayOrderRepository.FirstOrDefaultAsync(x => x.Id == input.Id); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); if (order.LifePayRefundStatus == LifePayRefundStatusEnum.已退款) { return; } if (order.LifePayOrderStatus == LifePayOrderStatusEnum.待退款 || order.LifePayRefundStatus == LifePayRefundStatusEnum.待退款) { if (order.ACOOLYStatus == ACOOLYStatusEnum.已完成 || order.ACOOLYStatus == ACOOLYStatusEnum.充值成功 || order.ACOOLYStatus == ACOOLYStatusEnum.部分充值成功) { order.LifePayOrderStatus = LifePayOrderStatusEnum.已完成; } order.RefundCheckRemark = input.RefundCheckRemark; order.RefundCheckUserId = CurrentUser.Id; order.LifePayRefundStatus = LifePayRefundStatusEnum.退款驳回; await _lifePayOrderRepository.UpdateAsync(order); #region 记录日志 await LifePayOrderHistory("退款驳回", "退款", order.Id, (int)OperateHistoryTypeEnum.LifePayRefund); #endregion } else { throw new UserFriendlyException("当前订单状态无法退款"); } } public async Task CreateEditPayChannels(CreateEditPayChannelsInput input) { if (input.Id.HasValue) { var dto = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.Id == input.Id.Value); CheckExtensions.IfTrueThrowUserFriendlyException(dto == null, "未获取到渠道折扣数据"); 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; #region 记录日志 await LifePayOrderHistory("渠道管理", "编辑", input.Id.Value, TableType.LifePayChannles); #endregion } else { CheckExtensions.IfTrueThrowUserFriendlyException(input.ChannlesRate < 0.01m, "渠道折扣设置错误"); input.Id = Guid.NewGuid(); var entity = ObjectMapper.Map(input); await _lifePayChannlesRep.InsertAsync(entity); #region 记录日志 await LifePayOrderHistory("渠道管理", "新增", input.Id.Value, TableType.LifePayChannles); #endregion } } public async Task SetLifePayChannelsStatus(Guid id, LifePayChannelsStatsEnum status) { await _lifePayChannlesRep.Where(r => r.Id == id).UpdateAsync(r => new LifePayChannles { Status = status, }); #region 记录日志 await LifePayOrderHistory("渠道管理", status.GetDescription(), id, TableType.LifePayChannles); #endregion } public async Task CheckChannelsStatus(string channlesId) { var dto = await _lifePayChannlesRep.FirstOrDefaultAsync(r => r.ChannlesNum == channlesId); CheckExtensions.IfTrueThrowUserFriendlyException(dto == null, "当前渠道商不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(dto.Status == LifePayChannelsStatsEnum.禁用, "当前渠道商已禁用"); return true; } public async Task CreateEditLifePayRate(List input) { CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate <= 0).Any(), "折扣不得小于等于0"); var baseRate = input.FirstOrDefault(r => r.RateType == LifePayRateTypeEnum.供应商折扣价)?.Rate; var listData = new List(); foreach (var item in input) { CheckExtensions.IfTrueThrowUserFriendlyException(item.Rate < (baseRate ?? 0), "折扣不得小于供应商折扣"); var tmpDto = await _lifePayRateRepository.FirstOrDefaultAsync(r => r.RateType == item.RateType); if (tmpDto != null) { tmpDto.Rate = item.Rate; } else { listData.Add(new LifePayRate { CreationTime = DateTime.Now, Rate = item.Rate, RateType = item.RateType, Id = Guid.NewGuid(), }); } } if (listData.Any()) { await _lifePayRateRepository.InsertManyAsync(listData); } } public async Task CreateEditLifePayPremium(List input) { CheckExtensions.IfTrueThrowUserFriendlyException(input.Where(r => r.Rate < 0).Any(), "折扣不得小于0"); var listData = new List(); 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(); 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 私有 private string CreateOrderNo() { 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) { if (_initSettingOptions.OpenTheOnePennyTest) { /// 1分钱支付 decimal payAmount = 0.01m; CheckExtensions.IfTrueThrowUserFriendlyException(payAmount < 0.01m, "支付金额错误"); return (payAmount, amount - payAmount, amount); } else { /// 正常支付 var payAmount = decimal.Round(amount * rate / 100, 2, MidpointRounding.AwayFromZero); return (payAmount, amount - payAmount, amount); } } private void SetOrderStatus(LifePayOrder order, string code) { switch (code) { case ACOOLYConstant.Code.SUCCESS: order.LifePayOrderStatus = LifePayOrderStatusEnum.已完成; order.FinishTime = DateTime.Now; break; case ACOOLYConstant.Code.PROCESSING: order.LifePayOrderStatus = LifePayOrderStatusEnum.充值中; break; default: break; } } /// /// 记录相关的操作历史 /// /// /// private async Task PublishLifePayOrderHistoryEvent(string operateContent, string operateName, Guid relationId, int? tableType = TableType.LifePayOrder) { var recordEto = new RecordOperateHistoryEto { CreatorName = CurrentUser.Name, OperateContent = operateContent, OperateName = operateName, RelationId = relationId, TableType = tableType }; 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); } /// /// 获取支付二维码 /// /// /// /// /// /// /// public async Task GetPayQRCode(LifePayTypeEnum payType, string outTradeNo, string description, decimal amount, string ip, string h5Type) { var codeUrl = string.Empty; switch (payType) { case LifePayTypeEnum.AliPay: codeUrl = await GetAliPayQRCode(outTradeNo, description, amount); break; case LifePayTypeEnum.WxPay: codeUrl = await GetWxPayQRCode(outTradeNo, description, amount); //native // codeUrl = await GetWxPayH5Url(outTradeNo, description, amount, ip, h5Type); //h5 break; default: throw new UserFriendlyException(string.Format(CustomeErrorMessage.NotImplementedWhenSometing, "获取支付二维码")); } return codeUrl; } /// /// 获取微信支付二维码 /// /// /// /// /// /// private async Task GetWxPayQRCode(string outTradeNo, string description, decimal amount) { CheckExtensions.IfTrueThrowUserFriendlyException(amount <= 0, CustomeErrorMessage.SometingMustSometing, "获取支付二维码时金额", "大于0"); var res = await _wxPayApi.PayTransactionsNative(new PayTransactionsNativeInput { Appid = _wxPayOptions.AppID, Mchid = _wxPayOptions.Mchid, Description = description, OutTradeNo = outTradeNo, Amount = new PayAmount { Total = Convert.ToInt32(100 * amount), }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxRechargeNotifySectionUrl}", }); if (res == null || res.CodeUrl.IsNullOrEmpty()) { _logger.LogError($"获取微信支付二维码异常:{(res == null ? "返回参数为空" : $"{res.Code} --{res.Message}")}"); throw new UserFriendlyException(string.Format(CustomeErrorMessage.SometingError, "获取支付二维码时")); } return res.CodeUrl; } /// /// 获取微信支付二维码 /// /// /// /// /// /// private async Task GetWxPayH5Url(string outTradeNo, string description, decimal amount, string ip, string h5Type) { CheckExtensions.IfTrueThrowUserFriendlyException(amount <= 0, CustomeErrorMessage.SometingMustSometing, "获取支付二维码时金额", "大于0"); var res = await _wxPayApi.PayTransactionsH5(new PayTransactionsNativeH5 { Appid = _wxPayOptions.AppID, Mchid = _wxPayOptions.Mchid, Description = description, OutTradeNo = outTradeNo, Amount = new PayAmount { Total = Convert.ToInt32(100 * amount), }, NotifyUrl = $"{_wxPayOptions.NotifyUrl}{LifePaymentConstant.WxRechargeNotifySectionUrl}", SceneInfo = new H5SceneInfo() { PayerClientIp = ip, H5Info = new H5Info() { Type = h5Type } } }); if (res == null || res.H5Url.IsNullOrEmpty()) { _logger.LogError($"获取微信支付Url异常:{(res == null ? "返回参数为空" : $"{res.Code} --{res.Message}")}"); throw new UserFriendlyException(string.Format(CustomeErrorMessage.SometingError, "获取支付Url时")); } return res.H5Url; } /// /// 获取支付宝二维码 /// /// /// /// /// /// private async Task GetAliPayQRCode(string outTradeNo, string description, decimal amount) { CheckExtensions.IfTrueThrowUserFriendlyException(amount < 0.01M, CustomeErrorMessage.SometingMustSometing, "获取支付二维码时金额", "大于0.01"); var res = await _aliPayApi.GetAliPayQRCode(new GetPayQrCodeInput { Subject = description, OutTradeNo = outTradeNo, TotalAmount = amount, }); if (res == null || res.QrCode.IsNullOrEmpty()) { _logger.LogError($"获取支付宝支付二维码异常:{(res == null ? "返回参数为空" : $"{res.Code} --{res.Msg}")}"); throw new UserFriendlyException(string.Format(CustomeErrorMessage.SometingError, "获取支付二维码时")); } return res.QrCode; } /// /// 构造待签名字符串 /// /// HTTP请求方法 /// API接口的相对路径 /// 时间戳(秒级) /// 随机字符串 /// 请求体的JSON字符串 /// 待签名字符串 public static string BuildSignByUniOrder(string method, string uri, long timestamp, string nonce, string body) { string message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n"; return message; } private async Task> GetLifePayOrderListFilter(QueryLifePayOrderListInput input) { var channles = await _lifePayChannlesRep.Where(x => x.ChannlesName.Contains(input.KeyWords)).Select(x => x.ChannlesNum).ToListAsync(); var result = (from a in _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) .WhereIf(input.LifePayType.HasValue, x => x.LifePayType == input.LifePayType) .WhereIf(input.EndPayTime.HasValue, x => x.PayTime <= input.EndPayTime) .WhereIf(input.LifePayOrderStatus.HasValue, x => x.LifePayOrderStatus == input.LifePayOrderStatus.Value) .WhereIf(input.PayStatus.HasValue, x => x.PayStatus == input.PayStatus.Value) .WhereIf(input.ACOOLYStatus.HasValue, x => x.ACOOLYStatus == input.ACOOLYStatus.Value) .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.OrderNo.Contains(input.KeyWords) || x.OutOrderNo.Contains(input.KeyWords) || x.ACOOLYOrderNo.Contains(input.KeyWords) || channles.Contains(x.ChannelId)) join b in _lifePayChannlesRep on a.ChannelId equals b.ChannlesNum into temp from b in temp.DefaultIfEmpty() select new LifePayOrderListOutput { DiscountAmount = a.DiscountAmount ?? 0, FinishTime = a.FinishTime, Id = a.Id, LifePayOrderStatus = a.LifePayOrderStatus ?? 0, LifePayOrderType = a.LifePayOrderType, LifePayType = a.LifePayType, OrderNo = a.OrderNo, PayAmount = a.PayAmount ?? 0, PhoneNumber = a.PhoneNumber, RechargeAmount = a.RechargeAmount ?? 0, UserId = a.UserId, OutOrderNo = a.OutOrderNo, PayStatus = a.PayStatus ?? 0, PayTime = a.PayTime, ACOOLYOrderNo = a.ACOOLYOrderNo, RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(), RefundPrice = a.RefundPrice, CreationTime = a.CreationTime, RefundCheckRemark = a.RefundCheckRemark, RefundApplyRemark = a.RefundApplyRemark, RefundTime = a.RefundTime, ChannelName = b.ChannlesName, ActualRechargeAmount = a.ActualRechargeAmount, PlatformDeductionAmount = a.PlatformDeductionAmount, ACOOLYStatus = a.ACOOLYStatus, LifePayRefundStatus = a.LifePayRefundStatus, }); return result; } private async Task> GetLifePayRefundOrderListFilter(QueryLifePayRefundOrderListInput input) { var result = (from a in _channelFilter.GetChannelLifePayOrderFilter(_lifePayOrderRepository) .Where(x => x.LifePayOrderStatus == LifePayOrderStatusEnum.待退款 || x.LifePayOrderStatus == LifePayOrderStatusEnum.已退款 || x.LifePayOrderStatus == LifePayOrderStatusEnum.退款中 || (x.LifePayRefundStatus > LifePayRefundStatusEnum.无需退款 && x.LifePayRefundStatus != LifePayRefundStatusEnum.退款驳回)) .WhereIf(input.BeginRefundTime.HasValue, x => x.RefundTime >= input.BeginRefundTime) .WhereIf(input.EndRefundTime.HasValue, x => x.RefundTime <= input.EndRefundTime) .WhereIf(input.BeginRefundApplyTime.HasValue, x => x.RefundApplyTime >= input.BeginRefundApplyTime) .WhereIf(input.LifePayType.HasValue, x => x.LifePayType == input.LifePayType) .WhereIf(input.EndRefundApplyTime.HasValue, x => x.RefundApplyTime <= input.EndRefundApplyTime) .WhereIf(input.LifePayOrderStatus.HasValue, x => x.LifePayOrderStatus == input.LifePayOrderStatus.Value) .WhereIf(input.ACOOLYStatus.HasValue, x => x.ACOOLYStatus == input.ACOOLYStatus.Value) .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.ChannlesNum into temp from b in temp.DefaultIfEmpty() select new LifePayOrderListOutput { DiscountAmount = a.DiscountAmount ?? 0, FinishTime = a.FinishTime, Id = a.Id, LifePayOrderStatus = a.LifePayOrderStatus ?? 0, LifePayOrderType = a.LifePayOrderType, LifePayType = a.LifePayType, OrderNo = a.OrderNo, PayAmount = a.PayAmount ?? 0, PhoneNumber = a.PhoneNumber, RechargeAmount = a.RechargeAmount ?? 0, UserId = a.UserId, OutOrderNo = a.OutOrderNo, PayStatus = a.PayStatus ?? 0, PayTime = a.PayTime, ACOOLYOrderNo = a.ACOOLYOrderNo, RefundCredentialsImgUrl = a.RefundCredentialsImgUrl.GetOssPath(), CreationTime = a.CreationTime, RefundCheckRemark = a.RefundCheckRemark, RefundApplyRemark = a.RefundApplyRemark, RefundApplyTime = a.RefundApplyTime, RefundTime = a.RefundTime, RefundOrderNo = a.RefundOrderNo, RefundPrice = a.RefundPrice, ChannelName = b.ChannlesName, ActualRechargeAmount = a.ActualRechargeAmount, PlatformDeductionAmount = a.PlatformDeductionAmount, ACOOLYStatus = a.ACOOLYStatus, LifePayRefundStatus = a.LifePayRefundStatus, ActualReceivedAmount = a.ActualReceivedAmount.HasValue ? a.ActualReceivedAmount.Value : 0 }); return result; } private IQueryable 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, }); } public async Task GetOrderPrice(decimal price, decimal priceAmount, decimal platformRate, decimal channleRate, decimal channlesRakeRate, decimal premiumRate) { /// 毛利 var grossProfit = price * (channleRate - platformRate) / 100; /// 平台扣款金额 充值面额 * 平台折扣比例 var platformPrice = price * platformRate / 100; /// 手续费 var premiumPrice = priceAmount * (premiumRate) / 100; /// 渠道佣金 ((充值面额 * 渠道折扣比例)-(充值面额 * 平台折扣比例))* 佣金比例 var channlesRakePrice = grossProfit * (channlesRakeRate) / 100; /// 利润 var profit = grossProfit - channlesRakePrice - premiumPrice; return new OrderPriceReturn() { PlatformPrice = platformPrice, PremiumPrice = premiumPrice, ChannlesRakePrice = channlesRakePrice, Profit = profit }; } public async Task GetLifePayRate(CreateEditPayChannelsInput channel, LifePayRateTypeEnum lifePayRateType) { if (channel == null) { var rate = await GetRate(); CheckExtensions.IfTrueThrowUserFriendlyException(rate.IsNullOrEmpty(), "未配置折扣"); var result = rate.FirstOrDefault(x => x.RateType == lifePayRateType).Rate; return result; } else { return channel.ChannlesRate; } } public async Task SetPayType(string orderNo, LifePayTypeEnum lifePayType, string ip) { var order = await _lifePayOrderRepository.Where(x => x.OrderNo == orderNo).FirstOrDefaultAsync(); CheckExtensions.IfTrueThrowUserFriendlyException(order == null, "订单不存在"); CheckExtensions.IfTrueThrowUserFriendlyException(order.LifePayType.HasValue, "当前订单已选择支付类型"); order.LifePayType = lifePayType; var premium = await _lifePayPremiumRepository.Where(x => x.IsDeleted == false && x.PremiumType == order.LifePayType).FirstOrDefaultAsync(); order.PremiumRate = premium == null ? 0 : premium.Rate; await _lifePayOrderRepository.UpdateAsync(order); var desc = "生活缴费-"; switch (order.LifePayOrderType) { case LifePayOrderTypeEnum.PhoneOrder: desc += "话费"; break; case LifePayOrderTypeEnum.ElectricOrder: desc += "电费"; break; case LifePayOrderTypeEnum.GasOrder: desc += "燃气"; break; default: break; } return new SetPayTypeReturn() { Desc = desc, OrderNo = order.OrderNo, PayAmount = order.PayAmount.HasValue? order.PayAmount.Value : 0, LifePayType = lifePayType, }; } #endregion }