As long as your customer pays by bank transfer, reconciliation is simple: one payment, one invoice number in the title, the accountant ties it in the ERP in five seconds. Add Przelewy24, PayU or Stripe to the mix — and suddenly nothing lines up. It's not the system's fault; it's a different data model.
We see this at clients all the time. The company opens a webshop or a B2B portal, switches on three popular gateways, within a week they have orders. After a month, the accountant comes with a question: why does the bank account show 48 lump-sum payments while the ERP has 312 orders, and how do we reconcile this now. The answer isn't in the ERP and it isn't in the gateway — it's in the fact that nobody designed the middle layer that connects one to the other.
An online payment gateway is not another bank account. It's a separate system with its own logic, its own fees, and its own payout rhythm. Treat it like "one more account to import into Optima" and after three months you'll have 40–60 thousand PLN in a "to clarify" line.
Why it falls apart
In the traditional model the customer pays 1,230.00 PLN into your bank account, puts FV/2026/0421 in the transfer title, the accountant imports the MT940 bank statement into Comarch Optima and matching happens automatically. One to one. The gateway problem is that this model breaks on three levels at once.
Level one — net payout, not gross. The customer pays 1,230.00 PLN by card via Stripe. Your bank account receives 1,190.65 PLN, because Stripe took a 3.2% fee. The ERP sees that the invoice was for 1,230.00 — and matching doesn't happen, because the amounts don't agree. If you set up a rule "ignore differences up to 5%", you'll get lost on the first chargeback, which will also come in as a "difference up to 5%".
Level two — a batched payout, not one per transaction. PayU and Przelewy24 in their default SME plan pay out once a day or once every two days, in batches. You receive a 12,437.22 PLN transfer that represents 54 transactions across two days, reduced by fees, reduced by one refund and one chargeback. The title says "PayU settlement 2026-10-24". Zero invoice numbers. Unpack it by hand.
Level three — multi-currency and cross-border. Stripe pays you out in EUR or USD if you enable international card acceptance. The ERP is in PLN. Currency conversion happens at the bank at the rate at the moment of payout, not at the moment of order. The exchange difference is a separate line in your P&L — the ERP won't calculate this on its own, because it doesn't know what rate was "expected".
Each level on its own can be handled manually in a spreadsheet. Three at the same time, with 300 orders a month, can't. You need to build an integration.
The three parts you need to connect
A well-designed gateway–ERP integration is three separate mechanisms — not one script that "syncs everything". One mechanism = one responsibility.
- Payment status webhook. The gateway calls your endpoint the moment a payment succeeded, failed, got refunded, or ran into a chargeback. This is the "something changed on this specific transaction" signal — and it should update a specific order in the ERP, not an entire batched settlement. The webhook has to be idempotent: the same gateway can send the same event three times if it briefly doesn't get a 200 response. Three times doesn't mean we book it three times — it means we book it once, then ignore the duplicates.
- Daily gateway report. Przelewy24, PayU, Stripe and tpay all expose an API or a CSV with a detailed settlement — one line per transaction, with fee, VAT on the fee, refund, chargeback. This report is your source of truth for booking all the costs of the gateway. It's flat and ugly, but it's complete.
- Match the bank statement against the gateway report, not against orders. This is the whole trick. The ERP should not try to match a 12,437.22 PLN payment with 54 orders simultaneously. It should match 12,437.22 PLN with the gateway report for 2026-10-24 — and the gateway report already knows separately which orders it contained, because it saw them through webhooks. Three stages, three separate reconciliations, each by one criterion.
Once you have those three mechanisms arranged separately, a chargeback from Przelewy24 that lands two weeks after the transaction doesn't blow up the month-end close anymore — because you know which transaction it refers to and how to reflect it in the ERP.
A concrete real-world example
At one of our clients — a 28-person webshop selling home and garden furniture — payment gateways were plugged in from day one: Przelewy24 as the main one, PayU for 0% instalments, Stripe for international customers. Comarch Optima as the ERP, WooCommerce as the shop, shop–ERP integration via API. Monthly volume 450–600 orders, revenue around 480 thousand PLN gross.
Before the cleanup, settlement looked like this: once a week the accountant imported the bank statement into Optima, looked at the lump-sum gateway payments and manually matched them to orders by cross-checking the panels of Przelewy24 and PayU separately. Fees were booked in bulk based on a monthly debit note that each gateway sent. Refunds and chargebacks appeared randomly — sometimes as a minus on a batched payment, sometimes as a separate outgoing transfer. The "to clarify" line in the trial balance always had 15–25 entries, totalling 20–35 thousand PLN each month.
The problem compounded at quarter-end, because unexplained entries piled up. In March and June 2026, two days before quarter-end, they had to do a "gateway inventory" — the finance director would spend four to six hours with the accountant matching unlinked transactions. Every two quarters 20–30 thousand PLN landed in the exchange-difference and fee account because nobody could tie it back to specific orders anymore.
The rebuild took six weeks and fit in a 32 thousand PLN budget. We set up a small middleware (one small .NET application on their server) that receives webhooks from all three gateways, stores the state of each transaction in a database, pulls settlement reports from the gateway APIs daily and feeds three separate accounting documents into Optima: a sales invoice (order), a cost note for the gateway fee (expense), and a CASH document for the batched payout that matches against the bank statement 1:1. Refunds and chargebacks are reflected as corrections, linked to the original transaction.
After three months, the "to clarify" line fell from 20–35 thousand to 0.5–1.5 thousand PLN per month — mostly from EUR–PLN rounding on Stripe. Quarter-end no longer required a "gateway inventory". The accountant got back around 6–8 hours a week that used to go to manual matching. For the first time the finance director knew what online payments really cost them — it came to 3.8% of revenue, or around 18 thousand PLN a month, mostly on PayU 0% instalments, where the fee is passed through to the shop.
Three traps we see most often
There are three patterns that make gateway–ERP integrations fall apart after six months. Each one is easy to avoid if you know about it up front.
- "Order = invoice = payment", with no memory of the fee. The company only books the sales invoice and the net-of-fee payment in the ERP, because "the difference is the gateway fee". That works — until the first tax inspection, which asks why there's no VAT recorded for the 3.2% fee. The gateway fee is a separate cost, a separate invoice (the gateway has to issue one to you), a separate VAT entry. The ERP has to see both sides.
- Webhook without idempotency. Sometimes the gateway sends the same event twice — because the first response from your endpoint arrived late and the system considered it lost. If your middleware doesn't check whether this transaction was already processed, you'll book two invoices for one sale. Idempotency = you store the event ID in a database, don't process it a second time, and respond 200.
- Testing on "pending" instead of a completed webhook. Sometimes a developer pulls all orders with status "pending" from the shop and pushes them to the ERP, because they want them "visible immediately". Then the customer abandons the payment, the gateway sends no webhook, and the ERP is left with an invoice nobody will pay. Rule: create the invoice in the ERP only after a
PAIDwebhook, never earlier.
Each of these traps can be fixed with a few lines of middleware code — as long as you anticipate them before launch, not after the first quarter of settlements.
What to do this month
If you process more than 100 thousand PLN a month through gateways and have no ERP integration, you're probably already paying an ignorance tax in the form of unexplained entries and uncaptured fee costs. Start with three steps you can take without a big project.
- Take the last three months — how often did the accountant have to "manually match" something, and what's the current value of the "to clarify" line. If it's more than 1% of monthly revenue, the integration will pay off within six months.
- In the gateway panel, check whether the webhook is even enabled — and where it points. At half of the clients we visit, the webhook still points to the old shop domain, because nobody changed it after a migration two years ago.
- Download the settlement report for one month from the gateway panel as a CSV. Look at the fields — gross amount, fee, VAT on the fee, status, order ID. This is exactly the data that should land in the ERP, and it's the minimal shape of the integration.
After those three steps, you already know whether the problem exists at all, and how big it is.
What next
Online payments aren't hard in themselves — they're hard because they have a different data model from banking. If you treat the gateway as "one more account to import", you'll be losing time and money every month. If you build a middle layer that translates the gateway's language into the ERP's language, it stops hurting.
This isn't a big project. For a small company, two to six weeks of one person's work plus a simple middleware. For a larger one with several sales channels and several gateways, one to three months. The return is usually inside half a year — mostly on the accountant's recovered time, and on no longer topping up a "differences" account with sums that should have been a cost of a specific transaction.
If you'd like us to look at your setup — gateways, shop, ERP, the current way of reconciling — we'll show you where the holes are and roughly how large. The first conversation is free and takes half an hour.
A payment gateway isn't a bank statement. It's a separate system with its own logic — and if the ERP doesn't know this, every month you're paying for it in ignorance, not in fees.