Jak skutečně funguje Peppol SMP a SML discovery
Než lze doručit Peppol fakturu, musí odesílatelův systém najít přístupový bod příjemce. Neexistuje žádný centrální registr, na který by se dal přímo dotazovat. Místo toho Peppol používá dvouúrovňový řetězec discovery, který funguje jako DNS.
Pochopení tohoto řetězce je nezbytné, pokud budujete přímou integraci Peppol, spíše než delegujete směrování na poskytovatele přístupového bodu. I pokud poskytovatele používáte, znalost mechanismu discovery pomáhá ladit selhání doručení.
Dvě komponenty
SML (Service Metadata Locator) je kořenem řetězce. Jde o DNS-based službu provozovanou OpenPEPPOL. Jejím úkolem je říct vám, kde najít SMP účastníka.
SMP (Service Metadata Publisher) je služba na úrovni účastníka. Každý přístupový bod Peppol provozuje SMP pro své registrované účastníky. SMP publikuje, jaké typy dokumentů může účastník přijímat a URL endpoint, kam by tyto dokumenty měly být doručeny.
Kompletní flow discovery:
- Máte identifikátor účastníka (například belgické číslo podniku)
- Zahašujte a zakódujte ho do DNS hostname
- Dotáhněte se na zónu SML DNS pro zjištění hostname SMP účastníka
- Dotáhněte se na SMP pro získání metadat služby pro cílový typ dokumentu
- Extrahujte URL endpoint a certifikát příjemce
- Doručte podepsanou AS4 zprávu na tento endpoint
Krok 1: sestavení DNS dotazu
Identifikátor účastníka Peppol má dvě části: kód schématu a hodnotu. Pro belgickou společnost identifikovanou číslem podniku:
Scheme: 0208
Value: 0468863455
Full: iso6523-actorid-upis::0208:0468863455
Pro převod na DNS hostname:
- Převeďte celý identifikátor účastníka na malá písmena
- Vypočítejte MD5 haš
- Zakódujte haš v Base32 (bez odsazení, malá písmena)
- Přidejte předponu
b-(prefix Peppol SML) - Připojte doménu SML:
edelivery.tech.ec.europa.eu
V 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";
}
Kódování Base32 je podle RFC 4648. Standardní knihovna .NET Base32 neobsahuje; použijte malý nástroj nebo NuGet balíček SimpleBase.
Krok 2: DNS dotaz na SML
Dotáhněte se na hostname jako CNAME. Odpověď vám poskytne hostname SMP.
static async Task<string> LookupSmpHostname(string smlHostname)
{
var result = await Dns.GetHostEntryAsync(smlHostname);
// The CNAME target is the SMP hostname
return result.HostName;
}
Pokud DNS dotaz selže (NXDOMAIN), účastník není registrován v síti Peppol. Jde o definitivní odpověď „žádný takový účastník neexistuje”, nikoli o přechodnou chybu. Zaprotokolujte to a informujte uživatele, místo opakování.
Krok 3: dotaz na SMP
URL endpoint SMP se sestavuje z hostname SMP, schématu účastníka a hodnoty účastníka. Specifikace Peppol SMP (verze 2.0) definuje strukturu URL:
https://{smp-hostname}/{scheme}%3A%3A{value}/services/{doctype}
Oddělovač :: mezi schématem a hodnotou je procentuálně zakódován. Identifikátor typu dokumentu je také procentuálně zakódován.
Pro fakturu 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
Příklad celého požadavku:
GET https://{smp-hostname}/iso6523-actorid-upis%3A%3A0208%3A0468863455/services/urn%3Aoasis%3Anames...
SMP vrátí podepsaný XML dokument (metadata služby). Zde je, jak odpověď vypadá, oříznutá na relevantní části:
<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>
Krok 4: ověření podpisu SMP
Odpověď SMP je podepsána certifikátem přístupového bodu. Tento podpis musíte ověřit před důvěrou URL endpointu.
Zde má většina implementací potíže. Odpovědi SMP používají XML digitální podpisy (XMLDSig). Mnohé SMP servery při doručení znovu serializují podepsaný dokument, čímž mění deklarace prefixů jmenných prostorů. To narušuje referenční digest v podpisu.
Problém a jeho řešení jsou podrobně popsány v chybách validace XML Signature v Peppol. Stručně: použijte XML parser s PreserveWhitespace = true a před ověřením dokument neserializujte znovu.
Po ověření extrahujte URL endpointu a certifikát:
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 ?? ""));
Krok 5: doručení
S URL endpointu a certifikátem v ruce je faktura zabalena do AS4 zprávy a doručena přes HTTPS. AS4 je transportní protokol Peppol. Vyžaduje:
- Podepsání AS4 zprávy certifikátem vašeho přístupového bodu
- Šifrování payloadu certifikátem příjemce (z odpovědi SMP)
- Odeslání na
EndpointURIze SMP
Implementace AS4 je mimo rozsah tohoto článku. V praxi je vlastní implementace AS4 vrstvy významné inženýrské úsilí. Většina organizací používá certifikovaného poskytovatele přístupového bodu, místo přímé implementace AS4.
Ukládání do mezipaměti
Dotazy SMP by měly být ukládány do mezipaměti. TTL DNS záznamu SML je typicky 3600 sekund. Metadata služby SMP se nemění příliš často. 24hodinová mezipaměť na odpovědi SMP je rozumná pro většinu produkčních systémů.
Negativní výsledky (NXDOMAIN) neukládejte do mezipaměti na dobu neurčitou. Účastník se může zaregistrovat po vašem prvním dotazu. Negativní výsledky ukládejte do mezipaměti na 15 až 30 minut, nikoli na dny.
Co může jít špatně
NXDOMAIN ze SML: účastník není registrován. Jde o trvalý stav, nikoli přechodný. Neopakujte bez šetření.
SMP vrátí 404: účastník je registrován v SML, ale nemá metadata služby pro požadovaný typ dokumentu. Přístupový bod příjemce možná nenastavil podporu pro Peppol BIS Billing 3.0.
Selhání validace certifikátu: podpis odpovědi SMP používá certifikát, který není v seznamu důvěryhodnosti Peppol PKI. To by mělo být považováno za bezpečnostní chybu, nikoli za chybu konektivity. Odpověď odmítněte.
Selhání podpisu kvůli jmenným prostorům: viz chyby validace XML Signature v Peppol.
Endpoint vrátí AS4 SOAP fault: faktura byla doručena, ale přístupový bod příjemce ji odmítl. Kód chyby udává, zda je odmítnutí způsobeno nesouladem certifikátu, nepodporovaným typem dokumentu nebo selháním validace payloadu.
SealDoc a SMP discovery
REST API SealDoc provádí kompletní řetězec SMP discovery interně. Při odeslání požadavku na generování faktury s ID účastníka Peppol API vyřeší endpoint, ověří řetězec a nasměruje dokument. Pokud discovery selže, API vrátí strukturovanou chybu udávající, který krok selhal. Není třeba implementovat vyhledávání SML nebo SMP sami.
Pro účastníky, kteří potřebují spouštět dotazy na síť Peppol za účelem testování nebo auditu, může veřejný validátor SealDoc ověřit, zda je Peppol faktura doručitelná konkrétnímu účastníkovi, než se zavazujete k doručení.