skip to Main Content

I’m following Stripe’s online docs to create an embedded payment form for connected accounts.

https://docs.stripe.com/connect/direct-charges?platform=web&ui=embedded-form&client=html#mount-checkout

My test API key is set correctly in Program.cs

This endpoint in my controller is mostly straight from Stripe’s API guide, and it happily returns the client secret:

[HttpGet]
[AllowAnonymous]
public ContentResult StripeCheckoutSession()
{
        var options = new Stripe.Checkout.SessionCreateOptions
        {
            LineItems = new List<Stripe.Checkout.SessionLineItemOptions>
        {
            new Stripe.Checkout.SessionLineItemOptions
            {
                PriceData = new Stripe.Checkout.SessionLineItemPriceDataOptions
                {
                    Currency = "aud",
                    ProductData = new Stripe.Checkout.SessionLineItemPriceDataProductDataOptions
                    {
                        Name = "T-shirt",
                    },
                    UnitAmount = 1000,
                },
                Quantity = 1,
            },
        },
            PaymentIntentData = new Stripe.Checkout.SessionPaymentIntentDataOptions
            {
                ApplicationFeeAmount = 123,
            },
            Mode = "payment",
            UiMode = "embedded",
            ReturnUrl = "abc={CHECKOUT_SESSION_ID}"
        };
        var requestOptions = new RequestOptions
        {
            StripeAccount = "acct_12345...";
        };
        var service = new SessionService();
        Session session = service.Create(options, requestOptions);
        return Content(JsonConvert.SerializeObject(session.ClientSecret));
}

In the head of my .cshtml view I have added this script element:

<script src="https://js.stripe.com/v3/"></script>

In the body I have this markup:

<div id="checkout">
</div>

Also in the head I have this javascript copied from Stripe’s API guide.

<script type="text/javascript">
    // initialize Stripe.js
    const stripe = Stripe('pk_test_blah...', {
       stripeAccount: {{CONNECTED_ACCOUNT_ID}},
    });

    initialize();

    // fetch checkout session and retrieve client secret
    async function initialize() {
      const fetchClientSecret = async () => {
        const response = await fetch("/StripeCheckoutSession", {
          method: "POST",
        });
        const { clientSecret } = await response.json();
        return clientSecret;
      };

      // initialize checkout
      const checkout = await stripe.initEmbeddedCheckout({
        fetchClientSecret,
      });

      // mount checkout
      checkout.mount('#checkout');
    }
</script>

Note, I have replaced {{CONNECTED_ACCOUNT_ID}} with a reference to the actual value from the view model as follows:

'@Model.StripeAccountID'

When I run the project, nothing happens – a blank white screen. I half expected this because I don’t see how initialize() gets called. And I see it never executes.

So I wrote the js how I think it should work as follows:

    <script type="text/javascript">
        // initialize Stripe.js
        const stripe = Stripe('pk_test_blah...', {
            stripeAccount: '@Model.StripeAccountID',
        });

        $(document).ready(function () {
            initialize();
        })

        // fetch checkout session and retrieve the client secret
        async function initialize() {
            try {
                alert('Start');
                const fetchClientSecret = async () => {
                    const response = await fetch("StripeCheckoutSession", {
                        method: "GET",
                    });
                    const { clientSecret } = await response.json();
                    return clientSecret;
                };
                // initialize checkout
                alert('Init checkout');
                const checkout = await stripe.initEmbeddedCheckout({
                    fetchClientSecret,
                });
                // mount checkout
                alert('Finish mount');
                checkout.mount('#checkout');
            }
            catch (err) {
                alert(err);
            }
        }
</script>

I see alert(‘Start’) and then alert(‘Finish mount’) but not alert(‘Init checkout’)

I also tried using a separate function using an AJAX call to get the Client Secret. The function itself worked but then Initialize Checkout failed.

What am I doing wrong? Can anyone help me with this?

2

Answers


  1. Their example uses an index.js +index.html which will work a little different to an MVC/Razor page. One thing would be the async processing is a bit off. Instead of wrapping a new async method consider trying:

    async function initialize() {
        try {
            alert('Start');
            await fetch("StripeCheckoutSession", {
                method: "GET",
                headers: {
                    'Content-Type': 'application/json'
                },
            }).then (response => {
                if (response.ok) {
                    return response.json();
                } else { /* handle server exception */ }
            )}.then (data => {
                // initialize checkout
                alert('Init checkout');
                const checkout = await stripe.initEmbeddedCheckout({
                    data.clientSecret
                });
                // mount checkout
                alert('Finish mount');
                checkout.mount('#checkout');
            });
        catch (err) {
            alert(err);
        }
    }
    

    Beyond that enable the browser debugging tools and check for errors in the console and consider setting breakpoints in the JS to verify things are being called as you expect.

    Login or Signup to reply.
  2. The first thing we should do is to open the browser console to see if there is any error when you initialise the stripe.js

    Next, ensure is that @Model.StripeAccountID is resolving to an account ID. You can print some logs to confirm this. I’m not familiar with .net but I found another page that shows how pass a variable from .net to javascript.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search