Merchants
Webhooks

Webhooks

Webhooks provide real-time notifications whenever an order or return changes state. They are designed as asynchronous notifications, not synchronous APIs.

See also: Webhook Events by State


Overview

Webhook events are emitted when specific order or return states are reached. Each event is delivered via HTTP and must be acknowledged immediately.


Delivery Flow

  1. An order or return transitions to a new state
  2. A webhook event is generated
  3. The event is sent via HTTP POST
  4. The merchant system:
  • Returns HTTP 200
  • Processes the event asynchronously
  1. Failed deliveries are retried

Subscription

Merchants can:

  1. Register a webhook URL
  2. Configure a shared secret
  3. Enable / disable delivery at any time

Webhook delivery starts only after successful registration.


URL Validation (Registration Check)

During registration, the platform performs a one-time endpoint validation to ensure the provided URL is usable.

What we validate

  • The endpoint is reachable
  • It responds with HTTP 200

Validation request

  • Method: POST
  • Content-Type: application/json
  • Expected response: HTTP 200

Headers

  • If authentication is configured, an Authorization header is included.
  • The request includes a fixed User-Agent value:
User-Agent: Shopflix WebHook Test

Webhook Events

Order Events

Event TypeDescription
order.createdEmitted when an order enters the initial lifecycle states
order.deliveredEmitted when the order is successfully delivered
order.canceledEmitted when the order is canceled or rejected
order.deliveryFailedEmitted when delivery to the customer fails

Return Events

Event TypeDescription
return.createdEmitted when a return request is created
return.deliveringToStoreEmitted while the return is being shipped back
return.canceledEmitted when a return is canceled
return.waitingForSupportEmitted when manual review is required
return.completedEmitted when the return process is finalized

Return events use the same payload structure as order events. The event is identified by order_data.eventType; there is no separate return_data root.


Webhook Request

Request Metadata

FieldValue
MethodPOST
Content-Typeapplication/json
Body formatJSON

Payload Example

{
  "order_data": {
    "id": "GR--4004973--MER75",
    "eventType": "order.delivered",
    "countryCode": "GR",
    "hasInvoice": false,
    "subTotalItemsAmount": 10,
    "totalItemsAmount": 15,
    "createdAt": "2025-12-18 07:37:03.000000",
    "updatedAt": null,
    "expiresAt": null,
    "dispatchUntil": null,
    "customer": {
      "userId": 91755,
      "email": "customer42@example.com",
      "phone": "+35799123456",
      "firstName": "Spencor",
      "lastName": "Hopkin"
    },
    "addressDetails": {
      "street": "Test",
      "streetNumber": "53",
      "postCode": "14451",
      "city": "ΜΕΤΑΜΟΡΦΩΣΗ",
      "region": "ΑΤΤΙΚΉ",
      "regionCode": "ΑΤΤ",
      "country": "Greece",
      "countryCode": "GR"
    },
    "invoiceDetails": null,
    "carrier": {
      "shipmentId": 4047769,
      "name": "Courier Center",
      "deliveryName": "Courier Center Standard",
      "deliveryKey": "courier_center_standard",
      "trackingCodes": "013791689230",
      "comments": null,
      "deliveryToCourierEstimationDate": "18/12/2025",
      "deliveryToCustomerEstimationDate": "22/12/2025"
    },
    "payment": {
      "name": "cod"
    },
    "lineItems": [
      {
        "id": 42140,
        "sku": "SF-100005366",
        "merchantEan": "sf-foo-bar-5",
        "merchantSku": "MERSKU-SF-09175005-MER75-S",
        "productName": "Κρεμαστό Φωτιστικό GloboStar 02084 Μονόφωτο Πλέγμα για Ντουί E27 Μπεζ",
        "unitPrice": 10,
        "originalUnitPrice": 10,
        "totalPrice": 10,
        "quantity": 1,
        "sfArticle39Valid": false,
        "giftWrap": false,
        "extendedAttributes": {
          "originalValue": ""
        }
      }
    ]
  },
  "timestamp_webhook_creation": "2025-12-18 08:08:37",
  "timestamp_webhook_submission": "2025-12-18 08:08:41",
  "merchant_webhook_data": {
    "merchant_url": "https://merchant.example.com/webhooks/shopflix",
    "merchant_token": "merchant-token-placeholder"
  }
}

Payload Reference

Webhook payloads are sent with snake_case top-level keys. The order model inside order_data uses camelCase keys.

Top-level Fields

FieldTypeRequiredDescription
order_dataobjectOrder payload. See Order Data.
timestamp_webhook_creationstringTimestamp when the webhook queue message was created, formatted as YYYY-MM-DD HH:mm:ss.
timestamp_webhook_submissionstringTimestamp when the webhook delivery attempt was submitted, formatted as YYYY-MM-DD HH:mm:ss.
merchant_webhook_dataobjectMerchant webhook routing metadata. See Merchant Webhook Data.

Order Data

FieldTypeRequiredDescription
idstringMerchant order reference, e.g. GR--4004973--MER75.
eventTypestringWebhook event name, e.g. order.created, order.delivered, order.canceled, order.deliveryFailed, return.created, return.deliveringToStore, return.canceled, return.waitingForSupport, return.completed.
countryCodestringCountry ISO-2 code.
hasInvoicebooleanWhether checkout invoice details exist for the order.
subTotalItemsAmountnumberOrder subtotal in minor currency units.
totalItemsAmountnumberOrder total in minor currency units.
createdAtstringMerchant order creation timestamp.
updatedAtstring | null⚠️Merchant order update timestamp, if available.
expiresAtstring | null⚠️Order expiration timestamp, if available.
dispatchUntilstring | null⚠️Latest dispatch timestamp/date, if available.
customerobjectCustomer information.
addressDetailsobjectShipping address information.
invoiceDetailsobject | null⚠️Checkout invoice details. null when hasInvoice is false.
carrierobjectShipment and carrier information.
paymentobjectPayment information.
lineItemsarrayMerchant order line items.

Customer

FieldTypeRequiredDescription
userIdintNumeric customer identifier. Guest orders can return 0.
emailstringCustomer email.
phonestring | null⚠️Customer phone.
firstNamestringCustomer first name.
lastNamestringCustomer last name.

Address Details

FieldTypeRequiredDescription
streetstringStreet name/address line 1.
streetNumberstringStreet number/address line 2.
postCodestringPostal code.
citystringCity.
regionstring | null⚠️Region/state name.
regionCodestring | null⚠️Region/state code.
countrystring | null⚠️Country name.
countryCodestringCountry ISO-2 code.

Invoice Details

invoiceDetails contains checkout invoice-request details. It is null when the customer did not request an invoice.

invoiceDetails example
{
  "doy": "1201",
  "doyName": "Athens A DOY",
  "vatNumber": "EL123456789",
  "company": "Example Company SA",
  "occupation": "Retail",
  "address": "Aiolou 12",
  "postCode": "10552",
  "city": "Athens",
  "article39": null,
  "article39Eligible": "1",
  "article39IdentityType": "ΔΙ ΔΙΑΒΑΤΗΡΙΟ",
  "article39IdentityNo": "AB1234567",
  "article39MobilePhone": "+306971234567",
  "article39Otp": "842315",
  "article39Valid": null
}
FieldTypeRequiredDescription
doystring | null⚠️Tax office code.
doyNamestring | null⚠️Tax office name.
vatNumberstringCustomer VAT number.
companystring | null⚠️Company name.
occupationstring | null⚠️Business occupation/activity.
addressstring | null⚠️Invoice address.
postCodestring | null⚠️Invoice postal code.
citystring | null⚠️Invoice city.
article39string | null⚠️Article 39 flag/value when present.
article39Eligiblestring | boolean | null⚠️Whether Article 39 is eligible.
article39IdentityTypestring | null⚠️Article 39 identity document type label. See Article 39 Identity Type Values.
article39IdentityNostring | null⚠️Article 39 identity document number.
article39MobilePhonestring | null⚠️Mobile phone used for Article 39 verification.
article39Otpstring | null⚠️Article 39 OTP value.
article39Validstring | boolean | null⚠️Article 39 validation status when available.

Carrier

FieldTypeRequiredDescription
shipmentIdint | null⚠️Sales shipment identifier.
namestring | null⚠️Carrier name.
deliveryNamestring | null⚠️Delivery method name. See Carrier Delivery Method Values.
deliveryKeystring | null⚠️Delivery method key. See Carrier Delivery Method Values.
trackingCodesstring | null⚠️Shipment tracking code.
commentsstring | null⚠️Free-text shipment comments.
deliveryToCourierEstimationDatestring | null⚠️Estimated handover date to courier.
deliveryToCustomerEstimationDatestring | null⚠️Estimated delivery date to customer.

Payment

payment.name contains the payment method key stored on the order.

FieldTypeRequiredDescription
namestring | null⚠️Payment method key.

Line Items

FieldTypeRequiredDescription
idintSales order item identifier.
skustringProduct SKU.
merchantEanstring | null⚠️Merchant EAN from product offer.
merchantSkustring | null⚠️Merchant SKU from product offer.
productNamestringProduct name.
unitPricenumberUnit price paid, in minor currency units.
originalUnitPricenumberOriginal unit price, in minor currency units.
totalPricenumberTotal line price, in minor currency units.
quantityintQuantity.
sfArticle39Validboolean⚠️Whether Article 39 was applied/valid for the item.
giftWrapboolean⚠️Gift-wrap flag. Currently returned as false.
extendedAttributesobject⚠️Additional item metadata. See Extended Attributes. Empty metadata is sent as {}.

Extended Attributes

extendedAttributes example
{
  "originalValue": "Black / XL"
}
FieldTypeRequiredDescription
originalValuestring | null⚠️Original selected product-offer value from offer metadata, when available.

Merchant Webhook Data

merchant_webhook_data contains routing metadata used for webhook delivery. Treat merchant_token as sensitive and do not log it in plaintext.

merchant_webhook_data example
{
  "merchant_url": "https://merchant.example.com/webhooks/shopflix",
  "merchant_token": "merchant-token-placeholder"
}
FieldTypeRequiredDescription
merchant_urlstring | null⚠️Merchant webhook endpoint URL.
merchant_tokenstring | null⚠️Merchant token configured for webhook delivery. Treat this value as sensitive.

Processing Guidelines

  • Return HTTP 200 immediately
  • Process events asynchronously
  • Handle duplicate deliveries safely

Failure Handling & Retries

What is considered a failure?

A delivery attempt fails if:

  • The request times out
  • The endpoint returns anything other than HTTP 200

Automatic retries

  • Failed deliveries are retried automatically through the webhook retry queue
  • A delivery can be retried up to 12 times
  • The same queued payload is sent on each automatic retry attempt

Manual Resend from Merchant Portal

Manual webhook resend is supported from the Merchant Portal for merchant orders that have a webhook subscription configured.

Manual resend creates a new asynchronous delivery attempt for the selected merchant order. It can be triggered from the Merchant Portal, and the success message means that the webhook delivery was queued. It does not mean that the merchant endpoint has already received or acknowledged the webhook with HTTP 200.

Use manual resend when:

  • The merchant endpoint was temporarily unavailable
  • A previous delivery timed out or returned a non-200 response
  • The merchant has fixed their webhook endpoint and needs the order state sent again
  • The merchant needs to reconcile the current order or return state in their system

How to resend

  1. Open the Merchant Portal
  2. Go to the order details page
  3. Open the Details tab
  4. Click Trigger Webhook Order
  5. Confirm the action

What gets sent

Manual resend uses the same webhook delivery channel as automatic webhooks:

  • The delivery is queued asynchronously
  • The request sent to the merchant endpoint is an HTTP POST
  • The payload uses the same structure described in Webhook Request
  • The merchant endpoint must return HTTP 200 to acknowledge the delivery
  • Any timeout or non-200 response is treated as a failed delivery

Manual resend is based on the current item states of the merchant order at the time the action is triggered. The platform maps those states to webhook eventType values using the same rules as automatic webhook dispatch.

See the full state mapping: Webhook Events by State

Supported manual resend event types:

Event TypeSupported by manual resend
order.created
order.delivered
order.canceled
order.deliveryFailed
return.created
return.deliveringToStore
return.canceled
return.waitingForSupport
return.completed

If a merchant order contains items in multiple supported states, more than one webhook may be queued. States that do not map to a webhook event do not produce a manual resend delivery.


Idempotency

Because retries and manual resends are possible:

  • The same event may be delivered more than once
  • Merchants must treat webhook delivery as at‑least‑once

Recommended strategies:

  • Store a unique event key, for example order_data.eventType + order_data.id + timestamp_webhook_creation
  • Ignore already‑processed events
  • Never rely on delivery count

Security

Registration vs Event Delivery

Registration validation (one-time)

  • Uses a fixed User-Agent: Shopflix WebHook Test
  • Expects HTTP 200

Event delivery

  • Sends a JSON request body using Content-Type: application/json
  • Does not add an extra authentication header by default
  • If a merchant token is configured, it is included in merchant_webhook_data.merchant_token

Monitoring

  • Signature validation failures
  • 5xx responses
  • Delayed processing
  • Duplicate event deliveries