惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
MyScale Blog
MyScale Blog
雷峰网
雷峰网
量子位
小众软件
小众软件
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
T
Tailwind CSS Blog
月光博客
月光博客
博客园 - 【当耐特】
博客园_首页
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
IT之家
IT之家
爱范儿
爱范儿
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
WordPress大学
WordPress大学
The Cloudflare Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How to validate Peppol BIS 3 invoices in 5 lines of Pytho...
eleata team · 2026-05-05 · via DEV Community

eleata team

Starting September 2026 every B2B invoice in France must be e-invoiced (Peppol/Factur-X). Germany has mandated XRechnung for B2G since 2020. Italy has been on FatturaPA since 2019. Spain's Verifactu rolls out 2025-2026.

If you build accounting software, an ERP, or any e-commerce flow that touches EU customers, you'll likely need to validate these invoice formats at some point. The two main open-source Schematron engines are phive (by Philip Helger of the EN16931 working group) and Mustang (by Jochen Stärk and the FNFE-MPE working group). Both are great. Both ship as Java JARs or web forms — no API, no SDKs.

I built a thin REST API on top of Mustang 2.23.0 that gives you what's missing: SDKs, GitHub Action, and async batch.

The 5-line version

# pip install eleata-peppol
from eleata_peppol import Client

client = Client(api_key=os.environ["ELEATA_KEY"])
result = client.validate(format="peppol-bis-3", xml=open("invoice.xml", "rb").read())
print(result.valid, result.errors)

Enter fullscreen mode Exit fullscreen mode

That's it. Same Schematron rules CEN/OpenPeppol publish — equivalent accuracy to the phive reference web form.

Node version

import { Eleata } from "@eleata/peppol";
import fs from "node:fs";

const client = new Eleata({ apiKey: process.env.ELEATA_KEY! });
const result = await client.validate({
  format: "xrechnung-2.x",
  xml: fs.readFileSync("./invoice.xml"),
});

if (!result.valid) console.error(result.errors);

Enter fullscreen mode Exit fullscreen mode

In CI (GitHub Action)

- uses: eleata/validate-xrechnung-action@v1
  with:
    files: ./invoices/**/*.xml
    api-key: ${{ secrets.ELEATA_KEY }}

Enter fullscreen mode Exit fullscreen mode

Add a validates-in-CI badge to your README. Break the build before you ship a broken invoice.

What's in the box

  • POST /v1/validate (sync) and /v1/validate/batch (async + webhook callback)
  • 4 formats: Peppol BIS 3, XRechnung 2.x, Factur-X 1.07.2 (PDF/A-3 hybrid extracted natively), UBL 2.1
  • Public shareable validation reports at /r/{id}
  • 50 anonymized real EU invoice fixtures (CC0)
  • Free 200 validations/month, no credit card

Honest about scope

This is not a full Peppol Access Point — Ecosio, B2BRouter, Pagero do that. We are only the validator-as-an-API layer. If you need to send invoices through the Peppol network, you still need an Access Point.

Repos public on github.com/eleata. Live demo at peppol.eleata.io.

Curious to hear from anyone using a different validator (xrechnung-tooling, validator-fhir, InvoiceNavigator). What pain points hit you first when integrating?