Skip to content

Profile Peppol

Philip Helger edited this page Oct 31, 2023 · 5 revisions

phase4 was originally developed for usage in the Peppol eDelivery network.

Underlying specification: https://docs.peppol.eu/edelivery/as4/specification/ for the full specification

This solution is Peppol compliant since 2019. See the test report at https://github.com/phax/phase4/blob/master/docs/Peppol/TestBedReport-POP000306-20190906T103327.pdf

See also https://github.com/phax/phase4-peppol-standalone for an example of a standalone application

AS4 Profiles

This submodule comes with one profile only:

  • ID peppol

Peppol Prerequisites

To perform testing with Peppol you MUST have a valid Peppol certificate. Testing with a self-signed certificate does not work. Only certificates that are based on the Peppol AP PKI will be accepted. You may read https://peppol.helger.com/public/locale-en_US/menuitem-docs-peppol-pki for more information on the Peppol PKI. To retrieve a Peppol certificate, you must be a member of OpenPeppol AISBL - see https://peppol.eu/get-involved/join-openpeppol/ for details.

Peppol AS4 specifics

OASIS AS4 is a profile of OASIS EBMS v3. CEF AS4 is a profile of OASIS AS4. Peppol AS4 is a profile of CEF AS4. Find the Peppol specification document at https://docs.peppol.eu/edelivery/as4/specification/

Peppol has a very limited use of AS4. Some highlights are:

  • It uses only one-way push
  • TLS certificates must have SSL labs test grade "A" - that means e.g. no TLS 1.0 or 1.1 support
  • Signing and encryption rules follow the CEF AS4 profile requirements (AES 128 CGM, SHA-256)
  • It allows only for one AS4 payload
  • You have to use MIME encoding for the payload (as defined by the underlying SOAP with Attachments specification) - and are not allowed to add it into the SOAP body
  • The payload is always an SBD envelope (Standard Business Document; mostly wrongly addressed as SBDH - Standard Business Document Header) - same as it was for Peppol AS2
  • Compression must be supported but can be chosen on the senders choice

Maven Coordinates

    <dependency>
      <groupId>com.helger.phase4</groupId>
      <artifactId>phase4-profile-peppol</artifactId>
      <version>x.y.z</version>
    </dependency>

Subproject phase4-peppol-client

This subproject is your entry point for sending messages into the Peppol eDelivery network.

The contained project contains a class called Phase4PeppolSender.Builder (accessible via factory method Phase4PeppolSender.builder()) - it contains all the parameters with some example values so that you can start easily. Alternatively the class Phase4PeppolSender.SBDHBuilder (accessible via factory method Phase4PeppolSender.sbdhBuilder()) offers a builder class where you can add your pre-build StandardBusinessDocument, which implies that no implicit validation of the business document takes place. This class contains utility methods to explicitly validate the payload.

As a prerequisite, the file application.properties must be filled out correctly and your Peppol AP certificate must be provided.

See the folder https://github.com/phax/phase4/tree/master/phase4-peppol-client/src/test/java/com/helger/phase4/peppol for different examples on how to send messages via the Peppol AS4 client. Some of them use the SMP client to find the connection parameters, in some cases the X.509 certificates and endpoint URLs are provided explicitly (for testing purposes only of course).

The client side validation of outgoing business documents is implemented using phive (Philip Helger Integrative Validation Engine, OSS, Apache 2.0 Licence). By default the Peppol rules are available. Additional rules for other formats are available via phive-rules (OSS, Apache 2.0 License) and can be added to the configuration.

Subproject phase4-peppol-servlet

This subproject is your entry point for receiving messages from the Peppol eDelivery network using the well known Servlet technology.

It assumes you are running an Application server like Apache Tomcat or Eclipse Jetty to handle incoming connections. Integrations into other application servers like vertx or even the deployment as an AWS Lambda is possible but needs a bit more hand-crafting.

Register the Servlet com.helger.phase4.peppol.servlet.Phase4PeppolServlet in your application. Then implement the SPI interface com.helger.phase4.peppol.servlet.IPhase4PeppolIncomingSBDHandlerSPI to handle incoming Peppol messages. See Introduction to the Service Providers Interface if you are not familiar with the Java concept of SPI.

Sample setup for WEB-INF/web.xml:

<servlet>
  <servlet-name>Phase4PeppolServlet</servlet-name>
  <servlet-class>com.helger.phase4.peppol.servlet.Phase4PeppolServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>Phase4PeppolServlet</servlet-name>
  <url-pattern>/as4</url-pattern>
</servlet-mapping>

By default the "receiver checks" are enabled. They are checking if an incoming message is targeted for the correct Access Point and if not will reject the message. That is done by performing an SMP lookup on the receiver/document type/process ID and check if the resulting values match the preconfigured values. That of course requires that the preconfigured values need to be set, before a message can be received. That needs to be done via the static methods in class Phase4PeppolServletConfiguration. Alternatively you can disable the receiver checks using the setReceiverCheckEnabled method in said class.

Additionally before you can start, an IAS4CryptoFactory MUST be set. An implementation of this interface provides the keystore as well as the private key for doing signing and/or encryption services in phase4. Default implementations shipping with phase4 are AS4CryptoFactoryProperties and AS4CryptoFactoryInMemoryKeyStore. To change that configuration use the extended constructor of AS4XServletHandler that itself is instantiated in the Phase4PeppolServlet - therefore a custom Servlet class is required, where Phase4PeppolServlet should be used as the "copy-paste template" (and don't forget to reference the new servlet class from the WEB-INF/web.xml mentioned above).

Subproject phase4-peppol-server-webapp

This subproject shows how to a simple standalone Peppol AS4 server could look like. It is a demo implementation and does not do anything with the payload except storing it on disk. Use this as the basis for implementing your own solution - don't take it "as is". It takes incoming requests via HTTP POST at the URL /as4.

Upon startup it checks that a valid Peppol Access Point (AP) certificate is installed.

It stores all incoming requests on disk based on the incoming date time.

  • The full incoming message is stored with extension .as4in
  • The SOAP document is stored with extension .soap
  • The (decrypted) Peppol payload (SBD Document) is stored with extension .sbd
  • The returned receipt is stored with extension .response

To configure your certificate, modify the file phase4.properties. Usually there is no need to alter the truststore - it's the Peppol default truststore and considered to be constant.

Note: this application uses the property smp.url in configuration file phase4.properties to locate it's home SMP for cross checking if the incoming request is targeted for itself.

To start it from within your IDE you may run the test class com.helger.phase4.peppol.server.standalone.RunInJettyPHASE4PEPPOL - it will spawn on http://localhost:8080`. For IntelliJ users: make sure the folder phase4-peppol-server-webapp is the startup directory.

Special handling for Peppol Reporting

Since phase4 v2.2.2 it supports creation of Peppol Reporting items. It uses the peppol-reporting (OSS, Apache 2.0 license) library to create PeppolReportingItem objects. Please the website of the other module for the details of the process.

Creating records on sending

When sending messages via the builder classes Phase4PeppolSender.Builder or Phase4PeppolSender.SBDHBuilder two new methods are provided

  • createPeppolReportingItemAfterSending(...) - creates an instance of PeppolReportingItem but you need to store the entry manually
  • createAndStorePeppolReportingItemAfterSending(...) - as the name suggest it use the above mentioned method to create a PeppolReportingItem and then stores it to a Reporting backend based on the PeppolReportingBackend
    • This may fail if no Peppol Reporting Backend is configured (one implementation must be provided)
    • This may fail with a backend specific error (e.g. no database connection created)
    • Some document types are excluded from reporting, so they are not stored. This is ensured via PeppolReportingHelper.isDocumentTypeEligableForReporting

The configuration parameters for an eventually used reporting backend are taken from the same configuration sources as for the rest of phase4.

Creating records on receiving

For receiving messages, the support is not as good as for sending, as additional information is required (country code of C4 and the main end user ID), that is most likely not available in the AccessPoint itself but in a separate system.

The class Phase4PeppolServletMessageProcessorSPI received a static method createPeppolReportingItemForReceivedMessage to create a PeppolReportingInstance for a received message. However no specific storage shortcut is provided as PeppolReportingBackend.withBackendDo already provides a relatively convenient wrapper.