Skip to main content

ArtinTech Solution

The Order SMS That Resent Itself on Every Page Refresh

A store sending order confirmations by SMS started getting complaints that were flattering at first and then expensive: customers receiving the same confirmation four or five times. The message was correct. There were just too many of them, and every one cost money.

The hook was the bug

The sending code had been attached to a filter that runs while the thank-you page renders. Filters of that kind are not promises that something happened once — they run whenever the page is built. Refreshing the confirmation page, navigating back and forward, or a browser prefetching the URL each produced another render, and each render sent another message.

This is a general trap rather than a quirk of one plugin. A hook that fires during rendering answers the question “what should this page show”. Side effects that cost money or touch the outside world belong on hooks that answer “what just happened”.

Two changes, not one

The send moved onto an action that corresponds to the order actually being placed. That alone reduces the problem but does not eliminate it, because retries, race conditions and plugin interactions can still deliver the same event twice.

So the order itself now records that its message was sent. The send checks that flag first and returns immediately if it is set. The order is the one thing that persists across every request, which makes it the right place to keep the answer to “have we already done this?”

Fail quietly in the right direction

If the SMS credentials are missing or the phone number is empty, the function returns without sending and without raising an error that would block the order. A confirmation message failing should never prevent a sale from completing — the order is the thing that matters, the notification is a convenience on top of it.

Key takeaways

  • Rendering hooks run repeatedly. Never put billable side effects on them.
  • Moving to the right hook reduces duplicates; an idempotency flag eliminates them.
  • Store that flag on the record itself, not in a session or a transient.
  • Notification failures should degrade quietly and never block the transaction.

Related reading: manual mobile-money payments, and why order emails were not reaching Gmail.

Running into a similar limitation in your own WooCommerce or WordPress store? Let’s Talk — ArtinTech Solution builds exactly this kind of custom store tooling.

Share this article

Leave a Reply

Your email address will not be published. Required fields are marked *