How Payment Verification Works on Tagihin
Payment verification on Tagihin today has two layers, each honest about its limits. Layer one: every transfer proof a client uploads is SHA-256 hashed and checked against a platform-wide duplicate ledger — the exact same screenshot previously used on any other invoice is automatically flagged as a duplicate. It catches byte-for-byte identical files, not edited images. Layer two: an invoice only flips to Paid after your one-tap confirm — ideally once the funds show in your account mutation or in the QRIS notification from your PJP app, the strongest confirmation because it comes from the payment system. On the Pro-tier roadmap: bank-mutation auto-verify, Moota-style — an API watches your account mutations, and an incoming credit matching the exact amount auto-marks the invoice Paid. That feature is not live yet: today, no invoice is ever auto-marked paid.
Plenty of tools promise “fake transfer-proof detection” — a promise impossible to keep, because an Indonesian transfer proof is just a screenshot with no verifiable payload. Tagihin takes a different path: we spell out exactly what the system checks, what it cannot check, when an invoice flips to Paid, and which features are still plans. This guide documents Tagihin’s payment-verification flow end to end.
By the Tagihin team · Updated 10 Jun 2026
Note: this page describes Tagihin features as they are, limits included. Tagihin is not a PJP, not a payment gateway, and never holds your money — funds always flow straight from the client to your account via your own PJP or bank. Features marked “planned” may change before release.
The core principle: an image is not money
The only proof of money received is a record on your own side: the account mutation in your mobile banking, or the payment notification from your PJP’s merchant app. A proof-of-transfer image can be edited, reused, or lifted from an old transaction — and Indonesia has no official mechanism to verify a screenshot against a bank’s system. Tagihin’s entire verification design is therefore built on one rule: the system may help filter and flag, but the decision that “this money really arrived” must rest on a source the buyer cannot fake.
Why transfer proofs are easy to fake — and the four checks that actually work — is covered separately in the guide on how to check whether a transfer proof is real.
Live today: the SHA-256 duplicate ledger
Every Tagihin invoice has a payment page with a dynamic QRIS QR and a transfer-proof upload option. The moment a client uploads their proof image, this is what happens behind the scenes:
- The image is stored as-is, then its full byte content is hashed with SHA-256 — a cryptographic fingerprint that changes completely if even one byte differs
- That hash is checked against a platform-wide duplicate ledger: every proof ever uploaded on Tagihin — on your invoices or any other merchant’s
- If the exact same image was ever used on another invoice, the proof is immediately flagged as a duplicate and surfaced loudly on your dashboard — the reused-screenshot trick, the most common form of proof fraud, gets caught here
- If the hash has never been seen, the status is awaiting confirmation — a normal proof waiting for your one tap
Two design details keep it fair. First, a client who accidentally uploads the same image twice to the same invoice (a double tap, a dropped connection and retry) is not flagged — only the same image used across different invoices counts as suspicious. Second, the check never blocks an upload: if verification itself hiccups, the proof is still accepted and lands in your manual-confirmation queue as usual.
The limit we state outright
Hash matching works on byte-for-byte identical files. An image that is edited, cropped, re-screenshotted, or recompressed produces a different hash and will not be caught. That is why Tagihin never markets this feature as “fake-proof detection” — what it detects is reuse, not forgery. The final layer remains your own eyes on your account mutation or QRIS notification, and that is where the one-tap confirm comes in.
The one-tap confirm: you decide when it is Paid
On Tagihin today, no invoice flips to Paid without your decision. An incoming proof only adds an “awaiting confirmation” signal to the invoice on your dashboard and bill list — its status stays unpaid until you tap confirm. The ideal flow is simple: proof-received notification → check your account mutation or QRIS notification → amount matches → one tap → the invoice is Paid and the kwitansi is issued automatically. The figure you match is what the client actually had to transfer — the invoice total after PPh withholding, where it applies.
The dashboard signal deliberately comes in three levels so nothing can hide: a normal proof shows as awaiting confirmation, a problem proof (duplicate — or later, an adapter amount mismatch) shows as needs review, and eventually a bank-mutation-verified proof will show as system-confirmed. All three still need your decision — the difference is only how loudly the system speaks.
| Verification status | What it means | Live? |
|---|---|---|
| Awaiting confirmation | First time this image was seen; check your mutation, then confirm | Yes |
| Duplicate | The exact same image was used on another invoice — most likely a reused screenshot | Yes |
| Verified | The bank-mutation adapter found an incoming credit matching the exact amount — the invoice is auto-marked Paid | Planned (Pro) |
| Mismatch | The adapter searched your mutation feed and found no matching credit | Planned (Pro) |
| Check failed | The verification provider had trouble (quota/outage) — not a fraud signal; falls back to manual review | Planned (Pro) |
The QRIS path: the strongest confirmation, with no image at all
The best verification is the kind that needs nothing from the buyer at all. When a client pays a Tagihin invoice via QRIS, your PJP’s merchant app — GoPay Merchant, DANA Bisnis, or the mobile banking your QRIS is registered with — sends a real-time payment notification. That notification comes from the payment system, not from the buyer, so no screenshot can fake it.
Tagihin’s dynamic QR makes the matching trivial. Every invoice carries a QRIS QR with the exact amount locked inside the code (derived from your own static QRIS — the money path is unchanged), so one QR = one invoice = one amount. When your PJP notification pings, you match a single number: the amount in the notification equals the invoice amount, done. No transfer proof to upload, no image to second-guess.
How static → dynamic conversion works (and why funds still settle to your own account) is covered in full in the QRIS guide for freelancers, and you can try it without an account via our free dynamic-QRIS tool.
Pro roadmap: bank-mutation auto-verify (Moota-style)
For plain bank transfers — the payment path with no PJP notification — we are building the authoritative layer into the Pro tier: automatic bank-mutation verification. The model is already proven in Indonesia by services like Moota: you connect your own bank account, an API polls its mutation feed, and every incoming credit is matched against invoices awaiting payment.
How it will work once live: the client uploads a transfer proof as usual, then — after passing the duplicate check — the adapter searches your account mutations for an incoming credit matching the exact amount within a window of the last few days. Match found? The invoice is auto-marked Paid, because that mutation sits on your own account — if the amount landed, the money is really there, with no receiver ambiguity. No match? The status becomes “mismatch” and the invoice waits for your manual handling. Provider trouble? “Check failed” — not an accusation of fraud, just a fallback to the manual confirm flow. This is where exact-amount QRs help again: because every invoice carries its own distinct figure, amount matching is almost never ambiguous.
Today’s status, no spin: this feature is not live. The adapter exists in the code as a deliberately dormant seam — until the integration ships, no invoice is ever auto-marked Paid, and neither “verified” nor “mismatch” can appear on your account. Connecting an account will also always be your choice, never a requirement: it grants a third party read access to your mutations, and that decision deserves to be made consciously.
What we will never claim
- “Tagihin detects fake transfer proofs.” No — an edited image produces a different hash and passes the duplicate check. No party anywhere can verify a screenshot’s authenticity from the image alone.
- “Invoices auto-flip to Paid when a proof is uploaded.” No — today, Paid always goes through your confirm. Bank-mutation auto-verify is still planned, and even at release it only runs if you switch it on.
- “Your money passes through Tagihin.” Never — clients pay your QRIS or transfer to your account; funds settle directly via your own PJP or bank. Tagihin is an invoicing and document tool, not a payment processor.
- “The duplicate check reads your image’s contents.” What gets compared platform-wide is only the SHA-256 hash — a mathematical fingerprint of the file, not a cross-merchant analysis of what the image shows.
Invoices with exact-amount QRIS QRs, duplicate-proof checks, and one-tap confirmation (free plan available).
Read next
References / Sources
- Primary sources
- Bank Indonesia — Quick Response Code Indonesian Standard (QRIS)
- Bank Indonesia — BI-FAST: real-time interbank transfers
- NIST FIPS 180-4 — Secure Hash Standard (SHA-256)
- Secondary sources
- Moota — automatic bank-mutation checking service (the model behind the planned auto-verify)
- BCA — Awas Modus: official warnings on fake transfer proofs
- OJK Sikapi Uangmu — consumer education on digital-transaction fraud
Information as reviewed on 10 Jun 2026. Features marked “planned” are not yet available and their details may change before release; this page will be updated the moment they go live.