#ironbeard_code

1 messages ยท Page 1 of 1 (latest)

mystic violetBOT
#

๐Ÿ‘‹ 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.

faint sundial
#

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 ๐Ÿ˜ฌ )

mystic violetBOT
delicate dome
#

๐Ÿ‘‹ 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.

faint sundial
#

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.

delicate dome
#

I was thinking that might be the case

faint sundial
#

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 โค๏ธ

delicate dome
#

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 ๐Ÿ™‚

faint sundial
#

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?

delicate dome
#

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.