Webhook Integration for AS2
You can configure AS2 Gateway to send webhook push notifications (HTTP/S) for incoming AS2 messages and MDNs. This simplifies and adds convenience to your B2B data processing systems and workflows: you no longer have to repeatedly check/poll AS2 Gateway for new data, and you can process new data very quickly - because the webhooks actively push data to your system in near real-time. You can navigate to Webhook Configurations from the main menu to visit the currently configured Webhooks list.
1 Overview
1.1 Webhooks - a Quick Introduction
A webhook sends you notifications of events - such as when a new message is received. It is similar to the concept of callbacks in some programming/scripting languages, but instead works over a network protocol - usually HTTP(S).
You can configure AS2 Gateway to send webhook notifications for incoming AS2 messages and MDNs (sync/async). This is very convenient in comparison to other mechanisms for checking incoming data (such as listing unread messages via API), because:
- you no longer have to repeatedly poll AS2 Gateway for new data (like the aforementioned API endpoint, or the SFTP inbox) - in other words, your system can stay passive while AS2 Gateway will actively push data to it
- there is no redundancy (every webhook event corresponds to an actual receive), unlike in polling (where your system would need to keep on communicating, even when there is no new data); this saves the associated processing power and bandwidth on your end
- you are automatically notified of incoming messages/MDNs very quickly, usually within a matter of seconds
- you can use the webhook endpoint to fire/initiate your own custom workflows, leveraging it as a trigger/ingress point in your B2B pipeline without having to resort to internal cronjobs etc.
1.2 How AS2 Gateway Webhooks Work
- You create and deploy a webhook, which is a simple HTTP endpoint (request handler) that can handle the notification data posted by AS2 Gateway in a desired format.
- You add a webhook configuration entry on AS2 Gateway side, pointing to the above URL, along with the desired payload format setting.
- When a new AS2 message (or MDN) is received, AS2 Gateway automatically sends a HTTP POST request to your endpoint, containing details of the received message.
- Your handler processes the received details in the posted data, and decides on the next action - such as fetching the message content (files/attachments) via a Download-Attachments V1 API call or a SFTP get on the inbox, or simply passing along the AS2 message ID to the the next component in your order-processing pipeline.
1.3 Limitations
These refer to the AS2 Gateway webhook feature at the time of writing; some of they may already be improved/rectified.
- Raw-payload mode of received-message webhooks does not support multiple attachments; if you receive several files in one AS2 message, you will only receive the content of the first file in the webhook payload.
- For HTTPS webhook endpoints, additional steps may be required if the TLS certificate is not trusted (i.e. if the certificate is self-signed or issued by an untrusted party).
- Webhook requests are best-effort, and currently do not offer guaranteed delivery (i.e. are not automatically retried) and neither manual retries; if your endpoint fails due to some reason, AS2 Gateway will not invoke the webhook again for the same message/MDN. While the AS2 Gateway Team is working on improving the retry mechanisms, you can mitigate this using a hybrid approach - such as marking each message as read upon successful download/processing, and adding a SFTP/API based polling logic (at a slow rate) to capture any “skipped” messages that have remained unprocessed (unread) for more than a few minutes. Additionally, if there is a failure in pushing any of the production notifications on AS2 Gateway side, the team will notify you via alternative channels.
- Webhooks cannot currently be configured via the AS2 Gateway web console (browser UI). Please open a support request with AS2 Gateway Team if you wish to add a new webhook or modify an existing one.
2 Webhook Configuration
A webhook configuration on AS2 Gateway may include all or a subset of the following fields:
- a trading station
- a trading partner
- a webhook URL for receiving “message received” events, with an associated payload format
- a webhook URL for receiving “MDN received” events, with an associated payload format
Station and Partner
These fields can be used to filter (receive only a subset of) events based on the source (partner) and destination (station), or to direct or route receive events from different sources/destinations to different webhooks.
Configurations described in this section with the term “messages”, are applicable for MDNs as well.
Multiple Webhooks
For example, you can set up one webhook to only receive events for messages sent by an ACME partner to a MY-OWN-ORG station. At the same time you can configure more webhooks to handle other station-partner combinations (ACME → MY-SECOND-ORG, AMZN → MY-SECOND-ORG, etc.).
2.1 Semi-global Fallback Webhooks (Multi-station or Multi-partner)
If you leave one of the station or partner fields unspecified, the resulting webhook URL will receive all events that do not match other “more specific” webhook entries.
For example, a message webhook with station MY-OWN-ORG and partner unspecified, will receive events for all messages received by MY-OWN-ORG from partners that are not already covered by other webhooks. That is, if you have the following webhooks:
ACME -> (unspecified)
ACME -> MY-OWN-ORG
an ACME → MY-OWN-ORG message will trigger the second webhook while ACME → MY-SECOND-ORG will trigger the first.
For consistency, an organization can have only one of each type of semi-global webhooks: one to cover unspecified stations, and another for unspecified partners.
2.2 The (Fully) Global Fallback Webhook (Multi-station, Multi-partner)
Your organization can have one global webhook (specifying neither a station nor a partner) that will handle all messages that do not match a “more specific” webhook.
Expanding on the previous semi-global example, an AMZN → MY-OWN-ORG message will trigger the global webhook; as it would not match any other webhook entries.
2.3 Webhook URLs
URLs can be either HTTP or HTTPS. When invoked, they should return a HTTP 2xx (success-range) response, ideally with an empty body (payload), for the call to be considered successful. AS2 Gateway’s webhook invocations currently do not follow redirects (HTTP 301, 302, 307 etc.).
If your HTTPS webhook endpoint has a TLS certificate that is not implicitly trusted by AS2 Gateway, it may need to be explicitly imported into the system. You can import such certificates into your certificate store, under HTTPS type.
If using the raw payload mode, your HTTP handler should be able to accept raw binary data (depending on the nature of the attachment types that your partner is expected to be sending).
2.4 Payload Formats or Modes
Depending on your use case, you can instruct AS2 Gateway to invoke your webhook using one of the following payload formats:
2.4.1 Headers-only (default)
Request contains a set of HTTP headers that include metadata fields representing the message: sender/partner (AS2-From), AS2-level message ID (Message-ID), etc. The payload (body) is empty.
2.4.2 JSON Metadata
Request contains the above headers, and also a JSON payload representing the received entity (AS2 message/MDN) - compatible with the API data model.
2.4.3 Raw Payload
In addition to the previously-mentioned headers, data from the original event is directly posted in the payload:
- for an AS2 message: the (first) attachment from the decoded content
- for an MDN: the original, raw MIME payload of the MDN
3 Webhook Events
3.1 Webhooks for “Received Message” Events
When AS2 Gateway receives a new AS2 message on your behalf (to one of your stations, from one of your partners), it will send a HTTP POST request to the message webhook URL that you have configured - usually within a few seconds - containing the metadata of that message.
3.1.1 Extracting Metadata from HTTP Request Headers
Content of the request would vary, based on the selected payload mode/format. Yet, all requests would contain the following HTTP headers for quick access to the whereabouts of the message:
- AS2-From: AS2 identifer of the sender (remote trading partner)
- AS2-To: AS2 identifer of the receiver (your trading station)
- Message-ID: AS2 identifier of the received message
- Subject: subject line of the received message
- X-Partner-Type: type of the trading partner as configured on AS2 Gateway; “Test” or “Production”
Additional HTTP/AS2 headers may also be present, which can safely be ignored. Original headers received in the AS2 message are passed through to the webhook, verbatim; character case (upper/lower), whitespaces etc. of header keys may differ based on the sender’s AS2 system.
3.1.2 Handling errors
If there was an error processing the AS2 message, an additional X-Processing-Error header will be added; containing the error data, in this format:
errorCode1: error message 1; errorCode2: error message 2; ...
E.g.:
X-Processing-Error: 800: Decryption failure: bad certificate; 1100: Parse failed
In such cases, the raw payload mode may not contain any data (i.e. an empty request body).
3.2 Payload Formats
3.2.1 Headers-only (default)
Only the headers are available; payload will be empty.
As outlined before, almost all the important pieces of data are available as individual tokens in the header values, and can be extracted out straightaway (in a request.getHeader(“name”) fashion) without having to do any additional parsing.
POST /webhook/message HTTP/1.1
mime-version: 1.0
date: Mon, 15 Jun 2020 13:48:56 IST
as2-version: 1.2
subject: Invoice #981712
recipient-address: http://service.as2gateway.com:8280/service/as2-receiver
receipt-delivery-option: http://acme.hostname:8085/as2/receiver
ediint-features: multiple-attachments, CEM
as2-from: ACME
message-id: <AS2-1592209136307-2@ACME_MY-OWN-ORG>
X-Forwarded-For: 52.204.119.191
as2-to: MY-OWN-ORG
from: sender@acme.hostname
Content-Type: application/pkcs7-mime; name="smime.p7m"; smime-type=enveloped-data
disposition-notification-to: http://acme.hostname:8085/as2/receiver
disposition-notification-options: signed-receipt-protocol=optional, pkcs7-signature;
signed-receipt-micalg=optional, sha-256
X-Partner-Type: Production
Content-Length: 0
Host: webhook.myown.org
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
3.2.2 JSON Metadata
In addition to headers, the request contains a JSON payload representing the received AS2 message, resembling an AS2 Message entity from the API.
POST /webhook/message HTTP/1.1
mime-version: 1.0
date: Mon, 15 Jun 2020 13:48:56 IST
as2-version: 1.2
subject: Invoice #981712
recipient-address: http://service.as2gateway.com:8280/service/as2-receiver
receipt-delivery-option: http://acme.hostname:8085/as2/receiver
ediint-features: multiple-attachments, CEM
as2-from: ACME
message-id: <AS2-1592209136307-2@ACME_MY-OWN-ORG>
X-Forwarded-For: 52.204.119.191
as2-to: MY-OWN-ORG
from: sender@acme.hostname
Content-Type: application/json
disposition-notification-to: http://acme.hostname:8085/as2/receiver
disposition-notification-options: signed-receipt-protocol=optional, pkcs7-signature;
signed-receipt-micalg=optional, sha-256
X-Partner-Type: Production
Content-Length: 255
Host: webhook.myown.org
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
{"as2MessageId":"<AS2-1592209136307-2@ACME_MY-OWN-ORG>","compressed":false,"encrypted":true,"signed":true,"subject":"PrchOrd #981712","receiverId":"MY-OWN-ORG","senderId":"ACME","partnerType":"Production","attachments":[{"name":"981712.xml","size":3570}]}
3.2.3 Raw Payload
In addition to headers, the attachment received within the AS2 message is posted in the payload, along with appropriate Content-Disposition (original file name) and Content-Type headers.
POST /webhook/message HTTP/1.1
mime-version: 1.0
date: Mon, 15 Jun 2020 13:48:56 IST
as2-version: 1.2
subject: Invoice #981712
recipient-address: http://service.as2gateway.com:8280/service/as2-receiver
receipt-delivery-option: http://acme.hostname:8085/as2/receiver
ediint-features: multiple-attachments, CEM
as2-from: ACME
message-id: <AS2-1592209136307-2@ACME_MY-OWN-ORG>
X-Forwarded-For: 52.204.119.191
as2-to: MY-OWN-ORG
from: sender@ACME.com
disposition-notification-to: http://acme.hostname:8085/as2/receiver
disposition-notification-options: signed-receipt-protocol=optional, pkcs7-signature;
signed-receipt-micalg=optional, sha-256
X-Partner-Type: Production
Content-Length: 3570
Host: webhook.myown.org
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
Content-Disposition: attachment; filename=981712.xml
Content-Type: text/xml
<?xml version="1.0" encoding="UTF-8"?>
<invoice>
<header>
...
</invoice>
If the message contained multiple files, only the first one is posted in the request. In such cases, an additional X-Truncated: Attachments: 1/n header is included to indicate the total number (n) of available attachments.
3.2 Webhooks for “Received MDN” Events
When AS2 Gateway receives an MDN receipt for a message you have sent out (to one of your partners from one of your stations), it will send a HTTP POST request to the MDN webhook URL that you have configured, along with the metadata of that MDN.
The webhook is invoked for both synchronous (returned on the same HTTP channel that sends out the message) and asynchronous (sent back later by the partner as a new HTTP request) MDNs.
3.2.1 Extracting Metadata from HTTP Request Headers
Content of the request would vary, based on the selected payload mode/format. Yet, all requests would contain the following HTTP headers for quick access to the whereabouts of the message:
- AS2-From: AS2 identifier of the MDN sender (remote trading partner)
- AS2-To: AS2 identifier of the MDN receiver (your trading station)
- Message-ID: AS2 identifier of the MDN
- Original-Message-ID: AS2 identifier of the original (sent) message corresponding to this MDN
- Received-Content-MIC: Content-MIC value extracted from the MDN
- Subject: subject line of the MDN
- X-Partner-Type: type of the trading partner as configured on AS2 Gateway; “Test” or “Production”
Additional HTTP/AS2 headers may also be present, which can safely be ignored. Original AS2/HTTP headers received in the MDN are passed through to the webhook, verbatim; character case (upper/lower), whitespaces etc. of header keys may differ based on the sender’s AS2 system.
Original-Message-ID and Received-Content-MIC are not standard AS2/HTTP headers; they are extracted from the MDN content and included into the webhook’s HTTP headers, for your convenience.
3.2.2 Error MDNs
If the MDN contains an error, an additional X-Processing-Error header will be added; containing the error data, in this format:
errorCode1: error message 1: description 1; errorCode2: error message 2: description 2; ...
E.g.:
X-Processing-Error: 300: Invalid content for async MDN: Generic error; 400: Unexpected processing error: Generic error
3.2.3 Payload Formats
3.2.3.1 Headers-only (default)
Only the headers are available; payload will be empty.
As outlined before, almost all the important pieces of data are available as individual tokens in the header values, and can be extracted out straightaway (in a request.getHeader(“name”) fashion) without having to do any additional parsing.
POST /webhook/mdn HTTP/1.1
mime-version: 1.0
date: Mon, 22 Jun 2020 12:29:34 IST
server: acme.server
Received-Content-MIC: BdwvEtnDb5zfkORKm6fK/hZNxhinbjFUdp7ZpgzcYVI=, sha-256
as2-version: 1.2
subject: Message Delivery Notification
recipient-address: http://service.as2gateway.com:8280/service/as2-async-mdn-receiver
ediint-features: multiple-attachments, CEM
as2-from: ACME
message-id: <AS2-1592809174111-6@_MY-OWN-ORG>
X-Forwarded-For: 52.204.119.191
as2-to: MY-OWN-ORG
from: sender@acme.hostname
Content-Type: multipart/signed; protocol="application/pkcs7-signature";
micalg=sha1; boundary="----=_Part_33_188931338.1592809174127"
Original-Message-ID: <1647581489.0.1592807247716@as2gateway.com>
X-Partner-Type: Production
Content-Length: 0
Host: webhook.myown.org
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
3.2.3.2 JSON Metadata
In addition to headers, the request contains a JSON payload representing the received MDN, resembling an MDN entity from the V1 API.
POST /webhook/mdn HTTP/1.1
mime-version: 1.0
date: Mon, 22 Jun 2020 12:29:34 IST
server: acme.server
Received-Content-MIC: BdwvEtnDb5zfkORKm6fK/hZNxhinbjFUdp7ZpgzcYVI=, sha-256
as2-version: 1.2
subject: Message Delivery Notification
recipient-address: http://service.as2gateway.com:8280/service/as2-async-mdn-receiver
ediint-features: multiple-attachments, CEM
as2-from: ACME
message-id: <AS2-1592809174111-6@_MY-OWN-ORG>
X-Forwarded-For: 52.204.119.191
as2-to: MY-OWN-ORG
from: sender@acme.hostname
Content-Type: application/json
Original-Message-ID: <1647581489.0.1592807247716@as2gateway.com>
X-Partner-Type: Production
Content-Length: 65
Host: webhook.myown.org
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
{"content":"The AS2 message has been received.","mdnError":false}
3.2.3.3 Raw Payload
In addition to headers, the raw MIME content of the received MDN is posted in the payload. This is a MIME multipart (as per the AS2 specification) and can be parsed using the boundary from the Content-Type header.
POST /webhook/mdn HTTP/1.1
mime-version: 1.0
date: Mon, 22 Jun 2020 12:29:34 IST
server: acme.server
Received-Content-MIC: BdwvEtnDb5zfkORKm6fK/hZNxhinbjFUdp7ZpgzcYVI=, sha-256
as2-version: 1.2
subject: Message Delivery Notification
recipient-address: http://service.as2gateway.com:8280/service/as2-async-mdn-receiver
ediint-features: multiple-attachments, CEM
as2-from: ACME
message-id: <AS2-1592809174111-6@_MY-OWN-ORG>
X-Forwarded-For: 52.204.119.191
as2-to: MY-OWN-ORG
from: sender@acme.hostname
Content-Type: multipart/signed; protocol="application/pkcs7-signature";
micalg=sha1; boundary="----=_Part_33_188931338.1592809174127"
Original-Message-ID: <1647581489.0.1592807247716@as2gateway.com>
X-Partner-Type: Production
Content-Length: 65
Host: webhook.myown.org
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
------=_Part_33_188931338.1592809174127
Content-Type: multipart/report; report-type=disposition-notification;
boundary="----=_Part_8_1487173726.1576500399649"
------=_Part_8_1487173726.1576500399649
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
MDN for Message-ID: <1647581489.0.1592807247716@as2gateway.com>
...
3.3 Webhooks for “Message Send Failed” Events
When AS2G faces a permanent failure while trying to send a message out (usually due to a non-retryable error or the exhaustion of automatic retries), it will send a HTTP POST request to the send-failure webhook URL, along with details of the failed message. This is comparable to the message send-failure email notifications available at station settings, but more flexible and automation-friendly.
3.3.1 Metadata from Request Headers
All send-failure webhook requests would contain the following HTTP headers:
X-Partner-Type
: type of the trading partner as configured on AS2 Gateway; “Test” or “Production”X-Processing-Error
: message describing encountered error (from the last attempt, in case there were multiple retries)
3.3.2 Payload Format
In addition to above headers, the request contains a JSON payload representing the failed message (as an AS2 Message entity from V1 API).
(Unlike other webhook events, only the JSON-metadata payload format is available for send-failure webhooks.)
POST /webhook/send-failed HTTP/1.1
X-Processing-Error: HTTP 501
X-Partner-Type: Production
Date: Mon, 22 Jun 2020 12:43:45 GMT
Content-Type: application/json
Content-Length: 211
Host: localhost
Connection: Keep-Alive
User-Agent: AdroitLogic UltraESB-X
Accept-Encoding: gzip
{"as2MessageId":"<1228921116.0.1592829825399@as2gateway.com>","compressed":true,"encrypted":true,"signed":true,"subject":"Invoice #4719701","receiverId":"ACME","senderId":"MY-OWN-ORG","partnerType":"Production"}