← Back to all articles

Jak naprawdę działa odkrywanie Peppol SMP i SML

SealDoc Team · · 5 min read

Zanim faktura Peppol może zostać dostarczona, system nadawcy musi znaleźć punkt dostępowy odbiorcy. Nie istnieje centralny rejestr, który można odpytać bezpośrednio. Zamiast tego Peppol używa dwupoziomowego łańcucha odkrywania działającego jak DNS.

Zrozumienie tego łańcucha jest niezbędne, jeśli budujesz bezpośrednią integrację Peppol zamiast delegować routing do dostawcy punktu dostępowego. Nawet jeśli korzystasz z dostawcy, znajomość mechanizmu odkrywania pomaga debugować awarie dostarczania.

Dwa komponenty

SML (Service Metadata Locator) jest korzeniem łańcucha. To usługa oparta na DNS, obsługiwana przez OpenPEPPOL. Jej zadaniem jest informowanie o tym, gdzie znaleźć SMP uczestnika.

SMP (Service Metadata Publisher) to usługa na poziomie uczestnika. Każdy punkt dostępowy Peppol prowadzi SMP dla swoich zarejestrowanych uczestników. SMP publikuje, jakie typy dokumentów uczestnik może odbierać i adres URL punktu końcowego, do którego te dokumenty powinny być dostarczane.

Pełny przepływ odkrywania:

  1. Masz identyfikator uczestnika (na przykład belgijski numer przedsiębiorstwa)
  2. Haszujesz go i kodujesz w nazwę hosta DNS
  3. Odpytujesz strefę DNS SML, by znaleźć nazwę hosta SMP uczestnika
  4. Odpytujesz SMP, by uzyskać metadane usługi dla docelowego typu dokumentu
  5. Wyodrębniasz adres URL punktu końcowego i certyfikat odbiorcy
  6. Dostarczasz podpisaną wiadomość AS4 do tego punktu końcowego

Krok 1: konstruowanie zapytania DNS

Identyfikator uczestnika Peppol składa się z dwóch części: kodu schematu i wartości. Dla belgijskiej firmy identyfikowanej przez jej numer przedsiębiorstwa:

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

Aby zamienić to na nazwę hosta DNS:

  1. Zamień pełny identyfikator uczestnika na małe litery
  2. Oblicz skrót MD5
  3. Zakoduj skrót w Base32 (bez wypełnienia, małe litery)
  4. Poprzedź prefiksem b- (prefix SML Peppol)
  5. Dołącz domenę SML: edelivery.tech.ec.europa.eu

W 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";
}

Kodowanie Base32 to RFC 4648. Standardowa biblioteka .NET nie zawiera Base32; użyj małego narzędzia lub pakietu NuGet SimpleBase.

Krok 2: zapytanie DNS SML

Odpytaj nazwę hosta jako CNAME. Odpowiedź podaje nazwę hosta SMP.

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

Jeśli zapytanie DNS zakończy się niepowodzeniem (NXDOMAIN), uczestnik nie jest zarejestrowany w sieci Peppol. Jest to definitywna odpowiedź „taki uczestnik nie istnieje”, a nie błąd przejściowy. Zaloguj to i przedstaw użytkownikowi zamiast ponownych prób.

Krok 3: odpytywanie SMP

Adres URL punktu końcowego SMP jest budowany z nazwy hosta SMP, schematu uczestnika i wartości uczestnika. Specyfikacja Peppol SMP (wersja 2.0) definiuje strukturę URL:

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

Separator :: między schematem a wartością jest zakodowany procentowo. Identyfikator typu dokumentu jest również zakodowany procentowo.

Dla faktury 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

Przykładowe pełne żądanie:

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

SMP zwraca podpisany dokument XML (metadane usługi). Oto jak wygląda odpowiedź, ograniczona do istotnych części:

<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: weryfikacja podpisu SMP

Odpowiedź SMP jest podpisana certyfikatem punktu dostępowego. Musisz zweryfikować ten podpis przed zaufaniem adresowi URL punktu końcowego.

Tutaj większość implementacji napotyka problemy. Odpowiedzi SMP używają XML Digital Signatures (XMLDSig). Wiele serwerów SMP deserializuje podpisany dokument przy dostarczaniu, co zmienia deklaracje prefiksów przestrzeni nazw. Psuje to odwołanie do skrótu w podpisie.

Problem i jego rozwiązanie zostały szczegółowo omówione w artykule Pułapki walidacji podpisów XML w Peppol. Krótko: użyj parsera XML z PreserveWhitespace = true i nie deserializuj dokumentu przed weryfikacją.

Po weryfikacji wyodrębnij adres URL punktu końcowego i certyfikat:

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: dostarczenie

Mając adres URL punktu końcowego i certyfikat, faktura jest opakowywana w wiadomość AS4 i dostarczana przez HTTPS. AS4 to protokół transportu Peppol. Wymaga:

  • Podpisania wiadomości AS4 certyfikatem Twojego punktu dostępowego
  • Zaszyfrowania ładunku certyfikatem odbiorcy (z odpowiedzi SMP)
  • Wysłania na EndpointURI z SMP

Implementacja AS4 wykracza poza zakres tego artykułu. W praktyce zbudowanie własnej warstwy AS4 to znaczący wysiłek inżynierski. Większość organizacji korzysta z certyfikowanego dostawcy punktów dostępowych zamiast implementować AS4 bezpośrednio.

Buforowanie

Wyszukiwania SMP powinny być buforowane. TTL DNS na wpisie SML wynosi zazwyczaj 3600 sekund. Metadane usługi SMP nie zmieniają się często. 24-godzinne buforowanie odpowiedzi SMP jest rozsądne dla większości systemów produkcyjnych.

Nie buforuj wyników negatywnych (NXDOMAIN) bezterminowo. Uczestnik może się zarejestrować po Twoim pierwszym wyszukiwaniu. Buforuj wyniki negatywne przez 15 do 30 minut, nie przez dni.

Co może pójść nie tak

NXDOMAIN z SML: uczestnik nie jest zarejestrowany. Jest to stały, a nie przejściowy problem. Nie ponawiaj prób bez dochodzenia.

SMP zwraca 404: uczestnik jest zarejestrowany w SML, ale nie ma metadanych usługi dla żądanego typu dokumentu. Punkt dostępowy odbiorcy może nie mieć skonfigurowanej obsługi Peppol BIS Billing 3.0.

Awaria walidacji certyfikatu: podpis odpowiedzi SMP używa certyfikatu spoza listy zaufanych PKI Peppol. Należy to traktować jako błąd bezpieczeństwa, a nie błąd łączności. Odrzuć odpowiedź.

Awaria podpisu związana z przestrzeniami nazw: patrz Pułapki walidacji podpisów XML w Peppol.

Punkt końcowy zwraca błąd SOAP AS4: faktura została dostarczona, ale odrzucona przez punkt dostępowy odbiorcy. Kod błędu wskazuje, czy odrzucenie wynika z niezgodności certyfikatu, nieobsługiwanego typu dokumentu czy awarii walidacji ładunku.

SealDoc i odkrywanie SMP

SealDoc REST API wykonuje pełny łańcuch odkrywania SMP wewnętrznie. Gdy przesyłasz żądanie generowania faktury z identyfikatorem uczestnika Peppol, API rozwiązuje punkt końcowy, waliduje łańcuch i kieruje dokument. Jeśli odkrywanie zakończy się niepowodzeniem, API zwraca ustrukturyzowany błąd wskazujący, który krok zawiódł. Nie musisz samodzielnie implementować wyszukiwania SML ani SMP.

Dla uczestników potrzebujących wyszukiwań w sieci Peppol do testowania lub audytowania publiczny walidator SealDoc może weryfikować, czy faktura Peppol jest ruchowalna do konkretnego uczestnika przed zatwierdzeniem dostarczenia.


← Back to all articles