Metadata-Version: 2.4
Name: confactura
Version: 0.1.0
Summary: Client Python officiel de l'API Confactura — génération & validation de factures Factur-X (EN 16931).
Project-URL: Homepage, https://confactura.fr
Project-URL: Documentation, https://confactura.fr/docs
Author: Confactura
License-Expression: MIT
License-File: LICENSE
Keywords: e-invoicing,en16931,factur-x,facture,invoice,pdf-a3,zugferd
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: French
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Accounting
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24
Description-Content-Type: text/markdown

# confactura — client Python

Client officiel de l'API **[Confactura](https://confactura.fr)** : générer et
valider des factures **Factur-X** (PDF/A-3 + XML CII, profil **EN 16931**) en un
appel HTTP, conformes à la réforme française de la facturation électronique
2026-2027.

Le service recalcule les totaux côté serveur et **refuse de livrer** une facture
qui ne passe pas la validation XSD **et** Schematron (règles CTC FR incluses) :
un 200 est une garantie de conformité, pas une supposition.

```bash
pip install confactura
```

Le client est volontairement mince : il mappe 1:1 les endpoints publics, n'ajoute
qu'`httpx` comme dépendance, et laisse le typage de la facture à l'appelant.

## Clé API

```bash
curl -X POST https://confactura.fr/v1/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "vous@exemple.fr"}'
```

La clé n'est renvoyée qu'**une seule fois** (dans la réponse et par email). Le
plan gratuit couvre 20 factures/mois ; la **validation est illimitée et sans
clé**.

## Usage

```python
from confactura import ConfacturaClient, ConfacturaValidationError

df = ConfacturaClient(api_key="df_live_…")           # clé sur confactura.fr/#account

# Générer un Factur-X (PDF/A-3 + XML CII embarqué, validé XSD + Schematron)
invoice = {
    "number": "2026-0042",
    "issue_date": "2026-09-01",
    "due_date": "2026-09-30",
    "seller": {"name": "Ma Société", "address_line": "1 rue X", "postcode": "75001",
               "city": "Paris", "siren": "123456789", "vat_id": "FR32123456789",
               "electronic_address": "facturation@masociete.fr"},
    "buyer":  {"name": "Client SARL", "address_line": "2 av. Y", "postcode": "69001",
               "city": "Lyon", "electronic_address": "compta@client.fr"},
    "lines":  [{"description": "Presta dev", "quantity": 5, "unit_price": "450.00"}],
}
try:
    pdf = df.generate_facturx(invoice)
    open("facture-2026-0042.pdf", "wb").write(pdf)
except ConfacturaValidationError as e:
    print("Non conforme :", e.errors)

# Valider un Factur-X existant — anonyme, aucune clé requise, aucun quota consommé
report = df.validate(open("facture.pdf", "rb").read())
print(report["valid"], report["errors"])

# Consommation du mois
print(df.usage())   # {"plan": "free", "used": 3, "quota": 20}
```

`validate()` fonctionne sans clé API :

```python
ConfacturaClient().validate(pdf_bytes)
```

Pointer un autre environnement : `ConfacturaClient(base_url="http://localhost:8000")`.

## Champs requis côté CTC FR

Sans eux la facture part en **422** avec le rapport détaillé — jamais en 500 :

- `electronic_address` sur le vendeur **et** l'acheteur (`BR-FR-12` / `BR-FR-13`) ;
- `vat_id` côté vendeur dès qu'une ligne est en TVA standard (`BR-S-02`) ;
- un `siren` vendeur valide.

Les autres mentions de la réforme 2026 (frais de recouvrement, pénalités de
retard, escompte, catégorie d'opération) sont ajoutées **automatiquement** côté
serveur.

## API

| Méthode | Endpoint | Retour |
|---|---|---|
| `generate_facturx(invoice)` | `POST /v1/invoices/facturx` | `bytes` — PDF/A-3 |
| `generate_xml(invoice)` | `POST /v1/invoices/xml` | `bytes` — XML CII EN 16931 |
| `validate(pdf)` | `POST /v1/validate` | `dict` — `{valid, profile, flavor, errors}` |
| `usage()` | `GET /v1/usage` | `dict` — `{plan, used, quota}` |

Un 422 en génération lève `ConfacturaValidationError` (`.errors`, `.report`) ;
tout autre statut ≥ 400 lève `ConfacturaError` (`.status_code`, `.detail`).

## Liens

- Guide pas à pas : <https://confactura.fr/factur-x-python>
- Validateur Factur-X en ligne, gratuit : <https://confactura.fr/validateur>
- Erreurs Schematron expliquées : <https://confactura.fr/erreurs-schematron>
- Référence OpenAPI : <https://confactura.fr/docs>

## Tests

```bash
pip install -e . pytest
pytest        # zéro réseau (httpx.MockTransport)
```

MIT.
