Finance operations

Contractor invoice automation: from the monthly HR sheet to paid, without retyping

Contractors were retyping numbers finance already had. We built a portal that pre-fills invoices from the HR sheet, checks early ones line by line, and marks them paid on schedule.

On this page
  1. Where contractor invoicing breaks every month
  2. Why AP tools and spreadsheets don’t fit contractor invoices
  3. Contractor invoice automation that starts from the HR sheet
  4. Reconciling early contractor invoices with HR data, line by line
  5. Multi-entity VAT and bank details that can’t quietly drift
  6. Scheduled payment jobs that can’t fail silently
  7. What we’d harden next, plus a checklist for your team
  8. Questions we hear

The short version

  • Good contractor invoice automation starts from data finance already trusts: invoices arrive pre-filled from the HR sheet, and contractors confirm or flag them.
  • Early submissions go to a waiting room where each line is labeled match, mismatch or addition.
  • When the formula and the spreadsheet disagree, finance picks the winner once, and later recalculations respect that choice.
  • Freeze VAT per invoice, send bank changes to finance for approval, and give background jobs retries and a dead-letter queue.

Where contractor invoicing breaks every month

It’s the second working day of the month. Finance has the HR export on one screen and a pile of contractor invoices on the other, checking every line by hand. Most of those numbers came from finance in the first place, which is why contractor invoice automation should start from your data, not the contractor’s PDF.

One contractor billed 21 days; the sheet says 20. Another used last month’s rate. A third submitted before the month ended, and a fourth emailed new bank details, which is how payment fraud often starts.

Each mismatch means an email, a wait and a corrected PDF. Then every approved invoice is typed again into the ERP, once per legal entity.

66%

of AP teams still enter invoice data into ERP systems by hand

IFOL, Accounts Payable Automation Trends 2025
67%

of UK firms with 250+ staff still reconcile accounts in Excel

Sixthfin research by Odoxa, via IT Brief UK

Our engineers built a portal on that principle for a company paying contractors through two legal entities in different countries. It is live in production, part of our ERP and business systems work.

Why AP tools and spreadsheets don’t fit contractor invoices

Most accounts payable software assumes a supplier invoice matched against a purchase order. A contractor’s invoice restates data you already hold: working days, a daily rate, an FTE share (the fraction of full time they work), plus commission, bonuses, expenses and corrections.

  • OCR and three-way matching (reading the PDF, then checking it against a purchase order and a goods receipt) still start from the contractor’s numbers, and need a PO contractors rarely have.
  • Spreadsheet formulas drift when a rate changes mid-month, and a silent recalculation can overwrite a decision finance already made.
  • Email back-and-forth turns every disagreement into a rejected invoice and a new PDF.
Who types the numbers decides the workload
Contractor-typed invoices
  • Contractors type days, rates and totals
  • Finance checks every line against the HR sheet
  • Disputes mean a rejected invoice and a wait
  • Early invoices mix with final ones
Pre-filled invoices
  • Figures come from the approved HR sheet
  • Finance reviews only the lines that disagree
  • Disputes are flagged on the exact field
  • Early submissions wait in a separate queue

Contractor invoice automation that starts from the HR sheet

Finance uploads the monthly HR sheet, and the portal turns each row into an invoice the contractor only has to check. Releasing a period creates one invoice per contractor, legal entity and month, marked pending submission.

One month, from HR sheet to paid
  1. Import the HR sheet

    Each row is matched exactly to a legal entity and an active billing assignment.

  2. Run pre-release check

    The portal recomputes days × rate × FTE and lists every disagreement with the sheet.

  3. Release the period

    Invoices are created, and each contractor gets one email and in-app notice.

  4. Confirm or flag

    The contractor submits, or flags specific fields for review.

  5. Mark paid on schedule

    On the payment date, a background job marks submitted invoices paid and emails a confirmation.

Once a period is released, finance doesn’t send invoices back. Contractors flag a field with a comment instead, ending the reject-and-resubmit loop. Only an early waiting-room submission can be returned.

The contractor invoice approval workflow has five states: pending submission, review requested, waiting room, submitted and paid.

When the formula and the sheet disagree

The portal calculates the service amount itself and treats the sheet’s figure as the expected value. Mid-month rate changes and part-time FTE make them differ for honest reasons. A pre-release check flags any gap over 0.01.

Finance picks the calculated or the HR figure. Picking the HR figure saves it on the invoice as an override, which later recalculations use unless finance edits the days or rate.

When two sources disagree about money, a person should decide once and the system should remember.

Reconciling early contractor invoices with HR data, line by line

Some contractors submit before finance has released the period. Those invoices go to a waiting room, a holding area where finance reviews them against HR data.

Without a release, the server accepts only the current month, even through a direct API call.

Each component is compared with the HR figure, within a one-cent tolerance:

  • Match: invoiced, and equal to the HR value.
  • Mismatch: invoiced, but different. Finance sees both values and corrects one.
  • Addition: in the HR data but missing from the invoice, such as a bonus. It is pulled in, not flagged.

Two details keep false alarms down. The grand total is deliberately not compared, since any real difference already shows on its own line. Expenses-only invoices skip the working-days and services rows, so a zero never reads as a mismatch.

The database itself refuses a second live invoice for the same contractor, period, entity and category (standard, or expenses-only). It is a partial unique index.

Multi-entity VAT and bank details that can’t quietly drift

VAT rules that never guess

We match VAT rules on legal entity and contractor region exactly, with no fallback to “any rule for this entity”. If nothing matches, the invoice carries no VAT and a warning goes to the server log.

A reverse-charge rule (the buyer accounts for the VAT, not the contractor) applied to the wrong region is worse than none, because it looks right. It applies only when the contractor’s profile has the reverse-charge flag set.

The result is frozen at submission in a VAT snapshot: rule, code, rate, amount, operation and invoice clause. Editing a rule next quarter never rewrites last quarter’s invoices.

Stopping bank-detail change fraud: validate, encrypt, review

In the AFP’s 2025 survey, 45% of respondents cited vendor imposter fraud, where a criminal poses as a supplier. That share rose 11 percentage points.

  • One validator for form and server. An IBAN checksum is a built-in typo detector. We check each country’s known length (22 characters for GB) and the ISO 7064 mod-97 checksum. Form and server share the module, so they can’t disagree.
  • Encryption at rest. IBANs and account numbers are encrypted with AES-256-GCM, so a leaked database dump shows only ciphertext.
  • Approval for every change. Each changed bank field raises a change request with old and new values for finance to approve or reject, and a rejection restores the old value.

Scheduled payment jobs that can’t fail silently

Each service month has a payment date, by default the 20th of the following month. A nightly job should mark that period’s submitted invoices paid.

The first version looked up the current month’s calendar row and asked whether today was its payment date. It never was, because that date sits in the following month. The job skipped silently, so nothing was marked paid automatically.

The fix looks calendar rows up by payment date and works out which service months that date settles. Month boundaries are computed in UTC, so server time zones can’t shift them.

How a background job fails safely
  1. Cron publishes

    The scheduler only puts a message on a durable queue; a separate worker does the job.

  2. Worker consumes

    If a worker crashes mid-job, the unacknowledged message is redelivered, not lost.

  3. Retry after a delay

    A failed message waits in a retry queue, then returns to the main queue.

  4. Dead-letter it

    The third failure lands in a dead-letter queue with the reason and timestamp.

  5. Log the run

    Release and email batches record each run and send finance a summary, and logging never fails the job.

Bulk work runs in chunks of 10, and each invoice succeeds or fails on its own, so one bad record can’t sink the batch or swamp the database. The same thinking keeps long AI batch jobs from restarting at zero.

An ERP export finance can check first

The export page builds a header sheet and a line sheet per legal entity from submitted invoices. Each contractor gets one document per period, and each invoice line becomes a row with its GL account, cost-center dimension and VAT group.

Finance reviews and edits the sheets in the portal, then downloads them for import. Tables for export batches exist, but saving each export as an auditable batch is the next step.

What we’d harden next, plus a checklist for your team

Contractors now confirm figures instead of typing them, and finance reviews only rows that disagree. Here is what we’d still change.

  • One transaction plus an outbox. Marking an invoice paid, writing its history and queuing the email are separate steps, so a crash mid-way could skip the email. An outbox (pending emails saved in the same transaction, sent afterward) closes that gap.
  • One wait queue per delay. The code asks for a 5-second wait, then 15, but RabbitMQ uses the lower of the queue’s and the message’s time-to-live, and the queue’s is 5 seconds. So both retries wait about 5 seconds.
  • Make the mark-paid job report. It doesn’t write a run record yet, and a skipped payment day should be as visible as a failure.
  • Show VAT gaps on screen. A missing rule only reaches the server log today, the same gap we closed for release.
  • Approve before saving. Bank changes are saved at once and reviewed after. Holding them until finance approves is safer.
Contractor invoice automation checklist
  • Name one source of truth for each figure and pre-fill invoices from it.
  • Recalculate amounts in code and flag differences before release.
  • Store finance’s “which source wins” choice as an override.
  • Return every skipped row with a reason.
  • Let the database block duplicate live invoices.
  • Match VAT rules exactly, surface invoices with no match, and snapshot the result.
  • Validate IBANs in one shared module, encrypt bank fields, and hold changes until finance approves.
  • Let cron publish and workers execute, with retries, a dead-letter queue and skip alerts.
Download this checklist (PDF)

If your month-end still runs on a spreadsheet and a shared inbox, book a free 30-minute discovery call. Bring last month’s HR export (headers only, or with names removed), and we’ll map where each number comes from and which checks would pay off first.

Questions we hear

What is contractor invoice automation?

It means generating contractor invoices from data you already hold, such as HR or timesheet records, instead of waiting for each contractor to type one. Contractors review and confirm, finance checks only the lines that disagree, and approved invoices move on to payment and ERP import.

How do you reconcile contractor invoices with HR or timesheet data?

Compare component by component, not total against total. Check working days, the service amount and each extra, such as commission or expenses, against the HR record within a small tolerance. Label each line a match, a mismatch, or an addition the contractor left off.

Can a company create invoices on behalf of contractors?

Yes, but that is usually self-billing, and it has rules. In the UK, HMRC’s VAT Notice 700/62 requires a written agreement with VAT-registered suppliers before self-billing starts. In our build, contractors review and submit each pre-filled invoice, but whether that counts as self-billing where you operate is for your tax adviser.

How do you prevent vendor bank account change fraud?

Treat every bank-detail change as a request, not a direct edit. Hold it until finance approves, and confirm it through a contact you already trust, not the email that asked for it. A valid IBAN checksum doesn’t prove the account belongs to your contractor.

Should we build a contractor invoicing portal or buy one?

Buy if your rules fit a contractor payment platform or AP suite out of the box. Build when they don’t: several legal entities, VAT that depends on entity and region, mixed fee and expense invoices, or an exact ERP import format.

Sources

  1. Accounts Payable Automation Trends 2025IFOL (Institute of Financial Operations and Leadership)
  2. UK CFOs still rely on spreadsheets for financial closeIT Brief UK (Sixthfin research conducted by Odoxa)
  3. Survey: 79% of Organizations Were Victims of Attempted or Actual Payments Fraud Activity in 2024Association for Financial Professionals (AFP)
  4. Time-To-Live and ExpirationRabbitMQ
  5. Self-billing (VAT Notice 700/62)HM Revenue & Customs (GOV.UK)
Written by the SeriusTech engineering team

We build custom software, business systems, applied AI and localization technology for growing businesses. Every technical claim in this note was checked against the code it describes. Products and clients stay unnamed.

ERP & business systems servicesFollow for new field notes
Free 30-minute discovery call

Want this solved in your business?

  1. Send a short request. We reply within 1 business day with times that suit your time zone.
  2. Talk it through for 30 minutes, free and with no obligation.
  3. Leave with a suggested first step, such as a fixed-price discovery sprint.
Free, 30 minutes, no obligation

Request your discovery call

Tell us a little about your project. We reply within 1 business day with times that suit your time zone.

Open email draft

This opens your email app with a draft to contact@seriustech.com. Nothing is sent until you send it.