Matching bank transfers to orders automatically
Bank transfer is a perfectly good payment method until a human has to check the account and tick things off. That is the part to automate.
Why bother
Some categories cannot get card processing. Some businesses prefer to avoid the fees. Bank transfer solves the payment and creates an operational problem: money arrives with no connection to the order it belongs to, and someone has to make that connection before anything ships.
Done manually, that is a delay measured in hours, which is exactly the window where customers ask where their order is.
The mechanism
Poll the account through its API on a short interval. For each incoming credit, try to match it to an unpaid order. On a confident match, mark the order paid and trigger everything downstream. On anything else, leave it alone and flag it.
Matching rules
The reference is your primary signal, which is why the reference has to be something the customer will actually type. Show it prominently at checkout, in the confirmation email, and phrase it as an instruction rather than a label.
Be forgiving when comparing. Strip spaces, punctuation and case. People add words, drop prefixes and use their own shorthand, so a contains match on the normalised reference beats an exact match.
Then require the amount to agree, exactly. Reference plus amount is a strong match. Reference alone is not, because references get reused when someone pays for a second order by copying the first payment.
What to do with the rest
Anything that does not match cleanly should be surfaced, never guessed. Underpayments, overpayments, two orders paid in one transfer, a reference from a different business. Each needs a human, and each is rare enough that alerting is cheap.
Resist widening the rules to catch these. The cost of a wrong automatic match, dispatching against someone else's money, is far higher than the cost of looking at one payment by hand.
Operational notes
- Make the whole thing idempotent. You will poll the same transaction repeatedly, and it must only ever mark an order paid once.
- Keep the credentials off the application host if the API uses certificates or keys, and mind file ownership when mounting them into containers.
- Alert on every successful match too, at least early on. Watching it work is how you gain enough confidence to stop watching.
Need help with any of this?
These notes are free and always will be. If you would rather someone just set it up, or you are stuck on something similar, get in touch at hello@opsira.io.