Set up order and tracking webhooks

Set up a webhook so that Dropday tells your own system when an order is forwarded to a supplier, opened by the supplier or shipped.

Add a webhook

You need a user who can manage the account.

  1. Go to Settings → Webhooks.

  2. Add a webhook: give it a name, a description and the URL of your endpoint.

  3. Choose one or more events to subscribe to.

Events

  • supplier_order.created: an order was forwarded to a supplier. It includes the supplier and the time it was forwarded (forwarded_at).

  • supplier_order.opened: the supplier opened the order for the first time. It includes the time it was opened (opened_at).

  • supplier_order.shipped: the supplier marked the order as shipped. It includes the shipment time (shipped_at), the tracking code (tracking_code) and tracking link (tracking_url), the supplier and the order data. It also includes a carrier object with a code and a name, or null when Dropday doesn't recognise the carrier.

  • products.updated: a product feed finished importing. Follow product feed updates with a webhook and the API shows what it contains.

A supplier order event carries the order with only the order lines of that supplier order. Orders with several suppliers explains the split.

What Dropday sends

Dropday sends each event to every active webhook of your account that is subscribed to it, as a JSON POST. The body is an envelope with id, event, created_at and data, and data holds the content of the event.

For the three supplier order events, data has the same shape:

  • every event has supplier_order_id, supplier_id, supplier_name and order;

  • each event adds its own fields at the top of data: forwarded_at for supplier_order.created, opened_at for supplier_order.opened, and shipped_at, tracking_code and tracking_url for supplier_order.shipped. The times are in ISO 8601;

  • order has id, external_id (your webshop's order ID), reference, source, test, blocked, total, shipping_address, shipping, custom, order_lines, created_at, updated_at and finalized_at;

  • shipping_address has email, first_name, last_name, company_name, phone, address1, address2, city, postcode, state, country and country_iso, and shipping has cost, name, description, note and delivery_date;

  • each line in order_lines has id, external_id, ean13, reference, name, quantity, brand, category, labels, stock_quantity, supplier, price, purchase_price, height, width, length, weight, image_url and custom. quantity is the quantity on this supplier order, and supplier is the name of the product's supplier.

The example below shows where these fields sit in a supplier_order.shipped event with one order line. The values are placeholders: Dropday fills in the real values of the order, and your endpoint receives the whole body.

{
  "id": "EVENT_ID",
  "event": "supplier_order.shipped",
  "created_at": "CREATED_AT",
  "data": {
    "supplier_order_id": "SUPPLIER_ORDER_ID",
    "supplier_id": "SUPPLIER_ID",
    "supplier_name": "SUPPLIER_NAME",
    "shipped_at": "SHIPPED_AT",
    "tracking_code": "TRACKING_CODE",
    "tracking_url": "TRACKING_URL",
    "order": {
      "id": "ORDER_ID",
      "external_id": "WEBSHOP_ORDER_ID",
      "reference": "REFERENCE",
      "source": "SOURCE",
      "test": "TEST",
      "blocked": "BLOCKED",
      "total": "TOTAL",
      "shipping_address": {
        "email": "EMAIL",
        "first_name": "FIRST_NAME",
        "last_name": "LAST_NAME",
        "company_name": "COMPANY_NAME",
        "phone": "PHONE",
        "address1": "ADDRESS1",
        "address2": "ADDRESS2",
        "city": "CITY",
        "postcode": "POSTCODE",
        "state": "STATE",
        "country": "COUNTRY",
        "country_iso": "COUNTRY_ISO"
      },
      "shipping": {
        "cost": "COST",
        "name": "NAME",
        "description": "DESCRIPTION",
        "note": "NOTE",
        "delivery_date": "DELIVERY_DATE"
      },
      "custom": "CUSTOM",
      "order_lines": [
        {
          "id": "LINE_ID",
          "external_id": "LINE_EXTERNAL_ID",
          "ean13": "EAN13",
          "reference": "SKU",
          "name": "PRODUCT_NAME",
          "quantity": "QUANTITY",
          "brand": "BRAND",
          "category": "CATEGORY",
          "labels": "LABELS",
          "stock_quantity": "STOCK_QUANTITY",
          "supplier": "SUPPLIER_NAME",
          "price": "PRICE",
          "purchase_price": "PURCHASE_PRICE",
          "height": "HEIGHT",
          "width": "WIDTH",
          "length": "LENGTH",
          "weight": "WEIGHT",
          "image_url": "IMAGE_URL",
          "custom": "CUSTOM"
        }
      ],
      "created_at": "CREATED_AT",
      "updated_at": "UPDATED_AT",
      "finalized_at": "FINALIZED_AT"
    }
  }
}

Each request has an X-Dropday-Event header and an X-Dropday-Signature header.

Verify the signature

X-Dropday-Signature is the HMAC-SHA256 of the raw request body, keyed with the webhook's secret, as a lowercase hexadecimal string. It has no prefix such as sha256= and is not base64.

To verify a delivery, compute the HMAC-SHA256 of the raw request body with the webhook's secret and compare the 64-character hex string with the header. Use the exact bytes Dropday sent, not a body you parsed and encoded again. In PHP, the computation is:

$expected = hash_hmac('sha256', $rawBody, $webhookSecret);

Here $rawBody is the raw request body and $webhookSecret is the webhook's secret. The delivery is from Dropday when $expected is the same as the value of the X-Dropday-Signature header.

Manage webhooks and deliveries

You can switch a webhook on or off, rotate its signing secret, and view, filter and retry individual deliveries.

When a delivery fails, because your endpoint gives no successful response within 10 seconds or returns an error, Dropday retries it automatically. It makes up to 5 attempts, waiting 1 minute, 5 minutes, 15 minutes and 1 hour between them.

Manage webhooks through the API

An integration can manage your account's webhooks through the Dropday API: list, create, read, update and delete them. They are the same webhooks you manage under Settings → Webhooks. The requests are authenticated with the api-key and account-id headers (Authentication in the API documentation). An update with PATCH changes only the fields it sends.

GET /api/v1/webhooks/events returns the valid event names, each with a description and a category, so your integration doesn't have to hard-code them.

The webhook secret is returned only when you create a webhook through the API. Reading or listing webhooks does not include it.

An account can't have two webhooks with the same URL: creating or updating one with a URL your account already has is rejected, in the dashboard and through the API.

Through the API, an integration can only reach the webhooks of its own account. A webhook of another account is reported as not found.

Failed sends

There is no webhook event for a failed send to a supplier. A failed send is recorded on the order lines, and your system can read it through the Dropday API: GET orders/{reference} returns each order line with its status history, where failed attempts show as failed.