payments · architecture · OCR · LLM

Zero false positives: designing a payment verifier that never lies

How TasdeeqPay confirms manual bank transfers automatically without ever confirming one that didn't happen — and why biasing toward the cheaper error is the whole game.

27 June 20262 min readAhmad Muteen

Pakistani merchants reconcile a lot of payments by hand. A customer sends a bank transfer, screenshots the receipt, and someone on the merchant side eyeballs it against the order and the bank alert. It’s slow, and worse, it’s error-prone in an expensive direction: mark an order “paid” when it wasn’t, and the merchant just shipped for free.

TasdeeqPay automates that reconciliation. The design rule that shaped everything: never confirm a payment that didn’t happen.

Three sources, one agreement

The engine doesn’t trust any single input. It cross-matches three independent signals:

  1. Order data — what was owed, to whom.
  2. The customer’s payment screenshot — read via OCR into structured fields.
  3. The merchant’s bank alert — the ground truth the bank itself emitted.

Only when all three agree does the system confirm. Partial agreement is not a “probably” — it’s a hold for human review.

Why bias toward the cheaper error

Every classifier makes two kinds of mistakes. In payments they are not equal:

  • A false positive (confirming a payment that didn’t clear) costs the merchant the value of the goods.
  • A false negative (missing a real payment) costs one manual check.

So the system is tuned to eliminate the first at the expense of tolerating the second. That’s not timidity; it’s matching the failure mode to the real-world cost.

Let the model read, not a brittle parser

Every bank formats statements differently. The naive approach is a hardcoded parser per bank — which breaks the moment a layout changes. Instead, an LLM extracts the fields. New statement format? It generalizes instead of throwing. The determinism lives in the matching logic; the flexibility lives in the reading.

The unglamorous part: getting the alert off the phone

Bank alerts land on an Android phone, and Android OEMs are notorious for killing background apps to save battery. The companion app uses an outbox pattern hardened against exactly that — the alert is persisted the instant it arrives and forwarded reliably, not “best effort.”

The lesson generalizes: correctness at the core is worth nothing if the pipe feeding it drops messages.

A
Ahmad Muteen
AI-native product builder · Islamabad
← The LibraryWork with me →