← Back to all articles

Comment fonctionne réellement la découverte SMP et SML de Peppol

SealDoc Team · · 6 min read

Avant qu’une facture Peppol puisse être livrée, le système de l’expéditeur doit trouver le Point d’Accès du destinataire. Il n’existe pas de registre central que vous pouvez interroger directement. Peppol utilise plutôt une chaîne de découverte à deux niveaux qui fonctionne comme DNS.

Comprendre cette chaîne est essentiel si vous construisez une intégration Peppol directe plutôt que de déléguer le routage à un fournisseur de Point d’Accès. Même si vous utilisez un fournisseur, connaître le mécanisme de découverte aide à déboguer les échecs de livraison.

Les deux composants

SML (Service Metadata Locator) est la racine de la chaîne. Il s’agit d’un service basé sur DNS exploité par OpenPEPPOL. Son rôle est de vous indiquer où trouver le SMP d’un participant.

SMP (Service Metadata Publisher) est un service au niveau du participant. Chaque Point d’Accès Peppol gère un SMP pour ses participants enregistrés. Le SMP publie les types de documents qu’un participant peut recevoir et l’URL de point de terminaison où ces documents doivent être livrés.

Le flux de découverte complet :

  1. Vous disposez d’un identifiant de participant (par exemple, un numéro d’entreprise belge)
  2. Hachez-le et encodez-le dans un nom d’hôte DNS
  3. Interrogez la zone DNS SML pour trouver le nom d’hôte SMP du participant
  4. Interrogez le SMP pour obtenir les métadonnées de service pour le type de document cible
  5. Extrayez l’URL du point de terminaison et le certificat du destinataire
  6. Livrez le message AS4 signé à ce point de terminaison

Étape 1 : construction de la requête DNS

L’identifiant du participant Peppol comporte deux parties : un code de schéma et une valeur. Pour une entreprise belge identifiée par son numéro d’entreprise :

Scheme: 0208
Value:  0468863455
Full:   iso6523-actorid-upis::0208:0468863455

Pour transformer cela en nom d’hôte DNS :

  1. Mettez l’identifiant complet du participant en minuscules
  2. Calculez le hachage MD5
  3. Encodez le hachage en Base32 (sans rembourrage, en minuscules)
  4. Ajoutez le préfixe b- (le préfixe SML Peppol)
  5. Ajoutez le domaine SML : edelivery.tech.ec.europa.eu

En C# :

static string BuildSmlHostname(string participantId)
{
    var lower = participantId.ToLowerInvariant();
    var hash  = MD5.HashData(Encoding.UTF8.GetBytes(lower));
    var b32   = Base32.ToBase32String(hash).ToLowerInvariant().TrimEnd('=');
    return $"b-{b32}.iso6523-actorid-upis.edelivery.tech.ec.europa.eu";
}

L’encodage Base32 est RFC 4648. La bibliothèque standard .NET n’inclut pas Base32 ; utilisez un petit utilitaire ou le package NuGet SimpleBase.

Étape 2 : la requête DNS SML

Interrogez le nom d’hôte comme un CNAME. La réponse vous donne le nom d’hôte SMP.

static async Task<string> LookupSmpHostname(string smlHostname)
{
    var result = await Dns.GetHostEntryAsync(smlHostname);
    // The CNAME target is the SMP hostname
    return result.HostName;
}

Si la requête DNS échoue (NXDOMAIN), le participant n’est pas enregistré dans le réseau Peppol. C’est une réponse définitive “pas de tel participant”, pas une erreur transitoire. Enregistrez-le et renvoyez-le à l’utilisateur plutôt que de réessayer.

Étape 3 : interrogation du SMP

L’URL du point de terminaison SMP est construite à partir du nom d’hôte SMP, du schéma du participant et de la valeur du participant. La spécification SMP Peppol (version 2.0) définit la structure d’URL :

https://{smp-hostname}/{scheme}%3A%3A{value}/services/{doctype}

Le séparateur :: entre le schéma et la valeur est encodé en pourcentage. L’identifiant de type de document est également encodé en pourcentage.

Pour une facture Peppol BIS Billing 3.0 :

doctype: urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1

Exemple de requête complète :

GET https://{smp-hostname}/iso6523-actorid-upis%3A%3A0208%3A0468863455/services/urn%3Aoasis%3Anames...

Le SMP renvoie un document XML signé (les métadonnées de service). Voici ce à quoi ressemble la réponse, réduite aux parties pertinentes :

<ServiceMetadata>
  <ServiceInformation>
    <ParticipantIdentifier scheme="iso6523-actorid-upis">0208:0468863455</ParticipantIdentifier>
    <DocumentIdentifier>urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::...</DocumentIdentifier>
    <ProcessList>
      <Process>
        <ProcessIdentifier scheme="cenbii-procid-ubl">urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ProcessIdentifier>
        <ServiceEndpointList>
          <Endpoint transportProfile="peppol-as4-2.0">
            <EndpointURI>https://ap.example.com/as4</EndpointURI>
            <Certificate>MIIBxTCCA...</Certificate>
          </Endpoint>
        </ServiceEndpointList>
      </Process>
    </ProcessList>
  </ServiceInformation>
  <Signature>...</Signature>
</ServiceMetadata>

Étape 4 : vérification de la signature SMP

La réponse SMP est signée avec le certificat du Point d’Accès. Vous devez vérifier cette signature avant de faire confiance à l’URL du point de terminaison.

C’est là que la plupart des implémentations rencontrent des problèmes. Les réponses SMP utilisent des Signatures Numériques XML (XMLDSig). De nombreux serveurs SMP re-sérialisent le document signé lors de sa diffusion, ce qui modifie les déclarations de préfixe d’espace de noms. Cela casse le résumé de référence dans la signature.

Le problème et sa correction sont détaillés dans les pièges de la validation des signatures XML dans Peppol. En résumé : utilisez un analyseur XML avec PreserveWhitespace = true et ne re-sérialisez pas le document avant la vérification.

Après vérification, extrayez l’URL du point de terminaison et le certificat :

var ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("wsa", "http://www.w3.org/2005/08/addressing");
ns.AddNamespace("bdxr", "http://docs.oasis-open.org/bdxr/ns/SMP/2016/05");

var endpointNode = doc.SelectSingleNode(
    "//bdxr:Endpoint[@transportProfile='peppol-as4-2.0']/bdxr:EndpointURI", ns);
var certNode = doc.SelectSingleNode(
    "//bdxr:Endpoint[@transportProfile='peppol-as4-2.0']/bdxr:Certificate", ns);

var endpointUrl = endpointNode?.InnerText;
var cert = new X509Certificate2(Convert.FromBase64String(certNode?.InnerText ?? ""));

Étape 5 : livraison

Avec l’URL du point de terminaison et le certificat en main, la facture est encapsulée dans un message AS4 et livrée via HTTPS. AS4 est le protocole de transport Peppol. Il requiert :

  • La signature du message AS4 avec le certificat de votre Point d’Accès
  • Le chiffrement de la charge utile avec le certificat du destinataire (provenant de la réponse SMP)
  • L’envoi vers l’EndpointURI du SMP

L’implémentation d’AS4 dépasse le cadre de cet article. En pratique, construire votre propre couche AS4 représente un effort d’ingénierie significatif. La plupart des organisations utilisent un fournisseur de Point d’Accès certifié plutôt que d’implémenter AS4 directement.

Mise en cache

Les recherches SMP doivent être mises en cache. Le TTL DNS sur l’entrée SML est généralement de 3600 secondes. Les métadonnées de service SMP ne changent pas fréquemment. Un cache de 24 heures sur les réponses SMP est raisonnable pour la plupart des systèmes en production.

Ne mettez pas en cache les résultats négatifs (NXDOMAIN) indéfiniment. Un participant peut s’enregistrer après votre première recherche. Mettez en cache les résultats négatifs pendant 15 à 30 minutes, pas des jours.

Ce qui peut se passer

NXDOMAIN du SML : le participant n’est pas enregistré. C’est permanent, pas transitoire. Ne réessayez pas sans investigation.

Le SMP renvoie 404 : le participant est enregistré dans le SML mais n’a pas de métadonnées de service pour le type de document demandé. Le Point d’Accès du destinataire peut ne pas avoir configuré la prise en charge de Peppol BIS Billing 3.0.

Échec de validation du certificat : la signature de la réponse SMP utilise un certificat qui n’est pas dans la liste de confiance PKI Peppol. Cela doit être traité comme une erreur de sécurité, pas une erreur de connectivité. Rejetez la réponse.

Échec de signature lié aux espaces de noms : voir les pièges de la validation des signatures XML dans Peppol.

Le point de terminaison renvoie un fault SOAP AS4 : la facture a été livrée mais rejetée par le Point d’Accès du destinataire. Le code de faute indique si le rejet est dû à une discordance de certificat, un type de document non pris en charge ou un échec de validation de la charge utile.

SealDoc et la découverte SMP

L’API REST de SealDoc effectue la chaîne complète de découverte SMP en interne. Lorsque vous soumettez une demande de génération de facture avec un identifiant de participant Peppol, l’API résout le point de terminaison, valide la chaîne et achemine le document. En cas d’échec de la découverte, l’API renvoie une erreur structurée indiquant quelle étape a échoué. Vous n’avez pas besoin d’implémenter vous-même la recherche SML ou SMP.

Pour les participants qui ont besoin d’effectuer des recherches sur le réseau Peppol à des fins de test ou d’audit, le validateur public SealDoc peut vérifier si une facture Peppol est routable vers un participant spécifique avant de vous engager dans la livraison.


← Back to all articles