Skip to content

Integration Guide — e-invoicing SDK

Who is it for?

Software editors who need to connect their product to French e-invoicing:

  • Mandatory reception from 1/9/2026
  • Mandatory issuance from 1/9/2027

Quick start (open source library)

Fenêtre de terminal
npm install @facturation/core
import { generateXml, buildPdf, validate } from '@facturation/core';
const invoice = {
number: 'INV-2026-0001',
typeCode: '380',
issueDate: '2026-06-23',
currency: 'EUR',
seller: {
name: 'ACME SAS',
siret: '12345678900012',
vatNumber: 'FR12345678901',
address: { line1: '1 rue de la Paix', city: 'Paris', postalCode: '75001', countryCode: 'FR' },
},
buyer: {
name: 'CLIENT SAS',
siret: '98765432100018',
address: { line1: '5 avenue Victor Hugo', city: 'Lyon', postalCode: '69001', countryCode: 'FR' },
},
lines: [
{
id: '1',
description: 'Consulting services',
quantity: 10,
unitCode: 'HUR',
netPrice: 100,
lineNetAmount: 1000,
vatCategoryCode: 'S',
vatRate: 20,
},
],
};
// EN 16931 validation
const { valid, errors } = validate(invoice);
if (!valid) throw new Error(errors.map(e => e.message).join(', '));
// Generation
const xml = generateXml(invoice);
const pdfBuffer = await buildPdf(invoice, xml);
// pdfBuffer: Buffer containing the complete Factur-X PDF/A-3

Full SDK (paid)

The full SDK adds:

  • State machine: complete lifecycle (DRAFT → SUBMITTED → RECEIVED → ACCEPTED → PAID)
  • Sandbox/prod PA client: Iopole deposit, status tracking
  • Signed webhooks: HMAC-SHA256 verification of PA notifications
  • Explicit sandbox/prod switch: log + contractual warning

30-day free sandbox access: create an account.

import { SandboxPaClient, transition, verifyWebhook } from '@facturation/sdk';
// Sandbox deposit
const pa = new SandboxPaClient();
const { depositId, status, paReference } = await pa.deposit(invoice, xml);
// status === 'SUBMITTED'
// Verify a state transition
const result = transition(invoiceId, 'SUBMITTED', 'RECEIVED');
if (result.success) {
// result.event: { from, to, at, source }
}
// Verify an incoming webhook from the PA
const { valid, payload } = verifyWebhook(rawBody, signature, process.env.WEBHOOK_SECRET!);
if (valid) {
// payload.event: 'INVOICE_STATUS_CHANGED'
}

Invoice state machine

DRAFT → SUBMITTED → RECEIVED → ACCEPTED → PAID
→ REJECTED → SUBMITTED (retry)
→ REFUSED (terminal)
→ CANCELLED (terminal)

All invalid transitions throw InvalidTransitionError.

Pricing

PlanVolumePrice
Starter≤ 1,000 invoices/month€290/month
Growth≤ 10,000/month€590/month
ScaleUnlimited + priority support€990/month
One-time integrationOne-shotOn quote