Commerce begin_checkout event can fire multiple times with ajax panes

Created on 21 December 2023, 12 months ago
Updated 6 February 2024, 11 months ago

Problem/Motivation

If you have checkout panes that use ajax on the first page of checkout, the begin_checkout event will fire every time a page is updated.

Steps to reproduce

Set up a site with Commerce. Add a pane to the first page of checkout that has ajax. The example that we found this on is with Commerce Shipping module. On the shipping pane, there's a button to calculate shipping rates after adding the shipping address. That button reloads the form with ajax. (and currently fires begin_checkout when it refreshes)

Proposed resolution

Only fire begin_checkout when the first page of checkout is being loaded without ajax.

Remaining tasks

Patch coming.

User interface changes

None.

API changes

None.

Data model changes

None.

πŸ› Bug report
Status

Needs work

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States zengenuity

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

Comments & Activities

  • Issue created by @zengenuity
  • Status changed to Needs review 12 months ago
  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 10.1.x + Environment: PHP 8.1 & MySQL 5.7
    last update 12 months ago
    54 pass
  • πŸ‡ΊπŸ‡ΈUnited States zengenuity

    Patch attached.

  • πŸ‡¨πŸ‡­Switzerland berdir Switzerland

    Just found this as well. Patch partially helps, but a page refresh still counts twice, not sure if that's expected or not. There's also πŸ› Drupal Commerce purchase event gets sent multiple times if someone refreshes the checkout success page Active for a similar problem on purchase/checkout complete.

    Wondering if google_tag should maybe have a built-in feature for unique events where it stores some kind of identifier in session/tempstore.

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

    The SEO expert who flagged this issue for our site suggested it would be expected for begin_checkout to fire every time the first page of checkout is displayed, such as if someone navigates away from it and then comes back. If that's true, I think it would be tough to prevent it on page refresh, since that's going to be very similar. I guess we could look at the referrer, perhaps.

    For the purchase event, the situation would be different. That one should only ever fire once per order. It should probably happen on the order placed or order paid event rather than looking at the checkout step.

  • Status changed to Needs work 11 months ago
  • πŸ‡ΊπŸ‡ΈUnited States japerry KVUO

    I agree about the idea of a tempstore before firing, if thats even possible.. But there is likely some work needed to get this issue totally fixed per Berdir's comment.

  • πŸ‡ΈπŸ‡°Slovakia kaszarobert

    For commerce event tracking we've been using https://www.drupal.org/project/commerce_google_tag_manager β†’ (its latest release is hidden because it is Drupal 8, 9 only, plus the events are done for Universal analytics, not GA4) and there we never had an issue with events firing multiple times. I think there they also use tempstore. Maybe we could apply their solution here as well.

  • πŸ‡¨πŸ‡­Switzerland berdir Switzerland

    @japerry: I'm not entirely sure that the purchase and this event are exactly the same and need the same fix per #4. Purchase definitely should not fire more than once ever for the same order, but I can see use cases where this might be desired for this event, like when you abort and re-enter checkout.

    But if you have a payment and then return on a failed payment to the first step then that's also a problem and likely a bigger one than not firing the event again.

    commerce_google_tag_manager did not have a persistent key value store, it just used a request subscriber and only acted on GET requests, which is not unlike the current patch here.

  • πŸ‡¨πŸ‡­Switzerland berdir Switzerland

    FWIW, that said, we are using this patch now in production and did not yet get any complaints about it, so it's definitely an improvement over HEAD and one option would be to commit this and reopen πŸ› Drupal Commerce purchase event gets sent multiple times if someone refreshes the checkout success page Active to implement a persistent deduplication using tempstore or something.

Production build 0.71.5 2024