Search code examples
asp.netasp.net-mvc-5stripe-paymentspayment-gateway

How to retrieve checkout information when using Stripe SDK


Here is my Cart and Checkout process in my web application

My purpose is after checkout, I retrieve the payment information like transaction Id or payment reference

In my ASP.NET MVC 5 application, I have following code in Cart View

<div>
@using (Html.BeginForm("", "Cart", FormMethod.Post))
{
     ... here I show products in cart ...

     ... NOTE that I don't have any action in my form ...

     <input type="submit" id="stripe-checkout-button" value="Checkout" />
}
</div>

<script type="text/javascript">
    var stripe = Stripe('@ViewBag.StripePublishKey');
    var checkoutButton = document.getElementById('stripe-checkout-button');

    checkoutButton.addEventListener('click', function () {
        fetch('https://localhost:44323/Cart/CreateCheckoutSession', {
            method: 'POST'
            })
            .then(function(response) {
                return response.json();
            })
            .then(function(session) {
                return stripe.redirectToCheckout({ sessionId: session.id });
            })
            .then(function(result) {
                if (result.error) {
                    alert(result.error.message);
                }
            })
            .catch(function(error) {
                console.error('Error:', error);
            });
    });
</script>

In Cart controller I have following actions

[HttpPost]
public ActionResult CreateCheckoutSession()
{
    var cart = (ShoppingCart)Session["cart"];
    var options = new SessionCreateOptions
    {
        PaymentMethodTypes = new List<string> { "card" },
        Mode = "payment",
        SuccessUrl = Url.Action("CheckoutSuccessful", "Cart", null, Request.Url.Scheme),
        CancelUrl = Url.Action("CheckoutCancelled", "Cart", null, Request.Url.Scheme),
        PaymentIntentData = new SessionPaymentIntentDataOptions
        {
            CaptureMethod = "manual"
        },
        LineItems = new List<SessionLineItemOptions>()
    };

    foreach (var item in cart.Items)
    {
        // here I add the purchased product. I remove the code for simplification
    }

    var service = new SessionService();
    Session session = service.Create(options);

    ViewBag.SessionId = session.Id;

    return Json(new { id = session.Id });
}

public ActionResult CheckoutSuccessful(string sessionId)
{
    // sessionId is null here. I'm even not sure if I need this parameter

    ShoppingCart cart = (ShoppingCart)Session["cart"];
    return RedirectToAction("Index", "Checkout");
}

public ActionResult CheckoutCancelled()
{
    return RedirectToAction("Index", "Cart");
}

When I click on Checkout button, the application redirects to Stripe payment page and I can enter email and billing information and click pay. It works well and payment goes through.

Based on my setting, the application redirects to CheckoutSuccessful action after that.

What I am missing here is, in CheckoutSuccessful action, I need to retrieve email address and billing address plus payment or transaction Id. I don't know how to do that. In CheckoutSuccessful, the parameter sessionId is null. I don't know what I've done wrong here or what I'm missing.

Thanks for help.


Solution

  • After a few days research and try out, I figured it out.

    After creating session, I need to store the session.Id in Http Session and in CheckoutSuccessful method (which does not need any parameter), I need to call couple of APIs to retrieve session and payment information like below:

    var service = new SessionService();
    var session = service.Get(the stored session.Id);
    
    var custService = new CustomerService();
    var customer = custService.Get(session.CustomerId);
    
    var paymentService = new PaymentIntentService();
    var payment = paymentService.Get(session.PaymentIntentId);
    

    Then, I will have all required infromation in session, customer and payment objects.