Order Update Webhooks

To interact with Stylux's API, you need to ensure your requests are properly authenticated. To safely receive Stylux webhook events, your server must validate the incoming request's HMAC signature.

Authentication

Calls you make to the Stylux API (register webhook, fetch payload, and similar) use HMAC signed API keys. See Signed API Authentication for headers, the canonical string, and a working example.

Inbound webhook deliveries use a different HMAC (documented under Receiving a Webhook Payload below). Do not reuse the outbound request signing steps when validating a delivery from Stylux.

Registering a Webhook

To register an ORDER_UPDATE webhook, use the following endpoint:

POST: /v1/merchants/{merchantId}/webhooks

Use the following sample request body:

{
  "notificationUrl": "https://example.com",
  "webhookEvents": [
    {
      "eventType": "ORDER_UPDATE"
    }
  ]
}

Replace notificationUrl with the actual URL you want webhooks to be delivered to.

This will return an object that contains information about the webhook:

{
  "id": "7c144bfd-3df7-4a6d-9075-0b03077d8f47",
  "notificationUrl": "https://example.com",
  "webhookEvents": [
    {
      "eventType": "ORDER_UPDATE",
      "id": "9fa04414-3159-4fc5-9b3d-e87ea55453d8"
    }
  ]
}

Note: only register the webhook once; you'll need to store the webhook ID for use later.

Receiving a Webhook Payload

Now, whenever an ORDER_UPDATE occurs as part of the Stylux API you'll receive a POST request to your intended notificationUrl with a payload that looks like:

{
  "metadata": {
    "merchantId": "c3b4f85e-ec6f-4d07-8925-65256e2064cc",
    "sentTimestamp": "2025-04-25T22:23:35.958Z"
  },
  "webhookPayloadId": "1a5b3092-c2e0-49b5-9b02-b6d46366f449"
}

As part of this request we include an HMAC signature that your server should validate to ensure that the delivery is from a trustworthy source (i.e., is actually sent by Stylux). All webhooks will include the X-STYLUX-SIGNATURE and X-STYLUX-TIMESTAMP headers. Our webhook delivery pipeline computes this signature as follows: HMAC_SHA512(secret, webhookPayloadSentTimestamp + webhookPayloadBody). You can validate the HMAC signature when receiving the request using the same method to ensure the webhook payload was actually sent by Stylux.

Your server must acknowledge response with a 200 or 204 status code in 10s or less. If a delivery to the recipient fails (either due to status code or timeout) we'll attempt delivery of the webhook payload 20 times total over a ~24 hour period with exponential backoff.

Retrieving a Webhook Payload

Once you receive the webhook payload, you'll then need to fetch the actual payload data:

GET: /v1/merchants/{merchantId}/webhooks/{webhookId}/payloads/{webhookPayloadId}

If a valid webhook payload is requested, you should expect something like the following to be returned from this API:

{
  "deliveryStatus": "DELIVERED",
  "id": "b5fdee0c-67dc-4bae-af51-002844e2608d",
  "webhookData": {
    "contentType": "application/json",
    "id": "39041dec-fac8-4402-878d-a3444c568da6",
    "payload": {
      "orderData": {},
      "previousOrderData": {}
    }
  },
  "webhookEvent": {
    "eventType": "ORDER_UPDATE",
    "id": "6ee61709-6d9d-4bd4-9146-a2b3a3c4277d"
  }
}

Order Object

In the webhook payload, you'll have access to the current/previous order which can sometimes be helpful if needing to determine what specifically changed as part of the order update. A fully qualified order object will look something like:

{
  "status": "OPEN",
  "fulfillmentStatus": "UNFULFILLED",
  "id": "64bba7fb-9a28-4917-9442-7ff94b855773",
  "orderId": "orderId",
  "orderNumber": "#orderNumber",
  "lineItems": [
    {
      "id": "77820a49-b8ea-48e0-90d5-4c7d467c38d4",
      "lineItemId": "lineItemId",
      "price": "89.99",
      "quantity": 2,
      "productId": "productId"
    }
  ],
  "partnerFulfillments": [
    {
      "trackingNumber": null,
      "trackingUrl": null,
      "shippingCompany": null,
      "id": "21f7ca12-5fd7-4769-9d99-563a7d38fef3",
      "shortId": "1-xkazwlpl",
      "status": "PENDING",
      "lineItems": [
        {
          "id": "77820a49-b8ea-48e0-90d5-4c7d467c38d4",
          "lineItemId": "lineItemId",
          "price": "89.99",
          "quantity": 2,
          "productId": "productId"
        }
      ]
    }
  ]
}

Note: there's a lot more contained within the order object that's included in the webhook payload; the above is intended to only show a subset of available fields.

Partner Fulfillments

An order can contain 0 to many partner fulfillments where each partner fulfillment can contain 0 to many line items. For example, in the sample order above there's a single partner fulfillment with 1 line item. The way to interpret this is that there will exist a single fulfillment (or shipment) with that line item (2 of productId will be included in the fulfillment). When a partner fulfillment moves past PENDING (i.e., any of IN_PROGRESS, IN_TRANSIT, DELIVERED, DELIVERY_FAILED) it will have shipment info (i.e., it will contain at least a shippingCompany and if the label was created to be shipped with tracking information it will additionally have a trackingNumber and trackingUrl).


Did this page help you?