public async Task <IActionResult> CreateCheckoutSessionAsync(PostCreateCheckoutSessionRequest request) { Guid?userId = null; if (User.Identity.IsAuthenticated) { string uid = User.GetUid(); userId = (await _userService.GetUserByUidAsync(uid)).Id; } var response = await _paymentService.CreateCheckoutSessionAsync(request, userId); return(StatusCode(StatusCodes.Status201Created, response)); }
private async Task <PostCreateCheckoutSessionResponse> CreateCheckoutSessionBodyAsync(PostCreateCheckoutSessionRequest request, Guid?userId) { using var transaction = await _unitOfWork.BeginTransactionAsync(); var session = new Session(); try { var order = await _orderService.CreateOrderAsync(request.Order); await _unitOfWork.SaveChangesAsync(); foreach (var item in order.OrderItems) { if (item.Product.LeftInStock - item.Quantity <= 0) { throw new FailedToCreateCheckoutSessionException("Out of stock"); } item.Product.LeftInStock -= item.Quantity; _unitOfWork.ProductRepository.Update(item.Product); } if (userId.HasValue) { await _orderService.LinkUserToOrderAsync(userId.Value, order); } var lineItems = new List <SessionLineItemOptions>(); foreach (var orderItem in order.OrderItems) { lineItems.Add( new() { PriceData = new() { UnitAmountDecimal = decimal.Round( orderItem.UnitPrice, 2, MidpointRounding.AwayFromZero ) * 100, // why stripe Currency = "eur", ProductData = new() { Name = orderItem.Product.Name, Description = orderItem.Product.ShortDescription, Images = new List <string> { orderItem.Product.ThumbnailPictureUrl } } }, Quantity = orderItem.Quantity }); } var options = new SessionCreateOptions { PaymentMethodTypes = new List <string> { "card" }, CustomerEmail = order.OrderContactInfo.Email, Mode = "payment", LineItems = lineItems, SuccessUrl = request.SuccessUrl + $"password={order.UniquePassword}", CancelUrl = request.CancelUrl, AllowPromotionCodes = true, ShippingAddressCollection = new() { AllowedCountries = new List <string> { "LT" } }, Locale = "lt", ShippingRates = new List <string>() { _shippingRate.Value } // currently only one is supported by stripe }; session = await _stripeSessionService.CreateAsync(options); order.Payment = new(); order.Payment.PaymentIntentId = session.PaymentIntentId; _unitOfWork.OrderRepository.Update(order); await _unitOfWork.SaveChangesAsync(); await transaction.CommitAsync(); } catch (StripeException) { await transaction.RollbackAsync(); throw; } var response = _mapper.Map <PostCreateCheckoutSessionResponse>(session); return(response); }
public async Task <PostCreateCheckoutSessionResponse> CreateCheckoutSessionAsync(PostCreateCheckoutSessionRequest request, Guid?userId) { var executionStrategy = _unitOfWork.CreateExecutionStrategy(); /** * As a unit of repetition * Read more on: https://docs.microsoft.com/en-us/dotnet/architecture/microservices/implement-resilient-applications/implement-resilient-entity-framework-core-sql-connections */ var response = await executionStrategy.ExecuteAsync(() => CreateCheckoutSessionBodyAsync(request, userId)); return(response); }