01 What it does
PEPPOL Relay turns an ordinary invoice spreadsheet into network-ready e-invoices. You upload an Excel or CSV file — one file can hold many invoices, grouped by invoice number — map your columns to the PEPPOL fields, and the relay does the compliance work: validate the data, transform each invoice to UBL BIS 3.0, then either hand you the XML or deliver it to an Access Point.
- Excel / CSV intake — many invoices per file, grouped by invoice number; header data from a second sheet, a separate CSV, or a form.
- Column mapping & preview — remap your headers to PEPPOL fields and check the parsed data before anything runs.
- Validation — UK EN16931 + PIAT by default, with selectable country rulesets, before any transform.
- Transform — UBL BIS 3.0 invoices and credit notes, with PDFs embedded as Base64.
- Deliver or download — send to an Access Point (REST/SOAP), download the XML, or grab everything as a ZIP.
Privacy: files are processed in memory and never stored server-side, and Access Point credentials are used only for that single request. The tool keeps no invoice content.
02 How it works
The core is Python + FastAPI, running as a serverless function on the same Vercel deployment as this site. It's deliberately stateless — each request carries its own data, is processed in memory, and is discarded. The pipeline is staged so every step is observable:
- Upload & map — parse CSV/Excel (header row auto-detected), group rows into invoices, remap columns to PEPPOL fields.
- Validate — enforce EN16931 mandatory fields and PIAT tax alignment; surface errors clearly before anything is generated.
- Transform — emit one UBL BIS 3.0 document per invoice (invoice or credit note), with PDFs embedded as AdditionalDocumentReference.
- Deliver — POST the raw UBL to an Access Point over REST or SOAP, one call per invoice, and surface the request/response.
03 Design decisions
Map, don't dictate. Nobody should have to rename columns or reshape a workbook before uploading. You map your headers to the PEPPOL fields once and preview the parsed result, so the file stays yours and the mapping stays explicit.
Stateless by default. Invoice data is sensitive, so the tool stores nothing. Files are parsed in memory, the result is returned, and it's forgotten; Access Point credentials live only for the single call that uses them. That keeps the surface small and the function cheap to run.
Validate before you transform. Catching bad data early — before the PEPPOL mapping — keeps failures legible and avoids shipping malformed documents into the network.
04 Status & what's next
Done and live. The full pipeline ships today: upload Excel/CSV, map your columns, validate against EN16931, transform each invoice to UBL BIS 3.0 with embedded PDFs, then download the XML or deliver it to an Access Point (REST or SOAP). It runs on the same Vercel deployment as this site, served from its own subdomain.
A few things in the brief are not built yet — the audit log is in-session only today (nothing persisted), and there's no login, OCR, or email intake. Those land in V2, once Supabase is wired in for accounts and lock-down:
- Login & accounts (Supabase) — sign-in and lock-down, so each supplier sees only their own invoices.
- Persistent audit history — per-user invoice status and AP request/response logs stored in Supabase, not just in-session.
- Email intake — accept invoices straight from an inbox, not only as an upload.
- OCR & translation — read PDF invoices that arrive as scans or in another language.
- Saved column-mapping templates per supplier, plus wider country rulesets beyond the UK default.