All articles

How to automate provider invoice reconciliation: the build, step by step

Five stages: the contract as versioned data, events at transaction grain, deterministic repricing, a categorised exception queue, and recovery that writes the cause back upstream.

How to automate provider invoice reconciliation: the build, step by step

TL;DR

  • Provider invoice reconciliation is not AP three-way matching; there's no purchase order or goods receipt, only a fee schedule and a stream of events to check against it.
  • The build is five stages: contract terms as versioned, dated data; transactions at transaction grain, not invoice summaries; deterministic repricing; a categorized exception queue with owners and deadlines; and recovery feeding fixes back upstream.
  • Most teams build stage three (the repricing engine) while skipping stage two, so verification runs on invoice summaries instead of raw transaction data and produces nothing that can be disputed.
  • Exceptions need a category (rate deviation, fee overcharge, FX markup, missing fee, duplicate fee, timing violation), an amount with its trace, an owner, and a deadline set by the contract's actual dispute window.

Short answer

Automating provider invoice reconciliation is a five-stage pipeline. The contract becomes versioned data. The transactions arrive at their own grain. A deterministic engine reprices every one of them. Differences land in a categorised queue with an owner and a deadline. Recovery closes the loop and writes the cause back upstream.

Most teams get stage three working and quietly skip stage two. That is why their verification never produces evidence anybody can act on.

This is the build. For the reasoning underneath it, how a signed contract becomes a per-transaction check covers the logic, and the buyer's guide covers whether to buy or build at all.

First, what you are not building

Search for invoice reconciliation software and you will find accounts payable automation. The category is defined by matching a supplier invoice against a purchase order and a goods receipt, a pattern the market calls three-way matching. It is a real problem and it is solved well by mature products.

Provider invoice reconciliation has neither of those two reference documents. There is no purchase order, because you did not order a fee. There is no goods receipt, because nothing was delivered to a loading bay.

What you have instead is a contract that prices events, and a stream of events. The reference document is a fee schedule, and the question is whether each event was priced the way the schedule says. Three-way matching cannot answer that, and neither can a tool built around it.

That distinction decides your architecture, so it belongs at the front of the build rather than halfway through it.

Stage 1: turn the contract into versioned data

Your fee schedule is a document. The engine needs it as rules.

The modelling work is finding every term that changes a price: the base rate by card type and channel, the tiers and their thresholds, the FX handling, the settlement and payout charges, the minimums, the periodic fees, and the true-up mechanics. All of it, per corridor and per currency where they differ.

Then the part almost everyone underbuilds. Every rule carries an effective date, and the rule set is addressable by settlement date. Contracts get amended. A rate card changes in March. If your model holds only the current terms, every check you run against February silently uses the wrong price, and the output looks clean because nothing errored.

Rule of thumb for the schema: if a term can change without the whole contract being replaced, it needs its own effective date.

One caution on scope. Some of what you are billed is not priced by your agreement at all. The merchant service charge, as the UK regulator defines it, comprises interchange fees, scheme fees and acquirer net revenue. The first two are pass-through, so your contract governs how they are passed on rather than what they are. Model that boundary explicitly, or your engine will flag a legitimate interchange change as a contract breach.

Stage 2: get the events at transaction grain

This is the stage that decides whether the whole build works, and it is the one teams skip.

The temptation is to start from the invoice. It is already in your inbox, it is already summarised, and parsing it feels like progress. It is also the document under test. Reconciling an invoice against itself proves nothing, and any aggregate the provider has already computed has removed the evidence you need.

So the input is transaction-level: settlement files, transaction reports, payout files. One row per event, carrying enough attributes to reprice it. Card type and issuer type. Channel. Corridor and currency pair. The authorisation timestamp and the settlement timestamp, separately, because timing itself is a discrepancy category. The FX rate applied, where one was.

Two engineering notes worth building in from the start:

Idempotency. Providers re-issue files. Your ingestion has to be safe to run twice on the same day without double-counting, which means a stable natural key per event rather than a load-order id.

Completeness checks. Count and value totals per file, reconciled against the provider's own control totals. A silently truncated file produces a verification run that passes because the wrong charges were never loaded.

Stage 3: reprice deterministically

Now the engine. For each event, compute what the contract in force on its settlement date says it should have cost.

Three properties matter more than speed.

Deterministic. The same event and the same contract version produce the same number every time. No model, no estimate, no tolerance band. This is the part that has to survive a provider's pushback, and a number that varies is not evidence.

Ordered. Terms interact. A tier threshold applies before or after an FX conversion, a minimum applies at a different level than a per-transaction fee, and the sequence changes the answer. Get the order from the contract rather than from what is convenient in code.

Dated. Every computation records which contract version it used. When someone asks why February differs from March, the answer has to be in the output rather than in somebody's memory.

The two-pass method for building an expected figure and then assembling the actual one is set out in how to calculate your true provider cost per transaction. The pipeline is that method, run continuously instead of once.

Stage 4: build an exception queue, not a report

A report is where discrepancies go to be admired. A queue is where they get worked.

Every difference between expected and actual becomes an exception, and every exception carries four things:

  • A category. We use six: rate deviation, fee overcharge, FX markup, missing fee, duplicate fee, timing violation. The taxonomy explains what separates them, and the categories matter because they route to different fixes.
  • An amount, and its trace. The expected figure, the billed figure, the contract clause that produced the expectation, and the event id.
  • An owner. A named person, rather than a team inbox.
  • A deadline derived from your dispute window. Not an internal target you invented. Provider contracts cap how long you have, and the queue's clock has to be that clock.

Then two rules that keep the queue usable. Set a materiality floor, so a thousand two-cent roundings do not bury a real finding. And group exceptions by root cause rather than by transaction, because five thousand events failing the same tier rule is one problem with one fix.

Stage 5: recover, then write the cause back

Recovery is a workflow with its own steps, and the pipeline's job is to feed it evidence-grade packages rather than suspicions.

The part that gets left out is the return path. Every resolved exception has a cause, and the cause belongs somewhere upstream:

  • A contract term you modelled wrong goes back to stage 1.
  • A missing data attribute goes back to stage 2.
  • An ordering bug goes back to stage 3.
  • A provider-side error goes into a pattern log, because the second occurrence of the same error is a much stronger commercial conversation than the first.

Without that path you have built a detector. With it you have built a control, and exception volume falls over time instead of holding steady.

What stays manual, honestly

Three things, and pretending otherwise is how these projects lose credibility internally.

The first contract model. Reading a fee schedule and deciding what each clause means is judgment work. Expect a person to do it, and expect it to take longer than the ingestion.

Ambiguity. Real contracts contain terms that two reasonable people read differently. The engine cannot resolve those. It can flag them, which is more useful than guessing.

The commercial conversation. Evidence does not negotiate. Somebody still has to take the package to the provider.

If you cannot build all five

Build them in this order, and stop wherever your resources stop. Each stage is useful on its own.

  1. Stage 2 first. Clean transaction-level data with completeness checks has value with no engine at all, because it makes every later question answerable.
  2. Then stage 1, for your largest provider only. One contract modelled properly beats five modelled approximately.
  3. Then stage 3, on one fee type. Processing fees usually, since they are the largest line and the simplest rules.
  4. Then stage 4. The moment you have real exceptions, they need owners and deadlines, or they rot.
  5. Stage 5 last, because you cannot recover what you have not yet proved.

Teams that start at stage 3 build an engine with nothing trustworthy to run on. Teams that start at stage 4 build a queue that fills with false positives and gets abandoned in a month.

The bottom line

The hard part of this build is not the maths. It is the two things either side of it: contract terms modelled as versioned data, and events captured at a grain the invoice has already destroyed.

Get those right and repricing is arithmetic. Get them wrong and no amount of engine sophistication produces a number a provider will accept.

Bluefyn reconstructs contract pricing and checks fees transaction by transaction, so expected against actual becomes provable rather than estimated. Bluefyn never moves, holds or custodies funds. It analyses transaction and provider data.

A charge can reconcile perfectly and still be wrong. The build above is what tells the difference.

Frequently asked questions

Is invoice reconciliation software the same as provider fee verification?

No. Invoice reconciliation software, as the market uses the term, automates accounts payable: matching a supplier invoice against a purchase order and a goods receipt. Provider fee verification has neither document. It compares each transaction against the contract that priced it, which is a different reference and a different architecture.

What data do I need before I can automate any of this?

Transaction-level settlement data rather than invoice summaries. Each row needs card and issuer type, channel, corridor, currency, the authorisation and settlement timestamps separately, and the FX rate where one applied. Without that grain you cannot reprice an individual event, and an aggregate cannot be disputed.

Why does the contract need effective dates?

Because contracts get amended and checks get run against past periods. If your rule set holds only current terms, every historical verification uses the wrong price and reports a clean result. Dating the rules is what makes an old period checkable.

How do I stop the exception queue filling with noise?

Set a materiality floor, and group exceptions by root cause rather than by transaction. Thousands of events failing one tier rule is a single problem. Left ungrouped it looks like thousands of problems, and the queue gets abandoned.

What should I build first if I only have one engineer?

Transaction-level ingestion with completeness checks, for your largest provider. It is the foundation every later stage sits on, and it makes questions answerable even before any repricing exists.

Automation is also the fastest way to cut the cost of a reconciliation team.

What software can reconcile provider invoices with contract pricing?

Generic invoice reconciliation software matches a supplier invoice against a purchase order and a goods receipt, and provider fees have neither document, so that category does not apply. What works instead is software that models the fee schedule as versioned rules and reprices every transaction against the contract that priced it. Bluefyn does exactly this, reconstructing contract pricing and checking fees transaction by transaction, without moving, holding, or custodying funds.

ReconciliationVerificationFee recoveryProvider economics
BF
Bluefyn Team
Bluefyn

Operators and engineers building the economic control plane for fintech infrastructure.

Run one benchmark. One contract.

Send one provider contract and a month of statements, in whatever format they exist. We reconstruct the pricing, verify the transactions, and show you the discrepancies on your own numbers.

Request access

Start with one contract. No integration required to see the first findings.

Bluefyn never moves, holds, or custodies funds.