API XML SEPA : générer vos fichiers pain.001 et pain.008 depuis l'ERP
2026-11-06
Mardi, 9 h. Chez Atelier Morel, une PME nantaise de menuiserie, la comptable exporte de Sage la liste des factures fournisseurs à régler, la retouche dans Excel, la charge dans l’outil de la banque, puis recommence pour la remise de prélèvements des contrats d’entretien. Le développeur de l’équipe pose la question qui fâche : « Pourquoi le logiciel ne produit-il pas le fichier lui-même ? »
C’est exactement le rôle d’une API XML SEPA : votre ERP, votre logiciel comptable ou votre back-office envoie les paiements en JSON, et l’API renvoie un fichier XML ISO 20022 prêt à déposer, un pain.001 pour les virements ou un pain.008 pour les prélèvements. L’API ne remplace pas la banque : le fichier part ensuite par EBICS, par la banque en ligne ou par votre plateforme de trésorerie.
Ce guide s’adresse aux équipes techniques et financières qui veulent brancher cette génération sur Sage, Cegid, EBP, Pennylane ou un développement maison. Il montre les vrais champs à envoyer, ce qu’il faut contrôler avant l’appel et comment organiser la remise à la banque.
Ce que fait une API XML SEPA, et ce qu’elle ne fait pas
Une API XML SEPA est un traducteur. Elle reçoit des données métier (qui paie, qui reçoit, combien, quand, avec quelle référence) et les transforme en message XML conforme à la norme ISO 20022 et aux règles de l’European Payments Council. Elle contrôle au passage ce qui peut l’être sans la banque : format des IBAN, champs obligatoires, cohérence des montants et des totaux.
Elle ne fait pas trois choses, et c’est important pour cadrer le projet :
- Elle ne transmet pas le fichier à la banque. Le dépôt passe par votre canal bancaire habituel. C’est une étape distincte, avec ses propres habilitations et signatures.
- Elle ne vérifie pas le titulaire du compte. Un IBAN au bon format peut appartenir à quelqu’un d’autre ; la vérification du bénéficiaire relève de la banque.
- Elle ne décide pas à votre place. Le choix des factures à payer, la validation par le DAF et la séparation des rôles restent dans vos outils.
Ce découpage a un avantage : le XML devient un produit de votre système, reproductible et journalisé, au lieu d’un fichier bricolé à la main chaque fin de mois. Pour une vue d’ensemble des familles de messages (pain, pacs, camt), lisez notre article sur la norme ISO 20022.
Idée clé : l’API produit le fichier, la banque exécute l’ordre. Gardez ces deux étapes séparées dans votre architecture comme dans vos contrôles internes.
pain.001 ou pain.008 : quels champs l’API XML SEPA attend
La première décision est fonctionnelle. Les virements SEPA (fournisseurs, salaires, remboursements) donnent un fichier pain.001 ; les prélèvements SEPA (abonnements, loyers, cotisations, contrats d’entretien) donnent un pain.008. Les deux flux n’ont ni les mêmes données ni les mêmes contrôles : un prélèvement exige un mandat signé et un identifiant créancier SEPA (ICS), un virement non. Ne les mélangez jamais dans un même appel.
Côté versions, la plupart des banques françaises acceptent toujours pain.001.001.03 et pain.008.001.02, tandis que les guides de l’EPC s’appuient désormais sur les versions 2019 (pain.001.001.09 et pain.008.001.08). Demandez à votre banque quelle version elle attend avant de coder quoi que ce soit.
Le tableau ci-dessous reprend les champs de l’API REST de GenerateSEPA (version 2) et la balise XML qu’ils alimentent. C’est la base de votre correspondance avec les données de l’ERP.
| Donnée métier | Champ JSON | Balise XML générée | Remarques |
|---|---|---|---|
| Raison sociale de l’émetteur | name |
<Dbtr><Nm> (virement) / <Cdtr><Nm> (prélèvement) |
Les guides EPC limitent le nom à 70 caractères |
| Compte de l’émetteur | iban |
<DbtrAcct> / <CdtrAcct>
|
Le BIC est déduit de l’IBAN, vous n’avez pas à l’envoyer |
| Identifiant de l’émetteur | sepa_identifier |
<Id> de l’émetteur |
Obligatoire ; pour un prélèvement, c’est votre ICS |
| Bénéficiaire ou débiteur |
payments[].name / debits[].name
|
<Cdtr><Nm> / <Dbtr><Nm>
|
70 caractères maximum |
| IBAN de la contrepartie |
payments[].iban / debits[].iban
|
<CdtrAcct> / <DbtrAcct>
|
Contrôlé avant génération |
| Montant | amount |
<InstdAmt Ccy="EUR"> |
En centimes, entier : 125050 = 1 250,50 € |
| Date d’exécution ou d’échéance | date |
<ReqdExctnDt> / <ReqdColltnDt>
|
Format AAAA-MM-JJ |
| Libellé sur le relevé | description |
<RmtInf><Ustrd> |
Obligatoire, 140 caractères maximum |
| Référence interne | reference |
<EndToEndId> |
35 caractères maximum, unique par opération |
| Type de virement | payments[].reason |
<CtgyPurp> |
salary pour les salaires, other par défaut |
| Référence du mandat (RUM) | debits[].mandate_reference |
<MndtId> |
Prélèvement uniquement |
| Date de signature du mandat | debits[].mandate_signature |
<DtOfSgntr> |
Aujourd’hui ou avant, jamais dans le futur |
| Schéma de prélèvement | scheme |
<LclInstrm> |
CORE par défaut, ou B2B
|
Deux détails évitent beaucoup de tickets. D’abord, les montants voyagent en centimes : un ERP qui exporte « 1250.50 » doit multiplier par 100 et arrondir avant l’appel. Ensuite, l’API regroupe automatiquement les opérations par date : si votre liste contient des virements au 10 et au 25, le fichier contiendra deux blocs <PmtInf>, un par date d’exécution.
Premier appel : générer un fichier de virements depuis votre ERP
Le premier appel doit rester minimal : un émetteur, deux fournisseurs, une date. L’objectif est de vérifier la chaîne complète (authentification, correspondance des champs, décodage du fichier) avant d’y brancher les vraies données.
Authentification
L’API utilise l’authentification HTTP Basic : votre clé d’API sert d’identifiant et le mot de passe reste vide. La clé se récupère dans l’espace développeur de votre compte, une fois l’option API activée. Stockez-la dans un coffre de secrets ou une variable d’environnement, jamais dans le code ni dans un fichier Excel partagé.
Requête
Voici l’appel que pourrait émettre le back-office d’Atelier Morel pour régler deux fournisseurs le 13 novembre. Les IBAN et l’identifiant sont des exemples ; l’URL de base de l’API figure dans la documentation de votre compte.
curl -X POST "$API_BASE_URL/api/v2/sct" \
-u "$SEPA_API_KEY:" \
-H "Content-Type: application/json" \
-d '{
"name": "Atelier Morel SAS",
"iban": "FR7630006000011234567890189",
"sepa_identifier": "FR19ZZZ654321",
"payments": [
{
"name": "Scierie du Bocage",
"iban": "FR1420041010050500013M02606",
"amount": 125050,
"date": "2026-11-13",
"description": "Facture F2026-0412 bois massif",
"reference": "FOUR-2026-0412"
},
{
"name": "Quincaillerie Lebrun",
"iban": "FR7630001007941234567890185",
"amount": 38990,
"date": "2026-11-13",
"description": "Facture QL-7781 visserie",
"reference": "FOUR-2026-0413"
}
]
}'
Pour une remise de prélèvements, l’appel est le même sur /api/v2/sdd, avec une liste debits à la place de payments. Chaque ligne y ajoute mandate_reference (la RUM) et mandate_signature, et sepa_identifier doit contenir votre ICS.
Réponse
En cas de succès, l’API renvoie un JSON qui récapitule la remise et contient le fichier XML encodé en Base64 :
{
"id": 42,
"format": "SCT",
"file": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4K...",
"operations": 2,
"amount": 164040,
"name": "Atelier Morel SAS",
"sepa_identifier": "FR19ZZZ654321",
"created_at": 1794391200
}
Votre code décode file, enregistre le XML avec un nom horodaté et compare operations et amount à ce que l’ERP avait sélectionné. Si les totaux divergent, on s’arrête là. En cas d’erreur de données, la réponse contient une liste errors qui désigne l’opération fautive ; sans abonnement actif ou période d’essai, l’appel est refusé avec un statut 401.
Règle pratique : testez volontairement trois appels en échec dès le premier jour (IBAN faux, libellé vide, date de signature de mandat dans le futur). Vous saurez comment votre code affiche les erreurs avant que la comptabilité ne les rencontre.
De l’API à la banque : EBICS, banque en ligne ou plateforme de trésorerie
Une fois le XML obtenu, il reste à le remettre à la banque. Le choix du canal dépend du volume, du nombre de banques et du niveau d’automatisation visé.
| Canal | Comment le fichier arrive à la banque | Signature de l’ordre | Pour qui |
|---|---|---|---|
| Banque en ligne professionnelle | Un utilisateur dépose le XML dans l’espace « remises » ou « fichiers » | Validation dans l’espace web, souvent avec authentification forte | PME avec une ou deux banques et quelques remises par mois |
| EBICS T | Votre logiciel transmet automatiquement le fichier | Confirmation séparée par un signataire habilité | Entreprises qui veulent automatiser l’envoi en gardant une validation humaine |
| EBICS TS | Votre logiciel transmet le fichier signé électroniquement | Signature par certificat, sans étape manuelle | ETI et groupes avec de gros volumes ou plusieurs banques |
| Plateforme de cash management | L’outil de trésorerie centralise les fichiers et les distribue aux banques via EBICS | Circuit de validation intégré à l’outil | Directions financières multi-banques |
Le protocole EBICS, maintenu en France par le CFONB, suppose un contrat avec chaque banque (BNP Paribas, Société Générale, Crédit Agricole, LCL, CIC, Banque Populaire, Caisse d’Épargne…). Nous détaillons les différences T et TS et la mise en place du contrat dans notre article sur EBICS. Si vous restez sur la banque en ligne, notre guide pour déposer un XML SEPA à la banque sans erreur couvre les points de contrôle du dépôt.
Dans tous les cas, gardez le fichier généré tel quel : si vous le retouchez entre l’API et la banque, vous perdez la traçabilité qui justifiait le projet.
Les erreurs qui font rejeter un fichier généré par API
Un XML valide au regard du schéma peut quand même être refusé par la banque. Les causes sont presque toujours dans les données sources, pas dans la génération.
-
Montants en euros au lieu de centimes. Envoyer
1250.50au lieu de125050donne un montant cent fois trop faible, ou une erreur. Faites la conversion dans une seule fonction, testée, et comparez systématiquement le total renvoyé avec celui de l’ERP. -
Caractères hors du jeu SEPA. Le jeu de caractères garanti dans la zone SEPA se limite à l’alphabet latin sans accents, aux chiffres et à quelques signes (
/ - ? : ( ) . , ' +). Beaucoup de banques françaises tolèrent les accents, mais une esperluette, des guillemets typographiques ou un retour à la ligne copiés depuis l’ERP peuvent faire échouer la remise. Normalisez noms et libellés avant l’appel, en gardant la valeur d’origine dans votre base pour l’audit. - Champs trop longs. Nom limité à 70 caractères dans les guides EPC, libellé à 140, référence de bout en bout à 35. Un numéro de facture concaténé au nom du client dépasse vite ces limites : tronquez de façon déterministe, pas au hasard.
-
Références réutilisées. Une
referencedoit identifier une seule opération. Si un job relance un appel après un délai d’attente, il doit renvoyer la même référence et vérifier qu’aucun fichier n’a déjà été déposé pour ce lot, sinon vous risquez un double paiement. - Dates impossibles. Une date d’exécution déjà passée au moment du dépôt, un samedi, ou une échéance de prélèvement trop proche du délai de remise prévu dans votre convention bancaire. Calculez les dates côté ERP en tenant compte des jours de fermeture TARGET et de la marge exigée par votre banque.
- Données de mandat incohérentes. Pour un prélèvement, la paire RUM et date de signature doit rester identique pour toutes les échéances d’un même débiteur, et l’ICS doit être celui attribué à votre entreprise. Vérifiez sa structure avec notre outil gratuit de contrôle de l’identifiant créancier SEPA.
Avant d’automatiser le dépôt, faites relire quelques fichiers générés par votre banque ou passez-les dans le validateur XML de prélèvement SEPA : le premier rejet en production coûte toujours plus cher qu’un test.
Règle pratique : journalisez chaque appel avec la référence du lot, le hash du fichier, les totaux et l’utilisateur qui a déclenché l’envoi, mais masquez les IBAN complets dans les logs. Le RGPD s’applique aussi à vos traces techniques.
Intégrer une API XML SEPA dans votre SI avec GenerateSEPA
Développer soi-même la génération ISO 20022 a du sens si les paiements sont le cœur de votre produit et que vous avez une équipe qui suivra les évolutions des rulebooks. Dans les autres cas, c’est du code à maintenir pour un besoin standard.
L’API SEPA de GenerateSEPA couvre ce besoin standard : génération de fichiers pain.001 et pain.008 (CORE et B2B), validation d’IBAN avec BIC et nom de la banque, et création de mandats SEPA en PDF avec l’option mandats. L’accès API est une option à 10 € HT par mois en plus de l’abonnement de base à 20 € HT par mois, avec conversions illimitées. Rien n’est branché nativement sur un ERP précis : c’est votre script ou votre connecteur qui lit les données dans Sage, Cegid, EBP, Pennylane ou votre base, puis appelle l’API.
Une architecture simple fonctionne bien pour une PME :
- L’ERP prépare la sélection. Factures à payer validées, ou échéances de prélèvement du mois, avec un identifiant de lot.
-
Un job envoie le lot à l’API. Conversion des montants en centimes, normalisation des textes, appel à
/api/v2/sctou/api/v2/sdd. - Le fichier est contrôlé et archivé. Décodage, comparaison des totaux, stockage chiffré avec le numéro de lot.
- Le fichier part à la banque. Dépôt par un utilisateur habilité ou transmission EBICS, puis rapprochement avec le relevé.
Si votre projet porte surtout sur l’encaissement (cycle de facturation, mandats, retours et rejets), notre guide dédié à l’API de prélèvement SEPA va plus loin sur ces sujets. Pour des virements fournisseurs groupés, voyez aussi comment structurer un virement multiple.
Plan d’action pour passer en production
| Étape | Ce qu’on fait | Quand |
|---|---|---|
| 1. Interroger la banque | Version de pain.001 et pain.008 acceptée, canal de dépôt, délais de remise, règles sur les caractères | Avant tout développement |
| 2. Cartographier les données | Correspondance champs ERP → champs JSON, conversion en centimes, règles de troncature | Semaine 1 |
| 3. Premier appel en essai | Un lot de deux opérations, puis trois cas d’erreur volontaires | Semaine 1 |
| 4. Contrôles automatiques | Comparaison des totaux, unicité des références, dates ouvrées, masquage des IBAN dans les logs | Semaine 2 |
| 5. Pilote | Un lot réel à faible enjeu, déposé manuellement et vérifié ligne à ligne sur le relevé | Premier cycle de paiement |
| 6. Industrialisation | Planification du job, envoi EBICS si contrat, procédure de secours manuelle documentée | Après deux cycles sans anomalie |
| 7. Suivi | Revue des rejets et retours, mise à jour des règles de normalisation | Chaque mois |
Commencez petit : un flux, une banque, un lot réel, puis élargissez. Pour tester la génération sur vos propres données, activez l’essai gratuit de 7 jours et appelez l’API SEPA depuis votre environnement de recette.
Questions fréquentes
- Une API XML SEPA envoie-t-elle le fichier directement à la banque ?
- Non. L'API génère le fichier pain.001 ou pain.008 et vous le renvoie ; le dépôt se fait ensuite par la banque en ligne, par EBICS ou par votre plateforme de trésorerie. Cette séparation permet de garder la validation et la signature de l'ordre chez les personnes habilitées.
- Faut-il un identifiant créancier SEPA pour utiliser une API XML SEPA ?
- Oui pour les prélèvements : chaque remise pain.008 doit porter l'ICS de votre entreprise, attribué en France par la Banque de France via votre banque. Pour les virements, l'ICS n'est pas exigé par le schéma, mais l'API demande tout de même un identifiant de l'émetteur.
- Peut-on connecter Sage, Cegid ou Pennylane à une API SEPA ?
- Oui, à condition d'écrire un connecteur ou un script qui lit les paiements dans le logiciel et appelle l'API. La plupart de ces outils exportent les factures ou les échéances en CSV ou via leur propre API ; c'est cette extraction qui alimente l'appel de génération du fichier SEPA.
- Quelle version de pain.001 utiliser en France ?
- La plupart des banques françaises acceptent toujours pain.001.001.03, et certaines proposent déjà pain.001.001.09, la version 2019 sur laquelle s'appuient les guides de l'EPC. La bonne réponse est celle de votre banque : demandez-lui la version attendue avant de développer l'intégration.