#ethan_api
1 messages · Page 1 of 1 (latest)
👋 Welcome to your new thread!
⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1386892577244184697
📝 Have more to share? Add more details, code, screenshots, videos, etc. below.
Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
The one thing I have done differently to that guide is that I am not creating a Payment Intent with which to confirm the payment - instead I am creating a subscription and using the client secret from the subscription's latest_invoice
Hi! How are you creating your confirmation token?
const stripe = useStripe();
const elements = useElements();
const getConfirmationToken = async () => {
if (!stripe || !elements) {
throw new Error(
`Stripe or Elements object are missing: stripe: ${!!stripe}, elements: ${!!elements}`,
);
}
const { error: submitError } = await elements.submit();
if (submitError) {
throw new Error(submitError.message);
}
const { error, confirmationToken } = await stripe.createConfirmationToken({
elements,
params: {
payment_method_data: {
billing_details: {
email,
},
},
},
});
if (error) {
throw new Error(error.message);
}
return confirmationToken.id
};
Can I see your code for your payment confirmation?
const handleSubmit = async () => {
try {
if (!confirmationTokenId || !clientSecret || !stripe || !elements) {
throw new Error(...);
}
setLoading(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
confirmation_token: confirmationTokenId,
return_url: returnUrl,
},
clientSecret,
});
if (error) {
throw new Error(error.message);
}
} catch (error) {
setMessage(
error instanceof Error ? error.message : UNKNOWN_ERROR_MESSAGE,
);
} finally {
setLoading(false);
}
};
But it's worth noting that this is in a different component to where the confirmation token is created
And the payment element is rendered in the one where the confirmation token is created, but not this one
Both are wrapped with the same <Elements> provider though
I came across this issue suggesting that the elements object might be being recreated, but I've check and it doesn't appear to be
You don't need to pass the Elements object when confirming the payment: https://docs.stripe.com/payments/build-a-two-step-confirmation#submit-the-payment
const {error} = await stripe.confirmPayment({
clientSecret,
confirmParams: {
confirmation_token: '{{CONFIRMATION_TOKEN_ID}}',
return_url: 'https://example.com/order/123/complete',
},
});
ahh bingo, my bad
I was reading the Build a subscriptions integration guide at the same time to make sure I was doing things right with respect to the subscription stuff and I must have gotten mixed up between the two for the confirmPayment call
But that works now, thanks so much
Happy to help! 🫡