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?