Two payments created sometime when checkout with Stripe Payment Element

Created on 26 April 2025, 21 days ago

Problem/Motivation

hi, so sometime when a user on my site checkouts with Stripe Payment Element then two payments are added to the order, both payments have everything same including the remote id, you can see the order log in the screenshot attached, the payment is captured twice with same transaction id.

It donot happen always but only sometimes especially when a user goes back to review page or updates the cart.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Active

Version

2.0

Component

Payment Element

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @dastan56
  • πŸ‡ΊπŸ‡ΈUnited States willardb

    Your timing in posting this is great -- I just recently ran into the same thing myself and was happy to find someone else with the same problem.

    I am on commerce_stripe 2.0.0 but commerce 3.0.1 (not 2.x) for what it's worth. I am only seeing this behavior when using a stored payment method. I correctly get just one payment entry when providing new card information. But, when I use stored payment information, I have two (or more sometimes?) payment entries tied to the same stripe remote id as in your screenshot.

    I might be missing something deeper here and this might now work in all configuration scenarios, but from what I can tell in my setup, the form submit handler for stored payment methods in commerce_stripe.payment_element.js may need to prevent the submit default action just like it does in the case of providing payment info some lines up in that file. As it stands, when I click the "pay and complete purchase" button on the review screen in a scenario where I've used stored payment info, I see multiple requests to the /checkout/{ordernum}/payment endpoint, and one gets aborted by the browser even though it does hit my backend from the logs I can see. (see provided image)

    With some light testing, it doesn't seem like preventing the default submit action in the case of using a stored payment method is stopping anything else from firing that is required with commerce or commerce_stripe, and the payment does get recorded properly a single time for the order.

    I'll provide a patch of the fix I described which has solved the issue for me (for now) with the disclaimer that I'm not super well-versed in the commerce ecosystem and there might be something deeper going on here.

  • πŸ‡ΊπŸ‡ΈUnited States willardb

    I looked at this a little harder and determined that the actual issue seems to be related to how async event handlers work with form submissions. With an async function, the return false statement doesn't immediately stop the form submission because it happens after the await operation completes, which is too late.

    The event handler starts executing, but when it hits the await stripeConfirm() line, it yields control back to the browser while waiting for the Promise to resolve. During this time, the form submission continues because no return value has been provided yet.

    I did what I hope is a better job of refactoring the relevant form submit event handler to preserve the original intent and allow for normal submission when required but prevent normal submission in the case where we're waiting for a confirmation from Stripe. I'm providing an updated patch here and I will see about creating a merge request too.

    I've tested this lightly once again and it seems to work in my case but perhaps could cause unforeseen issues for others.

  • Pipeline finished with Failed
    21 days ago
    Total: 413s
    #482780
  • thanks for the detailed and quick response @willardb, for now i have switched to 8.x-1.3 version of the module, i will keep checking it to see if double payment issue happens with that version too, if yes then i will switch back to 2.0.0 version and will use the patch you provided.

  • πŸ‡ΊπŸ‡¦Ukraine vitaliyb98

    I faced the same problem. Commerce 3.0.2, Commerce Stripe 2.0.0

  • First commit to issue fork.
  • πŸ‡ΊπŸ‡ΈUnited States TomTech

    Hi all!

    Thanks for the reports, and sorry you encountered this issue.

    The js file has been further modernized and refined, removing jQuery related references.

    @willardb, you were actually closer in your initial assessment. :)

    We should actually never submit the form. Stripe will redirect the browser when the intent is confirmed successfully. (The redirect url actually is a different destination than what would happen with a submit. It is actually important to NOT submit the form.)

    The submit event listeners should only:
    1. disable the submit button(to prevent multiple submits),
    2. invoke the Stripe confirm method
    3. if an error occurs, display the error, and re-enable the submit button

    The two methods are now nearly identical, other than their initial argument. (We might refactor this later into one method.)

    Looks like we've got some javascript functional tests failing. This are not related to this issue.

    I'll be getting this merged, and the tests fixed.

  • πŸ‡ΊπŸ‡ΈUnited States TomTech

    tomtech β†’ changed the visibility of the branch 2.x to hidden.

    • e928a511 committed on 2.x
      Issue #3521297 by willardb, tomtech, dastan56, vitaliyb98: Two payments...
  • πŸ‡ΊπŸ‡ΈUnited States TomTech
    • e928a511 committed on 2.0.x
      Issue #3521297 by willardb, tomtech, dastan56, vitaliyb98: Two payments...
Production build 0.71.5 2024