Payments · webhooks
The money arrives. The access does not.
Stripe shows a successful payment. The customer emails you because nothing changed. You upgrade them by hand and hope it was a one-off. It is not a one-off, and it is almost always the webhook. The one part of a payment flow that cannot be tested by clicking through it.
This one is worth fixing the week it appears. Every day it runs, it costs you a refund and a trust problem.
- First step
- A short call, or a written description if you would rather not talk yet
- Who you speak to
- The engineer who would do the work. No account manager, no sales call.
- Turnaround
- Most single problems are resolved within 48 hours of getting access
- Cost
- Quoted after we have seen it: scope varies, and guessing helps neither of us
How to get this fixed
Already a client? Raise it as a ticket in Golux Club and it enters the queue with an SLA attached.
People pay but the app does not unlock. Why?
Access is being granted on the browser redirect after checkout, which is a page load and not a payment: it does not fire if the customer closes the tab, and anyone can visit it directly. Grant access from the webhook instead, verify its signature, and make the handler idempotent: Stripe retries the same event.
The rest of this page is why that happens, how to tell which case you have, and what fixing it involves.
Why the webhook is the part that breaks
Checkout is a redirect: the browser leaves, pays, and comes back. The 'come back' is a page that cannot be trusted to grant anything. The customer can close the tab, lose signal, or never return. The grant has to happen on the webhook, and webhooks fail in specific ways. The signature check needs the exact raw body, and most frameworks have already parsed it into JSON by the time your code sees it, so verification fails and the event is rejected. Or the endpoint is not registered for the event you rely on. Or nothing ties the Stripe session back to the user, because the customer id was never stored. Or the event arrives twice, Stripe retries by design, and the code was not written for that.
How to tell it is this
- Stripe's dashboard shows delivery failures or 400s on your webhook endpoint
- It works when you test with the CLI and fails in production
- Access is granted only if the customer lands back on the success page
- One purchase upgraded the customer twice, or created two subscriptions
- Subscriptions work on day one and never renew correctly
What we do
The order matters: verify, connect, then make it repeatable.
- 01
Replay your real failures
Stripe keeps the last 30 days of events. We replay them against your endpoint and watch it fail, which names the cause immediately.
- 02
Fix verification
The raw body reaches the signature check intact, the signing secret is the one for that endpoint, and the right events are subscribed.
- 03
Tie the payment to the person
The customer id stored on your side, the checkout session carrying who it is for, so a paid event can always find its user.
- 04
Make it safe to repeat
Handling written so the same event twice grants access once, and a failed delivery hours later still works. Then we replay the failures so the customers waiting get what they paid for.
What you get
- Payments granting access without anyone watching
- The backlog of failed events replayed, so existing customers are made whole
- Duplicate-safe handling: a retried event cannot grant access twice
- A note on what to watch in Stripe so you see the next failure before a customer does
When this is not what you need
- You have not connected Stripe at all yet. That is a build, not a fix; it is usually a day and we will quote it
- You need a different pricing model: seats, usage metering, trials with cards. That is product work
- The problem is tax, invoicing or an accounting integration: real problems, different specialists
How it works
- 01
Tell us the symptom
One paragraph is enough. The error, the screen, what you expected. Run the free audit first if you have not; it often names the problem for you.
- 02
A call, or a written reply
Thirty minutes to look at it together, or a written answer if you prefer. Either way you find out what it is before anything is agreed.
- 03
A written offer
After the call: the scope, the approach and what we need from you. Discussed on the call, confirmed in writing.
- 04
Fixed, explained, handed back
The fix in your project, a short note on what was wrong and why, and how to check it yourself: typically inside 48 hours of getting access.
What we promise before any money changes hands
We tell you what is actually wrong, whether it is one problem or a symptom of a bigger one, and what it would take, before you commit to anything. If the honest answer is that you can fix it yourself in an afternoon, that is the answer you get, and the instructions are usually on this page already.
Questions
- Is my Stripe secret key exposed too?
- Check: it often is in generated apps, and that is a worse problem than the webhook. Our free audit looks for sk_live in the bundle from outside. If it finds one, rotate today; when both are present, the key is part of the same fix.
- Can you recover the customers who paid and got nothing?
- Usually yes. Stripe keeps the last 30 days of events; once the endpoint works, we replay them and the grants happen as they should have. Anyone outside that window we list for you to handle by hand.
- Do I need to be there while you work?
- Fifteen minutes at the start to give access and confirm what 'paid' should unlock. After that, no.
- What about Lemon Squeezy, Paddle or Polar?
- Same shape of problem, same fix, quoted the same way. The mechanics differ slightly; the fact that the grant belongs on the webhook does not.
Other things we fix the same way
- A secret key is in my bundle“There is a secret key in my JavaScript bundle.”
- The build or deploy is failing“The deploy fails, or it works in preview and breaks in production.”
- Login works, no data shows“I can log in, but every list is empty and there is no error.”
From the products we build
Free tools and guides from software we built and run ourselves.
- serverinspector.comKeyword monitoring: catch hidden website outagesWhy a 200 OK is not proof that a page works, and how a content check catches the failures an uptime ping misses.Read it
- serverinspector.comReducing alert fatigue: thresholds, retries and dedupConfirmation checks, flap detection and deduplication, so every alert that fires is one worth reading.Read it
Next step
Tell us the symptom. We will tell you if it is one problem.
We typically reply within 48 hours with what it is, whether one fix covers it, and what we need from you. If it is bigger than one problem, we say that instead, before anything is agreed.