PEPPOL Service Bus Hooks

Use hooks to be notified about events of the Peppol Service Bus.
The Peppol Service Bus can send webhooks and email notifications to your application about events that happened in your Party. This mechanism is very useful for receiving invoices. Once an invoice has arrived you will be notified via the registered hooks.

There are several types of Hooks possible. The type of Hook depends on the action defined. There are two general available actions  Mail and https.

There are several moments a hook can be triggerd. This is defined by topics.

Topics

The topic indicates when the hook is to be called.

Topic Function
InvoiceReceived Triggerd when document is succesfully received by PEPPOL Service Bus
InvoiceReceivedError Triggerd on document that is rejected by PEPPOL Service Bus because of a error
InvoiceSent Triggerd when document is succesfully sent by PEPPOL Service Bus and received by other party
InvoiceSentError Triggerd on document that is rejected by receiver because of a error. This is a permanent error and document will not be send
InvoiceSentRetry Triggerd on document that is rejected by receiver because of a error. This can be a tempory failure. Retries will be done
Special Hooks See if hooks are working correctly. Only the email action can be used
HookSent Triggers when a hook is triggered and a hook message is sent. This means the receiving system is informed about a topic.
HookSentRetry Triggers when a hook is triggers but the message was not send because the receiver can’t be reached and a retry will be done. This is a indication that your hook receiver is not working correctly and the PEPPOL Service  Bus is unable to inform about the status of processed documents.
HookSentError Triggers when a hook has stopped retrying. This is a permanent error.

MailHooks

A mail hook has the following action:  “action”:”mailto:receiver@example.com”

WebHooks

Webhooks deliver information by pushing a https message to a receiver. This can only be done with https.

Configure your webhook

You can register the webhook via PUT method on the /Hook endpoint. The Peppol Service Bus starts sending HTTP POST webhooks once the webhook is registered, and only will send events that occur after registration and on the registered topics.
Define an action with your endpoint Url and append this Url with a # and a secret key. This key will be used to sign the requests. You can optionally define the basic authentication in the action to protect your endpoint in the form of: https://user:pass@your.endpoint#someRandomKey.

{
    "id": "1",
    "name": "webhook",
    "action": "https://user:pass@webhook.site/a81a0be5-8aad-4110-a40c-aa41a2c6e9ac#secureKey",
    "topics": [
      "InvoiceReceived"
    ],
    "isActive": true
 }

Testing webhook

For testing the call GET /api/v1/{partyId}/hook/ping can be used. This call will trigger the InvoiceReceived hook by sending a dummy document to {partyId}.

Securing webhook

We use an HMAC SHA256 signature of the payload and include that signature in the request header X-EConnect-Signature. The header value is in the form of sha256=signature, where signature is a 64-byte, hexadecimal representation of a SHA256 signature. The signature is computed using a secret key provided  by you. Validate this signature to make sure the data is not manipulated and sent form the PSB.

You could also whitelist these IP addresses: 104.40.188.59 (psb.econnect.eu) for production and 51.144.92.226 (accp-psb.econnect.eu) for acceptance.

The payload contains a sentOn field. Make sure that this date is not older than 5 minutes to prevent relay attacks.

Responding to a webhook

To acknowledge receipt of a webhook, your endpoint should return a 2xx HTTP status code. Any response code outside of this range, including 3xx codes, will indicate that you did not receive the webhook.

We will attempt to deliver your webhooks up to five days with an exponential back off. Setup a mail hook with the topic HookSentError, to be notified about a delivery failure. The webhooks cannot be manually triggered.

We only accept https endpoints with a valid server certificate.

Disable any CSRF protection on your webhook endpoints to avoid the webhook being blocked.

Returned elements

topic Topic that triggering the hook
partyId Hook owning partyID. The party that sent or received a document
hookId The hook that triggerd the message
documentId Id of document that is is processed.
createdOn Orignal date the hook is triggerd
sentOn Date the hook is actual sent

An example of a webhook request:

Content-Type: application/json
X-EConnect-Signature: sha256=32db41dabde9d6462d5eaf1c96509745fcf3201b4dea780325b41e1d4ce52254
X-EConnect-Delivery: 51d3173a-d446-480c-a4a2-c310ecc60ab4
Content-Length: 216

{"topic":"InvoiceReceived","partyId":"NL:KVK:ECONNECTTEST","hookId":"3","documentId":"11253212-d065-485a-9e2d-68c8764181b7","createdOn":"2019-02-07T19:17:32.305612+01:00","sentOn":"2019-02-07T18:17:33.1864657+00:00"}

You cloud use https://www.freeformatter.com/hmac-generator.html to manually validate the signature. Enter your secret key and select SHA256 as the digest algorithm, then compute the hash.

Validate Webhook signatures

1. Get the signature from Header.

var signature = context.Request.Headers.Get("X-EConnect-Signature")

2. Get json payload from the request body and your secret key.
3. Compute signature using the payload and secret key. Then stringify the byte[] to a hexadecimal representation, and prepend the string with “sha256=”.

{
    var encoding = new System.Text.UTF8Encoding();
    byte[] keyByte = encoding.GetBytes(secret);
    byte[] messageBytes = encoding.GetBytes(message);
    using (var hmacsha256 = new HMACSHA256(keyByte))
    {
        byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);

        var builder = new StringBuilder();
        builder.Append("sha256=");
        for (var i = 0; i < hashmessage.Length; i++)
        {
            builder.Append(hashmessage[i].ToString("x2"));
        }

        return builder.ToString();
    }
}

4. Compare signatures. (We advise to use a secure compare.)

Was this article helpful?