---
title: "A Coupon Changed the Checkout Price, but the PayPal Message Beside It Kept Quoting the Old One"
canonical: https://dxdev.com/blog/2026-02-24_four-payments-that-would-not-move/
datePublished: 2026-02-24
---
A checkout page showed a 30% coupon applied to the main total, but the payment message beside the buy button kept offering four payments based on the old, higher price. The correct discounted total was being passed in, and the message simply refused to redraw with it. Nothing errored, and the number that was wrong was not the number that had been calculated wrong.

I can picture why that would feel wrong from the customer side. The order itself would charge the discounted amount. The number beside the buy button would not. At the last possible moment, one part of the page was saying, in effect, “Here is what this costs,” while another part was telling a different story.

That is not a small bit of polish. Payment is where people decide whether to trust a page. If a price drops and the monthly or installment estimate does not, a customer has a fair reason to pause. They may wonder which number is real, whether the coupon worked, or whether something worse is about to happen after they click.

At first, the fix looked almost embarrassingly simple. The payment message had been given the original total. When the coupon changed that total, I tried giving the message the new one and asking it to draw itself again in the same spot. The rest of the page already knew how to update. The running total changed. The tax line changed. The label on the buy button changed. So the payment message ought to have followed along.

It did not.

There was no error message. Nothing visibly broke. The old number simply stayed there, as if the new number had never arrived. I spent time checking the coupon math and checking that the correct total was being passed in. Both were fine. That part matters, because it is easy to keep hunting for a mistake in the number when the number is not the problem.

The scary technical name here is an **SDK**. It is just a packaged piece of software from another company that you place inside your own page. In this case, that packaged piece had settled into the little box where it first appeared. Asking it to draw again in the same box was not a dependable way to make it read the new price.

The answer was less like fixing a calculator and more like replacing a note on the refrigerator door. Instead of trying to erase and rewrite the old note, I took down the little box that held the payment message, put a fresh blank box back in the exact same place, and then asked the payment message to appear there.

That fresh box was important. It gave the payment message somewhere it had not already claimed. But it had to be put back carefully. If the new box lost its styling, the payment message could look different or make the page jump. If it went back in the wrong place, it could slide to the bottom of its section. So the replacement kept the same appearance and returned to the same spot before the old message was redrawn.

That solved the stuck number, but there was one more wrinkle. The price on the page did not just change. It animated down after the coupon was applied. In other words, the number was moving for a moment before it reached its final home.

If I replaced the payment box at the exact instant the coupon was applied, it could sometimes catch the price halfway through that movement. The displayed payment estimate was then new, but not necessarily settled. It is like writing down the score while the scoreboard is still flipping its cards.

The practical fix was a short wait of 300 milliseconds. That is three tenths of a second. It was long enough for the price animation to finish and short enough that nobody would notice a lag beside the buy button. The point was not that 300 is a magic number for every checkout. The point was to wait until the thing the message depends on has actually stopped changing.

There was also a sneaky edge case. The page had a sensible shortcut: if the newly calculated total matched the previous total, it skipped some of the update work. Usually that saves effort. But “the total is unchanged” does not always mean “the payment message is right.” The message could still be showing an older amount because an earlier update had arrived at an awkward time, or because it had failed to appear cleanly before.

So the refresh had to happen even on the shortcut path. Otherwise, the rare and frustrating cases would stay broken precisely because the page decided there was nothing new to do.

I like this story because it is not really about payment software. It is about the quiet ways a customer-facing promise can fall out of step with reality. The big number was correct. The order charge was correct. Yet a smaller number next to the button was enough to make the whole moment feel unreliable.

The 300 milliseconds is the part I would defend hardest, because it marks the difference between a number that has arrived and a number that has settled. The payment message was handed the correct discounted total and still showed the old one, first because it had claimed its box and would not redraw there, and then because it could catch the price mid-animation, before the total had stopped moving. A fresh box, put back in the same spot after a three-tenths-of-a-second wait, and a refresh that runs even when the new total matches the old one: those three details are what finally made the small figure beside the buy button agree with the large one above it.
