diff --git a/Apimanager_backend/Controllers/PayController.cs b/Apimanager_backend/Controllers/PayController.cs index bf14a4f..0e3de1d 100644 --- a/Apimanager_backend/Controllers/PayController.cs +++ b/Apimanager_backend/Controllers/PayController.cs @@ -17,16 +17,17 @@ namespace Apimanager_backend.Controllers private IOrderService _orderService; private IPaymentConfigService _paymentService; private IPayService _payService; - public PayController(ILogger logger,IOrderService order,IPaymentConfigService paymentConfigService,IPayService payService) + public PayController(ILogger logger, IOrderService order, IPaymentConfigService paymentConfigService, IPayService payService) { _logger = logger; _orderService = order; _paymentService = paymentConfigService; _payService = payService; } + //创建支付订单 [HttpPost] [Authorize(Roles = "User")] - public async Task CreatePayment([FromBody]CreatePaymentDto dto) + public async Task CreatePayment([FromBody] CreatePaymentDto dto) { var userId = User.Claims.First(x => x.Type == "userId").Value; //获取支付接口信息 @@ -41,17 +42,18 @@ namespace Apimanager_backend.Controllers switch (paymentConfig.PayType) { case PayType.None: - throw new BaseException(4001,"当前支付方式未配置"); + throw new BaseException(4001, "当前支付方式未配置"); case PayType.Epay: - var epayRes = await _payService.CreateEpay(orderRes, paymentConfig,dto.ReturnUrl); + var epayRes = await _payService.CreateEpay(orderRes, paymentConfig, dto.ReturnUrl); return Ok(epayRes); default: throw new BaseException(4001, "不支持的支付方式"); } } + //支付完成通知 [HttpGet] public async Task Notice( - int pid, string trade_no,string out_trade_no + int pid, string trade_no, string out_trade_no , string type, string name, decimal money , string trade_status, string sign, string sign_type ) @@ -66,8 +68,9 @@ namespace Apimanager_backend.Controllers param["trade_status"] = trade_status; param["sign"] = sign; param["sign_type"] = sign_type; + //获取支付配置key,用于签名校验 PaymentConfig paymentConfig = await _paymentService.GetPaymentConfigInfoByTypeAsync(type); - bool verifyRes = EpayHelper.VerifySign(param,paymentConfig.SecretKey); + bool verifyRes = EpayHelper.VerifySign(param, paymentConfig.SecretKey); if (!verifyRes) { throw new BaseException(4001, "签名校验失败"); @@ -79,5 +82,16 @@ namespace Apimanager_backend.Controllers await _orderService.UpdateOrderAsync(orderDto); return Ok("Success"); } + [HttpPost] + [Authorize( Roles = "User")] + public async Task Buy([FromBody]BuyDto dto) + { + var userId = User.Claims.First(x => x.Type == "userId").Value; + dto.UserId = int.Parse(userId); + await _payService.BuyAsync(dto); + var res = new ResponseBase(1000,"订购成功",null); + return Ok(res); + } + } } diff --git a/Apimanager_backend/Dtos/BuyDto.cs b/Apimanager_backend/Dtos/BuyDto.cs new file mode 100644 index 0000000..420154d --- /dev/null +++ b/Apimanager_backend/Dtos/BuyDto.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; + +namespace Apimanager_backend.Dtos +{ + public class BuyDto + { + public int UserId { get; set; } + [Required] + public int ApiPackageId { get; set; } + } +} diff --git a/Apimanager_backend/Services/IPayService.cs b/Apimanager_backend/Services/IPayService.cs index fc2af3b..c3c530a 100644 --- a/Apimanager_backend/Services/IPayService.cs +++ b/Apimanager_backend/Services/IPayService.cs @@ -6,5 +6,6 @@ namespace Apimanager_backend.Services public interface IPayService { Task CreateEpay(Order order,PaymentConfig paymentConfig,string returnUrl); + Task BuyAsync(BuyDto dto); } } diff --git a/Apimanager_backend/Services/OrderService.cs b/Apimanager_backend/Services/OrderService.cs index 8014376..61281d2 100644 --- a/Apimanager_backend/Services/OrderService.cs +++ b/Apimanager_backend/Services/OrderService.cs @@ -79,6 +79,7 @@ namespace Apimanager_backend.Services #region 更新订单状态 public async Task UpdateOrderAsync(OrderDto order) { + var transaction = await _apiContext.Database.BeginTransactionAsync(); try { var data = await _apiContext.Orders.SingleOrDefaultAsync(x => x.OrderNumber == order.OrderNumber || x.ThirdPartyOrderId == order.ThirdPartyOrderId); @@ -89,13 +90,22 @@ namespace Apimanager_backend.Services data.UpdatedAt = DateTime.Now; data.Status = order.Status; data.PaiAt = order.Status == OrderStatus.Completed ? DateTime.Now : null; + var user = await _apiContext.Users.FirstOrDefaultAsync(x => x.Id == order.UserId); + if (user == null) + { + throw new BaseException(2004, "用户未找到"); + } + user.Balance += order.Amount; _apiContext.Orders.Update(data); + _apiContext.Users.Update(user); await _apiContext.SaveChangesAsync(); + await transaction.CommitAsync(); return true; }catch(Exception e) { + await transaction.RollbackAsync(); logger.LogError(e.Message); - throw new BaseException(4003, "订单未找到"); + throw; } } #endregion diff --git a/Apimanager_backend/Services/PayService.cs b/Apimanager_backend/Services/PayService.cs index e6ce878..74c775a 100644 --- a/Apimanager_backend/Services/PayService.cs +++ b/Apimanager_backend/Services/PayService.cs @@ -13,12 +13,61 @@ namespace Apimanager_backend.Services private IMapper _mapper; private ILogger _logger; private ApiContext _context; - public PayService(IMapper mapper,ILogger logger,ApiContext apiContext) + public PayService(IMapper mapper,ILogger logger, + ApiContext apiContext) { _mapper = mapper; _logger = logger; _context = apiContext; } + + public async Task BuyAsync(BuyDto dto) + { + var transaction = await _context.Database.BeginTransactionAsync(); + try + { + var package = await _context.Apipackages.FirstOrDefaultAsync(x => x.Id == dto.ApiPackageId); + if (package == null) throw new BaseException(4004,"套餐未找到"); + var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == dto.UserId); + if (user == null) throw new BaseException(2004,"用户不存在"); + if (user.Balance < package.Price) + { + throw new BaseException(4002, "支付失败,余额不足。"); + } + var uPackage = await _context.UserPackages.FirstOrDefaultAsync(x => x.UserId == dto.UserId && x.PackageId == dto.ApiPackageId); + if (uPackage == null) + { + UserPackage userPackage = new UserPackage(); + userPackage.UserId = dto.UserId; + userPackage.PackageId = dto.ApiPackageId; + userPackage.RemainingCalls = package.CallLimit; + userPackage.ExpiryDate = DateTime.Now.AddMonths(1); + await _context.UserPackages.AddAsync(userPackage); + } + else + { + var baseDate = uPackage.ExpiryDate > DateTime.Now ? uPackage.ExpiryDate : DateTime.Now; + _context.UserPackages.Update(uPackage); + } + user.Balance -= package.Price; + _context.Users.Update(user); + await _context.SaveChangesAsync(); + await transaction.CommitAsync(); + return true; + }catch(Exception e) when(!(e is BaseException)) + { + await transaction.RollbackAsync(); + _logger.LogError(e,"购买套餐失败:{Message}",e.Message); + throw new BaseException(1005,"服务器内部错误"); + } + catch (BaseException) + { + await transaction.RollbackAsync(); + throw; + } + + } + public async Task CreateEpay(Order order, PaymentConfig paymentConfig,string returnUrl) { try