I’m following Stripe’s online docs to create an embedded payment form for connected accounts.
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
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:
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.
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.