L'idempotency dans l'API PSB d'eConnect : comment éviter les envois en double avec le header X-EConnect-DocumentId.
Lors de l'envoi de factures et d'autres documents via une API, il existe toujours un risque d'envois en double. Un timeout réseau, un redémarrage de votre application ou une erreur inattendue peut faire que vous ne savez pas avec certitude si un document a été effectivement traité. Sans protection, vous pourriez envoyer le même document une seconde fois, avec des factures en double comme conséquence.
L'API PSB offre un mécanisme d'idempotency intégré qui résout ce problème. En envoyant un documentId unique à chaque upload, le PSB reconnaît les tentatives en double et empêche qu'un même document soit traité deux fois.
Le mécanisme d'idempotency repose sur le header HTTP X-EConnect-DocumentId. Lors de l'envoi d'un document, vous ajoutez ce header avec une valeur unique identifiant le document.
POST /api/v1/{partyId}/salesInvoice/send HTTP/1.1
Host: psb.econnect.eu
Authorization: Bearer {token}
Content-Type: application/xml
X-EConnect-DocumentId: 550e8400-e29b-41d4-a716-446655440000
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
...
</Invoice>
Le PSB traite le document et enregistre le documentId. Si vous envoyez la même requête à nouveau (par exemple lors d'un retry après un timeout), le PSB reconnaît que le documentId existe déjà et retourne une réponse 409 Conflict au lieu de traiter le document une seconde fois.
HTTP/1.1 409 Conflict
Ce 409 n'est pas un message d'erreur au sens traditionnel. C'est une confirmation que le document a déjà été traité avec succès précédemment. Votre application peut marquer la requête comme terminée en toute sécurité.
Le documentId envoyé dans le header X-EConnect-DocumentId doit respecter quelques conditions :
@ et _ ne sont pas autorisésImportant : n'utilisez jamais le numéro de facture comme documentId. Un numéro de facture peut être réutilisé pour une note de crédit ou une facture corrigée, ce qui entraîne des conflits. Utilisez plutôt un UUID/GUID que vous générez par tentative d'envoi.
Un UUID est le choix recommandé. Il est garanti unique et largement supporté dans tous les langages de programmation.
Bon : 550e8400-e29b-41d4-a716-446655440000 (UUID)
Bon : DOC2026030800142 (séquence propre, si unique)
Mauvais : INV-2026-001 (numéro de facture, ne pas utiliser)
Mauvais : ab@cd (caractères spéciaux)
Mauvais : abc (trop court)
L'idempotency prend toute sa valeur en combinaison avec une logique de retry. Si un appel API échoue à cause d'une erreur réseau ou d'une erreur serveur 5xx, vous souhaitez réessayer la requête sans risque de traitement en double.
L'approche recommandée fonctionne comme suit :
X-EConnect-DocumentId.200 OK : le document est traité, terminé.409 Conflict : le document était déjà traité lors d'une tentative précédente, terminé.5xx ou un timeout : attendez un instant et réessayez la requête avec le même documentId.4xx (sauf 409) : il y a un problème avec la requête elle-même. Réessayer n'a pas de sens, l'erreur doit être corrigée.Conseil : utilisez l'exponential backoff lors des retries. Commencez avec un court délai d'attente (par exemple 1 seconde) et doublez-le à chaque tentative suivante, jusqu'à un maximum de par exemple 60 secondes. Le PSB lui-même applique une politique de retry de maximum 8 tentatives sur environ 35 heures en cas d'erreurs 5xx.
Le header X-EConnect-DocumentId est supporté sur tous les endpoints permettant d'uploader des documents vers le PSB. Les principaux sont :
POST /api/v1/{partyId}/salesInvoice/sendPOST /api/v1/{partyId}/generic/sendPOST /api/v1/{partyId}/purchaseOrder/sendPour les endpoints de réception (téléchargement de documents), l'idempotency n'est pas applicable : la récupération d'un document est par nature idempotente car elle ne modifie aucune donnée.
L'idempotency est un petit mécanisme avec un grand impact. En envoyant systématiquement un X-EConnect-DocumentId à chaque upload de document, vous vous protégez contre les envois en double. En combinaison avec une logique de retry et l'exponential backoff, vous construisez une intégration robuste résistante aux problèmes de réseau et aux erreurs serveur temporaires.
En résumé
Envoyez à chaque upload de document le header X-EConnect-DocumentId avec un UUID unique. Lors d'un retry, le PSB retourne 409 Conflict si le document a déjà été traité. N'utilisez jamais le numéro de facture comme documentId.
Consulter la documentation API complète