Skip to content

Webhooks

StoreFront sends real-time webhook notifications to your system when transactions occur. This enables you to:

  • Track purchases in real-time
  • Fulfil cashback or points rewards immediately
  • Update your internal reporting systems

Standard Webhooks

StoreFront webhooks are compliant with the Standard Webhooks specification. This means you can use any Standard Webhooks compatible library to verify and process webhooks.

For details on signature verification, security best practices, and operational considerations, refer to the Standard Webhooks specification.

Headers

Every webhook includes the following Standard Webhooks headers:

HeaderDescription
webhook-idUnique identifier for this webhook (use as idempotency key)
webhook-timestampUnix timestamp of when the webhook was sent
webhook-signatureHMAC-SHA256 signature for verification

Endpoint Requirements

Your webhook endpoint must:

  • Accept POST requests
  • Use HTTPS with a valid SSL certificate
  • Return a 2xx status code to acknowledge receipt
  • Respond within 30 seconds

Async Processing

Process webhooks asynchronously and return 202 Accepted immediately. This prevents timeout issues if your processing takes time.

Retries

If delivery fails, StoreFront retries with exponential backoff:

AttemptDelayCumulative Time
1Immediate0
25 seconds5 seconds
35 minutes~5 minutes
430 minutes~35 minutes
52 hours~2.5 hours
65 hours~7.5 hours
710 hours~17.5 hours
814 hours~31.5 hours
920 hours~51.5 hours

Event Types

StoreFront sends webhooks for two transaction events:

EventDescription
SaleA purchase has been completed and fulfilled
CancelA previously completed transaction has been cancelled

The specific event type depends on your pricing model:

Pricing ModelSale EventCancel Event
Face Valuesale.face_valuecancel.face_value
Discountsale.discountcancel.discount
Cashbacksale.cashbackcancel.cashback

StoreFront-Specific Behaviour

Per-Item Webhooks

StoreFront supports multi-item baskets, but webhooks are sent per item, not per order.

Gift cards are fulfilled individually through Tillo's API, where each brand may be processed by a different upstream supplier. In the event of an upstream issue - such as temporary supplier unavailability or stock constraints - individual items within an order may be affected independently.

As a result:

  • Each successfully fulfilled item triggers its own webhook
  • Each webhook contains an order_id to group items from the same order
  • Each item has a unique transaction_id
  • If an item experiences a fulfilment delay, its webhook will be sent once the issue is resolved

Immutable Transactions

Transactions are immutable - there is no "status change" concept:

  • A sale webhook indicates a successful purchase
  • A cancel webhook is a separate event for reversals
  • Match cancellations to sales using transaction_id

Payload Reference

The payload structure varies by pricing model. All payloads follow the Standard Webhooks format with type, timestamp, and data fields.

Discount Model

Sale Webhook

json
{
  "type": "sale.discount",
  "timestamp": "2025-02-26T13:08:09Z",
  "data": {
    "product": {
      "code": "xbox-usa",
      "name": "Xbox"
    },
    "order_id": "2515839709",
    "member_id": "8788698",
    "transaction_id": "2515839709-365402",
    "created_date": "2025-02-26T13:08:01Z",
    "purchase_amount": "100.00",
    "buyer_discount": {
      "amount": "8.70",
      "percentage": "8.70"
    },
    "member_discount": {
      "amount": "6.50",
      "percentage": "6.50"
    },
    "incentive": {
      "percentage": "1.50",
      "amount": "1.50"
    }
  }
}
{
  "type": "sale.discount",
  "timestamp": "2025-02-26T13:08:09Z",
  "data": {
    "product": {
      "code": "xbox-usa",
      "name": "Xbox"
    },
    "order_id": "2515839709",
    "member_id": "8788698",
    "transaction_id": "2515839709-365402",
    "created_date": "2025-02-26T13:08:01Z",
    "purchase_amount": "100.00",
    "buyer_discount": {
      "amount": "8.70",
      "percentage": "8.70"
    },
    "member_discount": {
      "amount": "6.50",
      "percentage": "6.50"
    },
    "incentive": {
      "percentage": "1.50",
      "amount": "1.50"
    }
  }
}

Cancel Webhook

json
{
  "type": "cancel.discount",
  "timestamp": "2025-01-01T15:48:01Z",
  "data": {
    "order_id": "2515839709",
    "member_id": "8788698",
    "transaction_id": "2515839709-365402",
    "created_date": "2025-01-01T15:48:01Z"
  }
}
{
  "type": "cancel.discount",
  "timestamp": "2025-01-01T15:48:01Z",
  "data": {
    "order_id": "2515839709",
    "member_id": "8788698",
    "transaction_id": "2515839709-365402",
    "created_date": "2025-01-01T15:48:01Z"
  }
}

Cashback Model

Sale Webhook

json
{
  "type": "sale.cashback",
  "timestamp": "2025-02-26T13:08:09Z",
  "data": {
    "product": {
      "code": "xbox-usa",
      "name": "Xbox"
    },
    "order_id": "2515839709",
    "member_id": "8788698",
    "transaction_id": "2515839709-365402",
    "created_date": "2025-02-26T13:08:01Z",
    "purchase_amount": "100.00",
    "buyer_discount": {
      "amount": "8.70",
      "percentage": "8.70"
    },
    "member_cashback": {
      "amount": "6.50",
      "percentage": "6.50"
    },
    "incentive": {
      "percentage": "1.50",
      "amount": "1.50"
    }
  }
}
{
  "type": "sale.cashback",
  "timestamp": "2025-02-26T13:08:09Z",
  "data": {
    "product": {
      "code": "xbox-usa",
      "name": "Xbox"
    },
    "order_id": "2515839709",
    "member_id": "8788698",
    "transaction_id": "2515839709-365402",
    "created_date": "2025-02-26T13:08:01Z",
    "purchase_amount": "100.00",
    "buyer_discount": {
      "amount": "8.70",
      "percentage": "8.70"
    },
    "member_cashback": {
      "amount": "6.50",
      "percentage": "6.50"
    },
    "incentive": {
      "percentage": "1.50",
      "amount": "1.50"
    }
  }
}

Cancel Webhook

json
{
  "type": "cancel.cashback",
  "timestamp": "2025-01-01T15:48:01Z",
  "data": {
    "order_id": "f9s8e7f9f7",
    "member_id": "7fhw8ekd-73js-0sl1-m18s-8ejamaleruto",
    "transaction_id": "f9s8e7f9f7",
    "created_date": "2025-01-01T15:48:01Z"
  }
}
{
  "type": "cancel.cashback",
  "timestamp": "2025-01-01T15:48:01Z",
  "data": {
    "order_id": "f9s8e7f9f7",
    "member_id": "7fhw8ekd-73js-0sl1-m18s-8ejamaleruto",
    "transaction_id": "f9s8e7f9f7",
    "created_date": "2025-01-01T15:48:01Z"
  }
}

Face Value Model

Sale Webhook

json
{
  "type": "sale.face_value",
  "timestamp": "2025-02-26T13:08:09Z",
  "data": {
    "product": {
      "code": "xbox-usa",
      "name": "Xbox"
    },
    "order_id": "1536485736",
    "member_id": "0293751",
    "transaction_id": "1536485736-365400",
    "created_date": "2025-02-26T13:08:01Z",
    "purchase_amount": "100.00",
    "buyer_discount": {
      "amount": "8.70",
      "percentage": "8.70"
    }
  }
}
{
  "type": "sale.face_value",
  "timestamp": "2025-02-26T13:08:09Z",
  "data": {
    "product": {
      "code": "xbox-usa",
      "name": "Xbox"
    },
    "order_id": "1536485736",
    "member_id": "0293751",
    "transaction_id": "1536485736-365400",
    "created_date": "2025-02-26T13:08:01Z",
    "purchase_amount": "100.00",
    "buyer_discount": {
      "amount": "8.70",
      "percentage": "8.70"
    }
  }
}

Cancel Webhook

json
{
  "type": "cancel.face_value",
  "timestamp": "2025-03-13T09:32:55Z",
  "data": {
    "order_id": "1536485736",
    "member_id": "0293751",
    "transaction_id": "1536485736-365400",
    "created_date": "2025-02-26T13:08:01Z"
  }
}
{
  "type": "cancel.face_value",
  "timestamp": "2025-03-13T09:32:55Z",
  "data": {
    "order_id": "1536485736",
    "member_id": "0293751",
    "transaction_id": "1536485736-365400",
    "created_date": "2025-02-26T13:08:01Z"
  }
}

Field Reference

Sale Payload Fields

FieldTypeDescription
typestringEvent type (e.g., sale.discount, sale.cashback, sale.face_value)
timestampstringWhen the webhook was sent (ISO 8601 UTC)
data.product.codestringTillo product code
data.product.namestringProduct display name
data.order_idstringOrder identifier (groups items in multi-item orders)
data.member_idstringYour user identifier from authentication (if provided)
data.transaction_idstringUnique transaction identifier for this item
data.created_datestringWhen the transaction occurred (ISO 8601 UTC)
data.purchase_amountstringFace value of the gift card (decimal string)
data.buyer_discount.amountstringYour discount from Tillo (decimal string)
data.buyer_discount.percentagestringYour discount percentage
data.member_discount.*stringDiscount applied to user (Discount model only). Inclusive of incentive values when configured and the incentivised payment gateway is selected
data.member_cashback.*stringCashback to award user (Cashback model only). Inclusive of incentive values when configured and the incentivised payment gateway is selected
data.incentive.amountstringIncremental incentive amount included in member_*.amount (e.g. member_discount.amount). Base amount can be derived as member_*.amount - incentive.amount
data.incentive.percentagestringIncremental incentive percentage included in member_*.percentage (e.g. member_discount.amount). Base percentage can be derived as member_*.percentage - incentive.percentage

Cancel Payload Fields

FieldTypeDescription
typestringEvent type (e.g., cancel.discount, cancel.cashback, cancel.face_value)
timestampstringWhen the webhook was sent (ISO 8601 UTC)
data.order_idstringOrder identifier
data.member_idstringYour user identifier from authentication (if provided)
data.transaction_idstringTransaction identifier (use to match to original sale)
data.created_datestringWhen the original transaction occurred (ISO 8601 UTC)

Handling Cancellations

When you receive a cancel webhook:

  1. Look up the original sale using transaction_id
  2. Reverse any actions taken:
    • Cashback: Deduct the awarded amount from the user's balance
    • Points: Reverse the points credited
    • Reporting: Update your records
  3. Return a 2xx response