Vibe-to-Production · Payments

Checkout Says It Worked. The Money Says Otherwise

Checkout works — you've watched real money arrive. But the totals in your app and the totals in your payment provider's dashboard don't quite agree, someone kept access after cancelling, or a refund you issued never showed up in your records. Each is small alone. Together they say your app and your money have different versions of events.

72 hours
01 / TO FINDINGS
2–6 weeks
02 / TYPICAL FIX WINDOW
500+
03 / ENGINEERS
92%
04 / ON-TIME DELIVERY
PaymentsProblem guide

When an AI-built checkout looks right but the numbers don't reconcile, the app is almost always recording payments at the moment of checkout and never listening to what the payment provider says afterwards — so refunds, failed charges and cancellations happen without your system noticing. You can prove or rule this out tonight with your provider's test mode, and the fix is a well-defined engineering pattern, not a rebuild of billing.

How to recognise it

The signs show up before the incident does.

None of these proves you have the problem. Each one raises the odds — and every one of them is checkable in the twenty-minute protocol below.

  • Two dashboards, two different truthsYour app says one number of paying customers; the payment provider's dashboard says another. Nobody can explain the gap — which means nobody can say which one the accountant should believe.
  • Cancelled customers who never leftSomeone cancelled — through the provider, through their bank — and your app kept serving them as a paying customer, because the cancellation happened somewhere your app has never listened to.
  • Refunds your records never heard aboutYou issue a refund from the provider's dashboard, and your app carries on as if the sale stood. Revenue reports drift a little further from reality with each one.
  • Failed renewals that fail silentlyA subscriber's card expires or declines at renewal. No email, no retry, no flag — the provider knows, your app doesn't, and the customer keeps the service for free until someone audits.
  • Reconciliation means a spreadsheet eveningMonth-end involves someone manually comparing provider records against app records and adjusting. That job growing each month is this problem, measured in your own hours.
Why this happens

One missing layer explains every symptom above.

Your app records the payment at checkout — and never listens to anything the payment provider says afterwards.

A payment is not a moment; it's a conversation that continues for months — refunds, disputes, failed renewals, cancellations, expiring cards. Providers report every one of these events, but only to apps built to receive them. Yours captured the opening sentence and hung up, so every later event happens in reality without happening in your records.

This is not a defect of any one tool — it follows from how prompt-built apps come to exist, and the platform guides show how the same gap surfaces on each stack.

What is actually at stake

It isn't a bug count. It's an open door.

Money is the one domain where 'roughly right' is a business problem: revenue figures an investor or acquirer can't tie to provider records become a diligence finding, unnoticed disputes quietly escalate with the card networks, and every silently failed renewal is either free service or a billing surprise — both of which cost trust that took months to earn. And unlike a crash, nothing here announces itself; the drift just compounds until someone audits.

If something has already gone wrong, the first-response guide covers the first hour. If nothing has — that is exactly the moment this is cheap to fix.

Check it yourself

Run the audit yourself — tonight.

No developer, no tooling, no permission needed — this is your own app. Work through the sheet in order; if a check fails, do it once more before believing it. What you find is yours to act on, with us or without us.

Diagnostic protocolAbout 20 minutesTwo browser windowsNo code required
  1. Do your app's numbers match the provider's, right now?

    Run it

    Open your payment provider's dashboard and count last month's successful charges. Then count last month's paid orders or active paying subscribers in your own app. Two numbers, side by side.

    What the result means

    An exact match is a pass — and genuinely good news. Any gap is this problem already in progress, and its size tells you how long the listening has been broken. This is the single most informative check on this page.

  2. When a card fails, does your app notice?

    Run it

    In your provider's test mode, pay with one of the published test cards that's designed to decline — every major provider documents these. Then look at what your app recorded, if anything.

    What the result means

    A clean failure — no order, or one marked failed — is a pass. An order marked paid, or a half-created record in limbo, means the app assumes success and checkout's word is being taken for the money's.

  3. Does a refund you issue ever reach your app?

    Run it

    Refund a test-mode transaction directly from the provider's dashboard — the same way you would a real one. Wait a few minutes, then check the order's status in your app without touching anything else.

    What the result means

    The order updating by itself is a pass — your app is genuinely listening. Silence means every refund you've ever issued is still counted as revenue in your records, and the drift grows with each one.

  4. Does cancelling actually end the service?

    Run it

    Cancel a test-mode subscription from the provider's side — the provider's dashboard or the customer's own portal, not your app's cancel button. Then log in as that test customer and see whether they still have paid access.

    What the result means

    Access ending or being flagged is a pass. A cancelled subscriber still enjoying full service means cancellations only work when they happen through your app — and customers' banks have never heard of your app.

  5. Can an impatient customer pay twice?

    Run it

    In test mode, go through checkout and behave like a nervous buyer: double-click the pay button, refresh the confirmation page, press back and submit again. Then count the resulting orders and charges on both sides.

    What the result means

    One charge, one order, however rough the journey, is a pass. Duplicates mean nothing de-duplicates payment events — and your first angry double-charged customer is a matter of traffic, not luck.

Each of these maps to a scored item in the production-readiness framework. A pass on all of them rules out the loudest failure class — the full audit covers what a browser can't reach, at a fixed price.

How it gets fixed

Sealed from the data layer up.

The order matters more than the effort: enforcement first, credentials second, proof third. Done in the wrong order, the work gets done twice while the exposure stays open. The same discipline runs through everything we deliver.

Get my scorecard
  1. 01

    Reconcile the history first

    Before any code changes, engineers diff your records against the provider's — every charge, refund and subscription state — so you know the true numbers and the size of the drift. That truth arrives with the audit, in 72 hours.

  2. 02

    Build the listener — verified and idempotent

    A webhook endpoint that receives the provider's events, verifies their signatures so forged calls are rejected, and processes each exactly once however many times it's delivered. This is the missing organ; everything after depends on it.

  3. 03

    Make provider events drive your records

    Refunds, disputes, failed renewals and cancellations now update your app the moment they happen — and the server confirms every charge with the provider directly, so checkout's claim is never again taken on faith.

  4. 04

    Handle the whole subscription lifecycle

    Renewal, retry, grace period, cancellation, refund — each state gets explicit handling and customer communication, so a failed card triggers a polite email and a dunning sequence instead of silent free service.

  5. 05

    Test the money paths, permanently

    Automated tests cover every event path — refund arrives, renewal fails, webhook replays — so billing correctness survives every future deploy. Money is the last place 'we click around' should ever be the verification story.

Where it sits in the framework

The framework's heaviest weights sit exactly here.

25 / 100

points of the production-readiness score sit in the categories this problem touches.

See every check and weight
0The full 100-point framework100
  • 15 ptsAutomated testingTests are what make the next change safe. Without them, every improvement carries the risk of a regression nobody notices until a customer does.
  • 10 ptsPayments & billingA payment form that looks correct and a payment system that is correct are very different things. This category only applies if you take money — when it does, it is unforgiving.
Our honest read
Run the count check tonight — your app's paid records against the provider's, side by side — and if the numbers disagree, believe the provider's and treat your app as the one that needs to catch up; the listening machinery it's missing is a well-defined pattern, not an open-ended project.
FAQ

The questions that follow.

QMy payment provider is a major, trusted company. Isn't this their job?
They're doing their job — flawlessly, in all likelihood. The provider charges cards, processes refunds, manages subscription states, and announces every one of those events to your app. Their side of the contract ends at the announcement; receiving it, verifying it and updating your records is application code, and only your build defines whether it exists. Every provider's documentation is explicit about this split. A perfect provider connected to an app that isn't listening produces exactly the symptoms on this page.
QThe numbers are only slightly off. Is that really urgent?
The size of the gap matters less than what it proves: events are being missed, and which events get missed is chance. This month it's a refund; next month it's a dispute — and disputes carry deadlines with the card networks that don't wait for your next manual reconciliation. Small drift is also simply the early reading of a compounding process. The mechanism, not this month's magnitude, is what deserves the urgency.
QWhat is a webhook, in plain terms?
It's how the provider calls you back. When you charge a card, your app talks to the provider — that direction works, which is why checkout succeeds. But most money events happen later, initiated by the provider: a renewal fails, a customer disputes, a refund settles. A webhook is the provider ringing your app's number to report these. If your app never set up a number to ring — no webhook endpoint — every one of those calls goes unanswered, which is precisely the failure this page describes.
QCan I just reconcile manually each month instead?
You can, and while the fix is being built you should — it's the honest stopgap. But notice what it is: a human re-deriving, monthly and after the fact, state your app should hold continuously. It scales with your volume, catches problems at month-end that customers experience immediately, and does nothing about the moments that can't wait — the dispute with a response deadline, the cancelled customer still being served today. Manual reconciliation is a bridge; treat it as having a demolition date.
QDo I owe money or apologies to customers if this has been happening?
The reconciliation tells you. Once your records are diffed against the provider's, each discrepancy becomes a specific, answerable case: customers served after cancelling, refunds that never reached your books, renewals that silently failed. In our experience most cases are small and most customers respond well to a straight correction, generously handled. What you shouldn't do is guess at the exposure before measuring it — the diff is the difference between managing a known list and fearing an unknown one.
QWhat does fixing this cost, and how long does it take?
The audit ($2K – $5K) includes the full reconciliation and the gap map, delivered within 72 hours. Building the webhook machinery, lifecycle handling and money-path tests is typically at the shorter end of 2–6 weeks — the pattern is well-defined and providers document it thoroughly — and it ships alongside your live checkout without interrupting a single sale.
Before you share anything
Your IP · 100% yours, in writing

Nobody has ever regretted sending us their repository.

Handing private code to anyone is a real decision, so everything below is settled before the audit starts rather than on request.

  1. An NDA is signed and returned before you send a linkStep one, every time
  2. Access is read-only, scoped to one repository, and time-boxedRevoked on delivery
  3. Our copy of your code is deleted when the report landsNothing retained
  4. We build for clients and never launch anything that competes with themNever has happened
No-obligation diagnosis

Send us the repository. We'll tell you what's missing.

Fixed price, 72 hours to findings, and a report you can act on with or without us. Nothing is committed until you have read it.

NDA signed before you send anything · read-only access, revoked when the report lands · our copy deleted on delivery.