Here is a support conversation that happens more often than anyone admits:
"I tried to pay your invoice but the page says the session has expired."
The customer did everything right. They opened your email, clicked Pay, and hit a dead end — on the one day they had set aside to pay you. Some will email you. Some will mean to come back. Some will pay late, and it won't be because they didn't want to.
The cause is almost always the same, and it is easy to check for.
Checkout pages are built to expire
When you pay for something online, the page you type your card into is usually a checkout session: a short-lived page created for one purchase, with the amount, currency and items fixed inside it. Payment processors make these expire on purpose. Stripe's hosted checkout sessions, for example, last at most 24 hours.
That is sensible for a shop. Prices change, stock runs out, and a payment page that lives forever is a page someone can find and reuse. A checkout session is meant to be created the moment someone decides to pay and used within minutes.
Where invoicing goes wrong
The trouble starts when an invoicing tool creates that checkout session when the invoice is sent and puts its URL straight into the email.
Invoices don't get paid in minutes. They get paid when the customer gets round to it — on payday, at month end, when the accounts person works through the pile. With net-30 terms, the first click on the Pay button can come weeks after the email went out. By then a 24-hour session is long dead.
Nothing about it looks broken when you test it, either. You send yourself an invoice, click Pay straight away, and it works perfectly. The link only fails for the customers who behave like customers.
How to tell if yours do this
You can check in two minutes, with a one-day wait in the middle:
- Send yourself a real invoice from your invoicing tool, to an email address you can open.
- Wait 25 hours. Don't open it before then.
- Click Pay. If you get an expired-session page instead of a payment form, every customer who pays more than a day after you send has been hitting the same wall.
While you are there, look at the link itself. If it goes straight to the payment processor's domain — a long URL full of random characters — it is probably a session link. If it goes to a page about your invoice first, it is probably the durable kind.
What a durable link looks like
The fix is to stop sending the checkout page and send the invoice instead.
A durable pay link points at a page about your invoice, which never expires. When the customer clicks Pay on that page, a fresh checkout session is created for them right then, with the invoice's current amount. They get a working payment page on day one, day thirty or day ninety.
It also fixes two smaller problems along the way:
- It knows the invoice's state. If the invoice has already been paid — or a bank transfer for it is still clearing — the page says so instead of offering a second payment.
- It can't charge a stale amount. The session is built from the invoice at the moment of payment, not from whatever it said when you first sent it.
We had this bug too
We'll be straight about why this post exists. Until October 2026, ScanThisText created the checkout session when an invoice was sent and stored that link. A customer who paid the next day was fine; one who paid the following week got an expired page. Nobody had reported it, which is the uncomfortable part: customers who hit a dead Pay button rarely tell the business, they just pay later or not at all.
Every invoice now carries a durable link, including the ones sent before the fix — they now point at a page that creates a fresh checkout on each click. If you send invoices through any tool, it's worth running the 25-hour test above. It's the cheapest way to find out whether your Pay button works for the people who actually use it.
Every account can send three invoices a month with pay links that don't expire. Start free.
Checkout session lifetime from Stripe's Checkout documentation, checked October 2, 2026.



