• What is webhook?

    Webhooks are a useful tool for applications that want to execute code after a specific event happens, for example, after an purchase order is created, or an return is confirmed, or an order is shipped.

    You can use webhook subscriptions to receive notifications about particular events.

    Instead of telling your app to make an API call every X number of minutes to check if a specific event has occured on a shop, you can subscribe to webhooks. When the event you have registered for occurs, the Moduslink API portal will trigger a notification to your application.

    This will reduce the number of API calls your system has to make, allowing you to build more efficient apps, and update your app instantly after a webhook is received.

    Webhook events you can subscribe to:

    • Sales Order
      • Created
      • Confirmed
      • Cancelled
      • Released
      • Reserved
      • Partially Shipped
      • Shipped
      • Invoiced
      • Paid
    • Returns
      • Created
      • Confirmed
      • Cancelled
      • Partially Received
      • Received
    • Purchase Order
      • Created
      • Confirmed
      • Cancelled
      • Goods Partialy Received
      • Goods Received

    For more information about webhooks refer to the other sections related to webHooks.

  • Configure a webhook

    As part of the onboarding process, ModusLink will configure the applicable WebHook events. The configured events can be changed at any time depending on the requirements or needs.

    You will need to provide the endpoint(s) to receive the WebHook message to Moduslink so we can have the endpoint(s) setup as part of the configuration.

  • Receive a webhook

    Once you register a webhook URL with ModusLink, we will issue a HTTPS POST request to the configured URL every time that event occurs. The request's POST message will contain JSON data relevant to the event that triggered the request.

    The message will have the following information:

    Sample WebHook message:

    {
      "eventType":"Orders.Created",
      "eventObjectId":"42000631",
      "eventObjectName":"orders",
      "eventObjectReference":"Your_ref_60",
      "eventDateTime":"2019-03-27T14:58:03",
      "links":[
        {
          "href":"/fulfillmentapi/v1/orders/42000631",
          "rel":"orders"
        }
      ]
    }

    Below table describes the relevant fields in the webHook message:

    Element Description
    eventType  The event that was triggered
    eventObjectId  RequestId of the event trigger
    RequestId  of the event triggered
    eventObjectName  Type of object e.g. Order, Purchase Order or Return
    eventObjectReference  Your reference
    eventDateTime  Date-timestamp of the event
    Links  Link to the object

    Please note standard each webhook will trigger once, if successfully received. It is however possible a webhook will trigger multiple times, or skips a intermediate status, as due to the asynchronous nature of our webhook queue processing a status can be 'overtaken' by a subsequent status if they did happen in close proximity.

  • Respond to webhook

    Your application acknowledges that it received the WebHook by sending a 200 OK response. Any response outside of the 200 range will be handled by ModusLink as confirmation that you did not receive our webhook. Moduslink does not follow redirects for webhook notifications and will consider a redirection as an error response.

    For every webhook connection error, an automatic retry is attempted 5 times with 5 minute intervals. After that it will be dropped from the queue.

    If you're receiving a ModusLink webhook, it is important that your application responds quickly.

  • Verify a webhook created by ModusLink

    Webhooks created by ModusLink API can be verified by calculating a digital signature.

    Each webhook request includes a base64-encoded X-Moduslink-HMAC-SHA256 header, which is generated using the app's shared secret along with the data sent in the request.

    To verify that the request came from ModusLink, compute the HMAC digest value and compare it to the value in the X-Moduslink-HMAC-SHA256 header. If they match, you can be sure that the Webhook was sent from ModusLink and the data has not been compromised.

    The example below demonstrate how to verify a WebHook request in C# using the Microsoft.NET framework.

                      
     public static class HttpPostTest
     {
        //The below function will process the incoming WebHook request and return   HttpStatusCode'OK' if it is sucessfull 
        public  async Task  ProcessWebhook(HttpRequestMessage request)
        {
            try 
            {
                //Get request data
                string requestData = new  StreamReader(request.Content.ReadAsStreamAsync().Result).ReadToEnd().ToString().Trim();
                //Get the  ModusLink HMAC values from request Header 
                IEnumerable   headerValues = request.Headers.GetValues("X-Moduslink-HMAC-SHA256");
                //Get the SecretKey value from the configuration settings
                string SecretKey = ConfigurationManager.AppSettings["X-Moduslink-HMAC-SHA256" ];
                
                //Varify whether the computed HMAC value  and the HMAC value in the request Header are matching 
                if (VarifyHMACValue(headerValues.FirstOrDefault().Trim(), SecretKey, requestData) ==   true)
                {
                        string webhookinfoJson =  JsonConvert.SerializeObject(requestData);
                        return req.CreateResponse( HttpStatusCode.OK, "WebhookInfo processed successfully");
                }
                else
                {
                        return req.CreateResponse(HttpStatusCode.OK, "WebhookInfo not processed due to the mismtach in XModuslinkHMACSHA256 value");
                }
            }
            catch (Exception ex)
            {
                        return req.CreateResponse(ex);
            }
        }
        //The below function will calculate the HMAC value by using the secret key provided and compare it with the HMAC value available in the request header 
        private static bool VarifyHMACValue( string ModuslinkHMACValue, string secretKey,  string requestData)
        {
            string HMACHeader = ModuslinkHMACValue;
            string CalculatedHMAC = null;
            byte[] secret = Encoding.UTF8.GetBytes(secretKey);
            using (var hasher = new HMACSHA256(secret))
            {
                HMACSHA256 HMAC =  new  HMACSHA256( Encoding.UTF8.GetBytes(secretKey.Trim()));
                byte[] Hash = HMAC.ComputeHash(Encoding.UTF8.GetBytes(requestData));
                CalculatedHMAC = Convert.ToBase64String(Hash);
                //remove the padding character from the CalculatedHMAC
                CalculatedHMAC = CalculatedHMAC.Remove(CalculatedHMAC.Length - 1);
            }
            //Now verify that the actual hash value in the request header is matching with the calucalted hash value.
            if (HMACHeader == CalculatedHMAC)
            {
                        //Do something 
                        return  true;
            }
            else
            {
                        return  false;
            }
        }
     }
    
  • webhook events by Type

    The Client will register a webhook endpoint as per our specifications where Moduslink will post trigger events to notify when there is a change in order processing. The webhook event will be a light weight message conveying the actual event, order reference and information to construct the unique URL of Moduslink status check API to fetch the complete order status. Moduslink clients will have the flexibility to subscribe to the events they are interested to be notified using this webhook mechanism.

    The table below provides a comprehensive list of identified events and their description.

    Event Type   Description
    Orders.Received   Sales Order Receipt– valid message received – "created"
    Orders.Confirmed   Sales Order Created triggered from SAP -> OMS -> API, "confirmed"
    Orders.Cancelled   Sales Order Cancelled / line cancelled "cancelled"
    Orders.Released   Sales Order Released Optional for Tier 1 clients Only: Order Released "released" –  release of FMS credit block
    Orders.Reserved   Stock Reserved Optional for Tier 1 clients Only: Sales Order Reserved "reserved"
    Orders.PartiallyShipped   Sales Order Shipped partially, with Carrier, ServiceCode, AWB, Serial Numbers, packages "partiallyshipped"
    Orders.Shipped   Sales Order Shipped, with Carrier, ServiceCode, AWB, Serial Numbers, packages "shipped"
    Orders.Invoiced   Optional – when FMS relevant:Sales Order Invoiced
    Orders.Paid   Optional – when FMS relevant:Sales Order Paid
         
    Rmas.Received   Return (RMA) Receipt - valid message received – "created"
    Rmas.Confirmed   Return (RMA) Created triggered from SAP -> OMS -> API, "confirmed"
    Rmas.Cancelled   Return (RMA) Cancelled "cancelled"
    Rmas.Returned   Product Received against the Return (RMA).
         
    PO.Create   Purchase Order Receipt– valid message received – "created"
    PO.Confirmed   Purchase Order Created triggered from SAP -> OMS -> API, "confirmed"
    PO.Cancelled   Purchase Order Cancelled / line cancelled "cancelled"
    PO.GoodsPartiallyReceived   Purchase order is partially received
    PO.GoodsReceived   Purchase order is received completly