# CLAUDE.md — Connecteur Stripe → Facturation électronique (Factur-X / SUPER PDP)

Contexte pour Claude Code. Réponds en **français**. Propriétaire : Anthony (Digicomcrea, agence web à Valserhône — SIREN à renseigner dans la config).

## Ce qu'est ce projet

Connecteur **PHP 8.1+ sans aucune dépendance** (pas de Composer) qui rend les factures Stripe (abonnements récurrents surtout) conformes à la réforme française de la facturation électronique, via la plateforme agréée **SUPER PDP** (api.superpdp.tech, API `/v1.beta`, OAuth2 client credentials).

Flux : webhook Stripe → file de travaux (SQLite) → mapping EN 16931 → XML CII + PDF/A-3 Factur-X → envoi SUPER PDP → suivi des statuts de cycle de vie (fr:2xx) + statut « Encaissée » (fr:212) au paiement → synchronisation des factures **reçues** (fournisseurs) par polling `starting_after_id`.

## Carte du code

```
public/stripe-webhook.php      Webhook Stripe (signature HMAC vérifiée, réponse immédiate, traitement inline si possible)
public/admin/index.php         Tableau de bord (HTTP Basic + CSRF) : émises / reçues / file / système
bin/cron.php                   À planifier toutes les 10 min : file d'émission + statuts + factures reçues
bin/check-setup.php            Diagnostic complet (--offline possible)
bin/send-invoice.php           Émission manuelle : in_xxx|cn_xxx [--dry-run|--force|--payment|--cancel]
bin/preview.php                Génère XML+PDF hors ligne (--demo ou un JSON de facture Stripe)
bin/validate-file.php          Validation : XSD locale + validateur officiel SUPER PDP (schematrons)
src/bootstrap.php              Autoload PSR-4 maison (EInvoice\ → src/), config, logs
src/Config.php, Db.php         Config par clés pointées ; SQLite WAL (storage/db/einvoice.sqlite) + migrations
src/Http.php                   cURL minimal ; encodage form Stripe
src/Stripe/                    StripeClient (REST épinglé 2025-02-24.acacia), WebhookSignature
src/Mapping/                   StripeInvoiceMapper (cœur : Stripe → InvoiceModel EN 16931), PartyResolver
                               (qualification B2B/B2C/B2BINT/REVIEW/SKIP), VatRules, Money (centimes entiers)
src/FacturX/                   CiiWriter (XML CII D16B profil EN 16931 + règles BR-FR), CiiValidator
                               (XSD + ~40 règles métier), InvoicePdfRenderer (mise en page), FacturXBuilder,
                               Pdf/MiniPdf (générateur PDF/A-3b maison : XMP, ICC, polices TTF, pièce jointe), Pdf/TtfFont
src/SuperPdp/                  SuperPdpClient (OAuth2, envoi, événements, annuaire, validation), StatusCodes
src/Services/                  OutboundService (orchestration), InboundService (réception+statuts),
                               JobQueue (retries exponentiels), Mailer (mail()/SMTP), FileStore (archives + verrous)
resources/xsd/                 XSD Factur-X 1.09 EN 16931 (NE PAS MODIFIER)
resources/fonts|icc/           Liberation Sans (OFL), sRGB.icc — embarqués dans les PDF
tests/run.php                  33 tests hors ligne (fixtures + doublures FakeStripe/FakeSuperPdp)
```

## Commandes

```bash
php tests/run.php                  # DOIT afficher « 33 réussi(s), 0 échec(s) » avant tout envoi/déploiement
php bin/preview.php --demo         # sanity check : génère un Factur-X d'exemple
php bin/check-setup.php            # une fois config/config.php rempli (--offline sans réseau)
php -l <fichier>                   # lint (aucun outil externe requis)
```

## Règles du projet

- **Zéro dépendance** : PHP standard uniquement (curl, dom, libxml, pdo_sqlite, mbstring, openssl, zlib). Ne pas introduire Composer sans demande explicite d'Anthony (hébergement mutualisé).
- `declare(strict_types=1)` partout ; montants en **centimes entiers** via `EInvoice\Util\Money` (jamais de flottants pour les totaux) ; chaînes décimales `"12.34"` dans le modèle.
- Interface et messages en **français** ; code/identifiants en anglais.
- Idempotence : événements Stripe dédupliqués par id ; travaux uniques par (type, ref) ; ré-émission bloquée si `superpdp_id` existe (sauf --force).
- Toute facture douteuse va en **review** (jamais d'envoi « au cas où ») : c'est un choix de conformité, à préserver.
- Après toute modification du mapping/writer : relancer `php tests/run.php` puis `php bin/validate-file.php` sur un PDF généré (validateur officiel) dès que les identifiants SUPER PDP sont configurés.
- Ne jamais committer/déployer `config/config.php` ni `storage/` (voir .gitignore).

## État : terminé et testé (hors ligne)

Émission B2B/B2C/B2BINT, remises, TVA multi-taux, factures « déjà payées », avoirs (381), avoir d'annulation post-transmission, encaissements fr:212, réception + statuts acheteur, tableau de bord, notifications e-mail, file avec retries. 33/33 tests. **Aucun appel réel** n'a encore été fait vers Stripe ni SUPER PDP (construit sur leur OpenAPI + doc officielle).

## Reste à faire (finalisation par Anthony, avec l'aide de Claude Code)

1. `cp config/config.example.php config/config.php` puis remplir : seller.* (SIREN réel, TVA, adresse, IBAN), stripe.secret_key (clé restreinte) + webhook_secret, superpdp.client_id/secret (bac à sable d'abord), mail.*, admin.password_hash.
2. `php bin/check-setup.php` → tout en [OK] (KYB SUPER PDP « verified »).
3. Test de bout en bout en **bac à sable** : facture test Stripe → tableau de bord → `bin/validate-file.php` sur le PDF → corriger si le validateur officiel remonte des règles (me donner le rapport).
4. Dépôt FTP (FileZilla) : tout le projet hors racine web si possible, sinon tel quel (les .htaccess protègent) ; adapter les `require .../bootstrap.php` si `public/` est déplacé ; webhook Stripe + cron ; droits en écriture sur `storage/`.
5. Bascule production (clés live + SUPER PDP production + ligne d'annuaire de réception).

Backlog d'améliorations possibles (non bloquant) : gestion OSS/TVA étrangère B2C UE, multi-taux par ligne, e-reporting des achats B2Bi, script de packaging FTP (`bin/package.php`), rotation des journaux, export comptable CSV.

## Pièges connus

- `bin/cron.php` : ne pas écrire `*/10` dans un docblock PHP (ferme le commentaire) — c'est déjà contourné.
- MiniPdf écrit du **WinAnsi** : caractères hors table remplacés par `?` (normalisation dans `MiniPdf::normalize`). Pour de nouveaux glyphes, enrichir la table, pas d'UTF-8 brut dans les flux texte.
- L'API Stripe est épinglée (`stripe.api_version`) : si montée de version, vérifier `lines.data[].tax_amounts/price` et les champs `amount_excluding_tax`.
- SUPER PDP : `POST /v1.beta/invoices` accepte le binaire brut (PDF Factur-X ou XML) ; statuts = liste d'événements, PAS une machine à états ; synchronisation par `starting_after_id` strictement croissant (voir doc « Synchronisation »).
- Le validateur local (CiiValidator) est un sous-ensemble : la référence est `POST /v1.beta/validation_reports`.

## Journal d'avancement (mis à jour par Claude Cowork — 20/08/2026)

- **Bac à sable SUPER PDP validé de bout en bout** : compte développeur, application « confidentielle » (Burger Queen, n° 000000002), identifiants dans `config/config.php`. Test réel réussi via `bin/test-sandbox.sh` : OAuth2 OK, facture de test déposée (id SUPER PDP **#974324**).
- **Entreprise de production créée** : GENNARO ANTHONY / nom commercial DIGICOMCREA, SIREN **515308625**, adresse officielle 215 CHE du Niezelet, 01410 Champfromier. Dossier KYB (accord formel + pièce d'identité) soumis le 20/08/2026. Lignes d'annuaire créées (France 515308625, Peppol 0225:515308625 et 0225:515308625_replyto), statut « En cours » jusqu'à validation du KYB.
- **Pour la phase bac à sable**, `seller.*` de config.php doit rester l'identité Burger Queen (name « Burger Queen », siren 000000002, adresse 809 avenue du Languedoc 12100 Millau).

### Prochaines étapes
1. Dépôt FTP du projet + webhook Stripe (mode test) + cron toutes les 10 min → vérifier via `admin/?tab=diag`.
2. Test complet : facture d'abonnement Stripe test → tableau de bord → statut chez SUPER PDP → `bin/validate-file.php` sur le PDF généré.
3. **À la validation du KYB** (e-mail de SUPER PDP attendu sous quelques jours) : créer l'application API de production (Applications → Nouvelle application → GENNARO ANTHONY), remplacer client_id/client_secret dans config.php, remettre `seller.*` réels (DIGICOMCREA, SIREN 515308625, adresse Champfromier, n° TVA), refaire un test, puis basculer la clé Stripe en mode live.
4. Échéance : réception obligatoire au **01/09/2026** — l'annuaire s'active dès la validation KYB.
