public async Task <ActionResult <StripeResult> > PostError([FromBody] StripeCharge request)
        {
            StripeResult result = new StripeResult();
            Order        order  = _context.orders.Find(request.CartId);

            try
            {
                order.IdempotencyToken = Guid.NewGuid().ToString();
                await _context.SaveChangesAsync();

                result.Success = true;
            }
            catch (Exception exception)
            {
                result.Success = false;
                result.Error   = exception.Message;
            }

            return(result);
        }
        public async Task <ActionResult <StripeResult> > Post([FromBody] StripeCharge request)
        {
            StripeConfiguration.ApiKey = StripeApiKey;

            PaymentIntentService service = new PaymentIntentService();
            PaymentIntent        paymentIntent;
            StripeResult         result = new StripeResult();
            Order order = _context.orders.Find(request.CartId);

            // First pass
            if (request.PaymentMethodId != null)
            {
                PaymentIntentCreateOptions options = new PaymentIntentCreateOptions
                {
                    PaymentMethod      = request.PaymentMethodId,
                    Amount             = request.TotalCost,
                    Currency           = "nok",
                    Description        = "Purchase from VippsCase.",
                    ConfirmationMethod = "manual",
                    Confirm            = true,
                };

                try
                {
                    paymentIntent = service.Create(options, new RequestOptions
                    {
                        IdempotencyKey = order.IdempotencyToken
                    });

                    // Check the user making the purchase
                    User user;
                    if (request.UserId == -1)
                    {
                        // Adding a new customer if one was not specified in the request
                        user = new User
                        {
                            Name           = request.CustomerDetails.FullName,
                            AddressLineOne = request.CustomerDetails.AddressLineOne,
                            AddressLineTwo = request.CustomerDetails.AddressLineTwo,
                            County         = request.CustomerDetails.County,
                            PostalCode     = request.CustomerDetails.PostalCode,
                            City           = request.CustomerDetails.City,
                            Country        = request.CustomerDetails.Country,
                            PhoneNumber    = request.CustomerDetails.PhoneNumber,
                            Email          = request.CustomerDetails.Email
                        };

                        // Storing our customer details.
                        _context.users.Add(user);
                    }
                    else
                    {
                        // Find the user matching the userId and add them to the order.
                        user = _context.users.Find(request.UserId);
                    }

                    // Setting the user and charge to the user we just made and the charge token.
                    order.StripeChargeToken = paymentIntent.Id;
                    order.UserId            = user.UserId;

                    // Saving all of our changes.
                    await _context.SaveChangesAsync();
                }
                catch (StripeException exception)
                {
                    // Idempotency special handling
                    if (exception.StripeError.ErrorType == "idempotency_error" ||
                        exception.StripeError.DeclineCode == "duplicate_transaction" ||
                        exception.StripeError.Code == "duplicate_transaction")
                    {
                        result.Success = true;
                    }
                    else
                    {
                        // When an order fails due to an issue with stripe,
                        // we'll assign the order a new idempotency key to prevent the "idempotency_error" from stripe.
                        order.IdempotencyToken = Guid.NewGuid().ToString();
                        await _context.SaveChangesAsync();

                        // Return the error message to the user.
                        result.Success = false;
                        result.Error   = _stripeErrorHandler.ErrorHandler(exception);
                    }
                    return(result);
                }
            }
            // Second pass
            else
            {
                PaymentIntentConfirmOptions options = new PaymentIntentConfirmOptions {
                };
                try
                {
                    paymentIntent = service.Confirm(request.PaymentIntentId, options);
                }
                catch (StripeException exception)
                {
                    // When an order fails due to an issue with stripe,
                    // we'll assign the order a new idempotency key to prevent the "idempotency_error" from stripe.
                    order.IdempotencyToken = Guid.NewGuid().ToString();
                    await _context.SaveChangesAsync();

                    // Return the error message to the user.
                    result.Success = false;
                    result.Error   = _stripeErrorHandler.ErrorHandler(exception);
                    return(result);
                }
            }

            switch (paymentIntent.Status)
            {
            case "requires_action" when paymentIntent.NextAction.Type == "use_stripe_sdk":
                // Tell the client to handle the action
                result.Data = new
                {
                    requires_action = true,
                    payment_intent_client_secret = paymentIntent.ClientSecret
                };
                result.Success = false;
                break;

            case "succeeded":
                // The payment didn't need any additional actions and completed!
                // Handle post-payment fulfillment
                result.Success = true;
                break;

            default:
                // Invalid status
                // TODO: Change this error message to be user-friendly
                result.Error   = "Invalid PaymentIntent status";
                result.Success = false;
                break;
            }

            return(result);
        }