The Price That Lived in Two Places
The pricing page said $30, but customers were charged $35. No one was trying to trick anyone. The price was stored in two places, and someone updated one but not the other.
I've worked on billing long enough to know how common this mistake is, and how much it can cost. Nothing breaks, and no error shows up. Customers just get charged the wrong amount, and over time people who liked your product start to resent it. Below I'll explain how this happens, why the usual fixes don't hold up, and what I do instead.

How it happens
Picture a small cafe. The menu on the wall says coffee is $3, but the till has its own price list. One morning the owner raises the till price to $3.50 and forgets to change the wall. All day, customers see $3 and pay $3.50.
Online billing works the same way. A business keeps its own list of plans, and that list is what shows up on the pricing page. But a payment company handles the payment and keeps its own separate list. When a customer pays, it's the payment company's list that decides what their card is charged.
That means every price is stored twice. Say the Pro plan goes from $30 to $35, and someone updates it only in the payment company. The pricing page still says $30. Nothing looks wrong, and payments still go through. They just go through at the wrong price.
Why it hurts more than 5 dollars
Now say 100 customers sign up that month. Each one pays $5 more than the page said, which adds up to $500 that nobody agreed to pay.
Some customers won't notice. Some will contact support. A few will go straight to their bank and say they were charged more than they were told. That's called a dispute. The bank pulls the money back first, asks questions later, and often charges the business a fee too, even if the business wins.
The fee isn't the real problem, though. The number of disputes is. Card companies keep track of how many disputes a business gets compared to how many payments it takes. If a business takes 1,000 payments a month, they start to notice at around 5 disputes. Stay above that for a few months, and the business can end up on a watch list with monthly fines. In the worst case, it can lose the ability to accept cards altogether.
The first fix everyone tries
"Just open the old price and change 30 to 35."
The payment company I use doesn't even let you do that. When I tried to change the amount on an existing price, it wouldn't let me. I could edit a few labels, but never the amount.
That seems annoying at first, but there's a good reason. Say Sara paid $30 last month, and her receipt is linked to that price. If you change it to $35, her old receipt is suddenly wrong. Six months later, if she asks for a refund, nobody can tell for sure what she actually paid.
So once a price has been used, you don't edit it. Instead, you create a new price and retire the old one, but keep it so it still shows what people paid while it was active. That keeps the records honest, but it raises a new question: if one plan now has two prices, which one is the real one?
The second fix everyone tries
"Just update both lists in one step, so either both change or neither does."
That works when everything lives in one system. But these two lists belong to two different companies, and there's no single button that updates both. I send my change to the payment company, they reply, and then I update my own list. Somewhere in between, the connection can drop, or their reply can get lost on the way back.
You can't make two companies act as one. You have to plan for the moment when one list has changed, and the other hasn't.
What actually works
My approach has four parts, and each one covers a gap the others leave open.
A name that moves
Think of a hospital door with a sign that says "Doctor on duty." A different doctor works there every night, but the sign stays the same. Patients look for the sign, not the specific person behind it.
Every new price gets its own long reference number, and that number changes each time. So I also give each plan a fixed name, like Pro Monthly, and the pricing page always asks for "the price called Pro Monthly." When the price goes from $30 to $35, I move the name to the new price, and the page shows $35 without anything else changing.
The payment company enforces one rule: only one price can have a given name at a time. When I tried to give a second price the same name, it refused and told me which price already had it. One name, one active price.
An order that fails safely
When a shop changes its opening hours, it puts up the new sign before taking down the old one. For an hour or so, the door has two signs. It looks a bit odd, but nobody thinks the shop has closed.
I do the same thing. I create the new price first, and only then retire the old one.
Doing it the other way around is risky. If you retire the old price first and something fails halfway, you have no active price, and the plan disappears from your store. At 40 sales a day and $35 each, that's $1,400 a day in lost sales until someone notices.
If you do it in the safe order and something fails, you're left with two active prices for a while. That's mostly harmless, because the pricing page looks up the price by name, and the name already points to the new one.
I can't stop things from breaking halfway through. But I can choose how they break.
Try again without fear
Say I try to retire the old price and get a network error. Did it work or not? I can't tell. But retiring a price twice has the same result as retiring it once; flipping a light switch off twice still leaves the light off. So the system just keeps trying until it gets a clear answer.
For steps that create something new, I attach a reference number to the request. If I send the same request with the same number, the payment company returns the original result instead of creating a second price. I've seen this happen: the same price came back, with the same creation time down to the second.
If I send the same number with a different request, say $35 instead of $30, it refuses. I like that. Each reference number belongs to one job. If two jobs ever end up sharing a number by mistake, I want an error, not a quiet "done" for something that never actually happened.
Check every morning
The first three parts make mistakes rare, but they don't rule them out. Someone can still change a price by hand on a busy afternoon.
So every morning, a small check reads both lists and compares them plan by plan. Do the prices match? Is the currency the same? Is there exactly one active price for each name? With 5 plans, that's just 5 rows on each side. If Pro is $30 on my side and $35 on theirs, someone gets alerted before the first customer of the day pays. A mistake that could cost $500 a month gets caught within hours.
It's the simplest part of the whole setup, and it's the one I'd keep if I had to drop everything else.
The price they read
Back to the cafe. The fix was never "just be more careful." People are careful, and they still forget to update the wall. The real fix is one price list that both the wall and the till read from, updated in an order that never leaves the shop without a price, plus a quick check of both every morning.
When a price is stored in two places, the two will drift apart unless something keeps them in sync. A $5 difference across 100 customers is $500 that nobody agreed to pay. Five disputes out of 1,000 payments is enough to get the card companies watching you. And behind every one of those numbers is a real person who saw $30, found $35 on their statement, and stopped trusting the business. Keeping both lists in sync makes sure the price people see is the price they pay.
- Payments
- Fintech
- Billing
- Customer Experience
- Software Engineering
