#ironbeard_code
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/1449076007297487020
๐ 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.
- ironbeard_code, 1 hour ago, 31 messages
- ironbeard_integration-questions, 23 hours ago, 36 messages
- ironbeard_code, 1 day ago, 37 messages
On the GET request of /checkout/payment/, which displays the PaymentElement, I create a SetupIntent using the following (python):
setup_intent = stripe.SetupIntent.create(
customer=customer_id,
usage='off_session',
)
which returns this:
{
"application": null,
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1SdZ8jE3d1saT86kwY0ZmjtL_secret_TakeJ2oIkCgj3owwMKm0W0y2V527F3x",
"created": 1765556661,
"customer": "cus_SlqQtl2WEvcWQu",
"customer_account": null,
"description": null,
"excluded_payment_method_types": null,
"flow_directions": null,
"id": "seti_1SdZ8jE3d1saT86kwY0ZmjtL",
"last_setup_error": null,
"latest_attempt": null,
"livemode": false,
"mandate": null,
"metadata": {},
"next_action": null,
"object": "setup_intent",
"on_behalf_of": null,
"payment_method": null,
"payment_method_configuration_details": null,
"payment_method_options": {
"card": {
"mandate_options": null,
"network": null,
"request_three_d_secure": "automatic"
}
},
"payment_method_types": [
"card"
],
"single_use_mandate": null,
"status": "requires_payment_method",
"usage": "off_session"
}
then on the front end, I have
form.addEventListener('submit', async (event) => {
event.preventDefault();
const { setupIntent, error } = await stripe.confirmSetup({
elements,
redirect: 'if_required',
confirmParams: {
expand: ['payment_method'],
return_url: window.location.origin + "{{ next_url }}",
}
})
if (error) {
message.innerText = error.message
} else if ( false ) {
// Your customer will be redirected to your `return_url`. For some payment
// methods like iDEAL, your customer will be redirected to an intermediate
// site first to authorize the payment, then redirected to the `return_url`.
} else {
const pm = setupIntent.payment_method
const fe = form.elements
fe.id.value = pm.id
fe.zip_code.value = pm.billing_details.address.postal_code
fe.card_brand.value = pm.card.brand
fe.card_last4.value = pm.card.last4
fe.card_exp_date.value = `${pm.card.exp_month}/${pm.card.exp_year}`
form.requestSubmit()
}
})
and the result is that "A processing error occurred." is displayed in message.innerText, which isn't helpful, but in the browser console I see:
POST
https://api.stripe.com/v1/setup_intents/seti_1SdZ8jE3d1saT86kwY0ZmjtL/confirm
[HTTP/2 400 301ms]
{
"error": {
"code": "setup_intent_unexpected_state",
"doc_url": "https://stripe.com/docs/error-codes/setup-intent-unexpected-state",
"message": "You cannot confirm this SetupIntent because it has already succeeded.",
"request_log_url": "https://dashboard.stripe.com/test/logs/req_WFwwWBMxLPYuX6?t=1765556695",
"setup_intent": {
"id": "seti_1SdZ8jE3d1saT86kwY0ZmjtL",
"object": "setup_intent",
"automatic_payment_methods": null,
"cancellation_reason": null,
"client_secret": "seti_1SdZ8jE3d1saT86kwY0ZmjtL_secret_TakeJ2oIkCgj3owwMKm0W0y2V527F3x",
"created": 1765556661,
"description": null,
"excluded_payment_method_types": null,
"last_setup_error": null,
"livemode": false,
"next_action": null,
"payment_method": "pm_1SdZ9GE3d1saT86ktXPVeZ6u",
"payment_method_configuration_details": null,
"payment_method_types": [
"card"
],
"status": "succeeded",
"usage": "off_session"
},
"type": "invalid_request_error"
}
}
(sorry for the flood of text ๐ฌ )
๐ Hi there, just reading through your question ๐
Looking over the example Setup Intent seti_1SdZ8jE3d1saT86kwY0ZmjtL I can see there are two calls being made to confirm the Intent back to back, the first succeeds, and the second results in the 400 error you've described.
hmm. that's helpful. I wonder why that is. could form.requestSubmit() be the issue?
oh, yeah it is. because stripe.confirmSetup is called in the form.submit listener.
I was thinking that might be the case
Maybe if I just call form.submit() instead of form.requestSubmit() it won't re-launch the event ๐คI'm just trying to continue the form submit after confirmSetup() is called
yup! just using form.submit() works. Thanks โค๏ธ
Have you had a chance to look over our two step confirmation docs? If I understand you are trying to collect payment info and then have the user confirm in a second step which those docs outline.
https://docs.stripe.com/payments/build-a-two-step-confirmation
The example uses a Payment Intent but otherwise it's much the same.
Glad we could help you get unstuck ๐
I think I looked at it awhile back, but it wasn't a good fit bc it's possible for my shopping carts to have two different subscriptions. So my plan was for this step to obtain a validated payment method, then on the checkout/review/ page, I can show details of the PM and the items in the cart, and then on POST create two Subscriptions with customer and pm already set, which should immediately charge them, right?
That makes sense since your confirmation is page is expecting payment details to be collected already. Just let us know if you have any other questions and were more than happy to assist.