Catch payment bugs before they become lost revenue.
Monitor Stripe and your application's payment records from one exception inbox.
You can load a built-in demo dataset after signing up, so you can see real findings before connecting anything of your own.
We never write to your Stripe account
Read-only by construction
PayRecon connects using a Stripe restricted key. No code path in the product issues a refund, creates a charge, cancels a subscription, or modifies any Stripe object.
We store less than you might expect
Only the fields needed for matching and evidence are kept — amounts, statuses, identifiers and timestamps. No card details, no billing addresses, no raw payloads.
Findings are explanations, not actions
An exception tells you what disagrees and what to check. Fixing it stays in your hands, in your systems.
The ten checks
Each check is a deterministic, versioned rule with a documented trigger condition, tolerance window and revenue-at-risk calculation. The same rules run against demo data and production data — there is no separate demo path.
Payment succeeded internal missing
Stripe captured a payment your application has no record of at all.
Payment succeeded internal not paid
Stripe reports a successful payment while your own record still says pending or failed.
Internal paid provider missing
Your application marked an order as paid, but no matching successful payment exists in Stripe.
Payment amount mismatch
The amount Stripe captured differs from the amount your application recorded.
Payment currency mismatch
The two sides of the same payment disagree about the currency.
Duplicate succeeded payment
One customer was charged more than once for what looks like a single purchase.
Refund status mismatch
A refund exists on one side only, or the refunded amounts disagree.
Paid invoice inactive subscription
An invoice was paid against a subscription that is cancelled, unpaid or expired.
Failed invoice active subscription
A subscription is still serving the customer while its invoices are failing.
Stale internal pending payment
A payment has been stuck in a pending state far longer than it should take to settle.
How it works
Connect Stripe, read-only
Paste a Stripe restricted key with read permissions. We validate what it can actually read and store it encrypted.
Bring your own records
Upload a CSV of your payment records or push them through the API. Re-importing the same file changes nothing — imports are idempotent.
Deterministic rules run
Versioned TypeScript rules compare both sides on a schedule. No model guesses at whether two payments are the same.
Work the exception inbox
Each finding carries side-by-side evidence, probable causes, recommended next steps, and a full audit timeline.
What it does not do
- It does not convert between currencies. Revenue at risk is reported per currency, as separate figures, because summing unlike currencies without a sourced rate would be misleading.
- It does not close findings on your behalf. An exception that stops being detected stays open until someone decides it is resolved, and that decision is recorded.
- It does not use a language model to decide whether two payments match. Matching favours explicit provider transaction identifiers, and ambiguous data is surfaced as ambiguous rather than guessed at.