Skip to content

Delivery Settings ​

Overview ​

Delivery Settings control whether a location accepts delivery orders and how delivery is priced and bounded. They are not a standalone page: they are the Delivery Settings section inside the Online Ordering configuration screen, stored as part of the location's online ordering settings object.

Key Purpose: Configure the delivery region, delivery fee, and delivery minimum order amount for a location.

Purpose ​

This section lets you configure the delivery-related parts of online ordering for a location:

  • The delivery region — an ordered list of named delivery areas that defines where you deliver and what it costs there.
  • The delivery fee model (free, flat charge, or free over a threshold), plus optional distance-based pricing.
  • The delivery minimum order amount required before a delivery order can be placed.

Whether delivery is enabled at all (the delivery.enabled toggle), delivery preparation delay (delivery.delay), delivery cutoffs (delivery.same_day_cutoff / delivery.next_day_cutoff), and future-day scheduling (schedule_order_for_future_days.delivery) live in the broader Online Ordering settings — see Online Ordering.

Key Concepts ​

  • Delivery Region (delivery_region.zones): An ordered list of delivery areas. Each area covers a radius, a driving distance, a set of postcodes or a list of streets, and may carry its own fee or be marked as somewhere you do not deliver. Areas are checked top to bottom and the first one that matches an address decides both coverage and price. See Delivery Region.
  • Delivery Fee Type (delivery_fee.type): One of three models — Free delivery, Charge delivery fee for all orders, or Free delivery for orders over a certain amount.
  • Per-area fee (delivery_region.zones[].fee): The fee charged when that area is the one that matched. Left blank, the area falls back to the fee rules below. This replaces the old per-postal-code custom-fee list.
  • On the POS bill: the delivery fee is itemised automatically on Square and Shopcaisse, and is opt-in on MplusKassa, Hendrickx/Vanhoutte and Lightspeed K-Series — see Integrations → Fees and Tips on the POS Bill.
  • Distance-Based Pricing (delivery_fee.distance_pricing_enabled): Optional pricing by driving distance, available whenever the fee type is not Free delivery. It applies to whichever area the order matched when that area leaves its own fee blank. Can be tiered (per-distance-band fees) or flat_rate (price per km).
  • Delivery Minimum Order Amount (minimum_order_amount): A minimum order value required before a delivery order is eligible.

Actions ​

Set the Delivery Region ​

Build the list of delivery areas. Next to "Add area", pick a shape — Radius, Driving distance, Postcodes or Streets — then name the area, fill in what it covers, and optionally give it its own delivery fee. Drag areas into the order you want them checked; the first area that matches an address decides. Mark an area "Do not deliver here" to carve it out, and put it above whatever would otherwise have covered it. Up to 10 areas, at least one of which must be an area you do deliver to. See Delivery Region.

Set the Delivery Fee ​

Pick the delivery fee type. If it is not Free delivery, enter the base fee (delivery_fee.fee). For Free delivery for orders over a certain amount, also enter the order amount that qualifies for free delivery (delivery_fee.minimum_order_amount_for_free_delivery). To charge different prices in different places, put the fee on the delivery area itself; to price by how far the driver goes, switch on distance-based pricing.

Set the Delivery Minimum Order Amount ​

Toggle minimum_order_amount.enabled on and enter the required amount (minimum_order_amount.amount).

Location ​

  • Backoffice Route: /online/online-ordering (nav: Online → Online Ordering, section Delivery Settings, id="DeliverySettings")
  • Backend Controller: app/Http/Controllers/Api/BackOffice/OnlineOrderingController.php (show / update)
  • Save Endpoint: PUT /back-office/online-ordering/{locationId} — the route group sits inside the /back-office prefix, and is gated by the edit-online-ordering permission (the matching read is GET /back-office/online-ordering/{locationId} with view-online-ordering). Validated by app/Http/Requests/BackOffice/OnlineOrdering/StoreOnlineOrderingRequest.php
  • Vue Component: src/views/online/online-ordering/forms/DeliverySettings.vue (mounted inside src/views/online/online-ordering/OnlineOrdering.vue)

Fields ​

Delivery Areas ​

PropertyValue
Field IDdelivery_region.zones
LabelDelivery Region
TypeOrdered list of delivery areas
Default[] (empty)
Validationnullable array, maximum 10 entries; at least one entry must not be a refusal

Description: The ordered list that defines delivery coverage and per-area pricing. Each entry carries a name, one shape (radius / distance / postcode / street), an optional fee, and a "do not deliver here" flag. The first area that matches an address decides. Full field reference: Delivery Region.

A location whose list is still empty falls back to its previous single-mode setup (delivery_region.type plus radius / max_distance / postal_codes / streets), read as an equivalent ordered list. Those legacy fields are documented on Delivery Region.


Delivery Fee Type ​

PropertyValue
Field IDdelivery_fee.type
LabelDelivery Fee
TypeChoice (DeliveryFeeTypes)
DefaultFree delivery
Validationrequired, must be a valid DeliveryFeeTypes value

Description: The delivery fee model. Valid values (from the DeliveryFeeTypes enum):

  • Free delivery
  • Charge delivery fee for all orders
  • Free delivery for orders over a certain amount

Delivery Fee ​

PropertyValue
Field IDdelivery_fee.fee
LabelDelivery fee for all other orders
TypeCurrency (€)
Default0
Validationrequired and numeric when fee type is not Free delivery

Description: The base delivery fee charged. Not required when the fee type is Free delivery.


Minimum Order Amount for Free Delivery ​

PropertyValue
Field IDdelivery_fee.minimum_order_amount_for_free_delivery
LabelThe total order amount needs to be over … to qualify for free delivery
TypeCurrency (€)
Default0
Validationrequired and numeric only when fee type is Free delivery for orders over a certain amount

Description: The order amount at or above which delivery becomes free. Below it, delivery_fee.fee is charged.


Per-Area Fee ​

PropertyValue
Field IDdelivery_region.zones[].fee
LabelDelivery fee (on the expanded delivery area)
TypeCurrency (€), or blank
Defaultblank — "Use the default fee"
Validationnullable, numeric, ≥ 0; rejected outright on an area marked "do not deliver here"

Description: Charging different prices in different places is done here, on the delivery area itself, rather than through a separate override list. The fee comes from the same area that decided coverage, so the two can never disagree. The field is hidden when the fee type is Free delivery.

Blank is not zero. Blank means "fall back to distance pricing or the base fee"; 0 means delivery is genuinely free in that area.

The separate "Custom Fees by Postal Code" list is gone. Per-postal-code and per-street overrides (delivery_fee.custom_fees) were folded into the delivery areas: each override became an area carrying that price. Once a location has delivery areas, the old list is no longer read when an order is priced, and sending it back is rejected on save. Locations that have not been set up as areas yet keep their old overrides working, read as equivalent areas.


Distance Pricing Enabled ​

PropertyValue
Field IDdelivery_fee.distance_pricing_enabled
LabelRoute Distance-Based Pricing
TypeToggle
Defaultfalse
Validationnullable boolean

Description: Enables fee calculation based on driving distance. Shown whenever the fee type is not Free delivery — it is no longer tied to a region type. It applies to whichever delivery area the order matched, when that area leaves its own fee blank.


Distance Pricing Type ​

PropertyValue
Field IDdelivery_fee.distance_pricing_type
LabelTiered / Flat Rate
TypeChoice (tiered / flat_rate)
Defaulttiered
Validationnullable string, must be tiered or flat_rate

Description: How distance-based pricing is computed when distance_pricing_enabled is true.


Distance Fees (Tiered) ​

PropertyValue
Field IDdelivery_fee.distance_fees
LabelRules
TypeArray of { max_km, fee }
Default[] (empty)
Validationnullable array (when distance pricing is tiered); each tier requires max_km (numeric, > 0) and fee (numeric, min: 0)

Description: Per-distance-band fees, e.g. "for routes up to X km, charge €Y". Tiers must increase in distance. If no rule matches, the default delivery_fee.fee is used.


Flat Rate per km ​

PropertyValue
Field IDdelivery_fee.flat_rate_per_km
LabelPrice per km
TypeCurrency (€ / km)
Default0
Validationrequired, numeric, min: 0 when distance pricing type is flat_rate

Description: Price per km of driving route distance. The fee is the rate multiplied by the route distance rounded up to the nearest km (e.g. €1.50/km over 3.2 km = 4 × €1.50 = €6.00).


Delivery Minimum Order Amount Enabled ​

PropertyValue
Field IDminimum_order_amount.enabled
LabelDelivery minimum order amount
TypeToggle
Defaultfalse
Validationrequired boolean

Description: When on, a minimum order value is required before a delivery order is eligible.


Delivery Minimum Order Amount ​

PropertyValue
Field IDminimum_order_amount.amount
LabelMinimum order amount
TypeCurrency (€)
Default10
Validationrequired and numeric when minimum_order_amount.enabled is true

Description: The minimum order value required for delivery when the toggle is enabled.


Business Rules ​

  • The delivery fee type comes from the DeliveryFeeTypes enum and is exactly one of: Free delivery, Charge delivery fee for all orders, or Free delivery for orders over a certain amount.
  • When the fee type is Free delivery, no fee fields are required; the base fee, the per-area fee and distance-based pricing are all hidden/skipped.
  • delivery_fee.minimum_order_amount_for_free_delivery is required only when the fee type is Free delivery for orders over a certain amount. Above that threshold the order qualifies for free delivery; below it the base delivery_fee.fee applies.
  • The delivery fee is resolved in one order: the matched delivery area's own fee (including 0) → distance-based pricing, if enabled → the base delivery_fee.fee. Free delivery and free-over-a-threshold are settled against the order total before any of that.
  • Per-area fees replace the old delivery_fee.custom_fees list. Once a location has delivery areas, custom_fees is not read when an order is priced and is rejected on save.
  • Distance-based pricing (delivery_fee.distance_pricing_enabled) is available whenever the fee type is not Free delivery; it is no longer gated on a region type. It is either tiered (per-band fees in distance_fees) or flat_rate (price per km in flat_rate_per_km). Beyond the widest tier no rate is configured, so the base delivery_fee.fee applies rather than nothing.
  • Tiered distance rules must be in increasing distance order: each tier's max_km must be greater than the previous tier's max_km, and fees cannot be negative.
  • The delivery region is an ordered list of up to 10 delivery areas, at least one of which must be an area you deliver to. Each area needs a name and a value for its shape. See Delivery Region.
  • The delivery minimum order amount (minimum_order_amount.amount) is only required when minimum_order_amount.enabled is true.
  • This minimum_order_amount is the delivery minimum and is separate from the pickup minimum (pickup_minimum_order_amount); see Online Ordering.

FAQs ​

  • What delivery fee options are there? Three: free delivery, a flat charge on all orders, or free delivery only when the order is over a set amount (otherwise the base fee applies).
  • How do I decide where I deliver? Build a list of delivery areas under Delivery Region. Each area is a radius, a driving distance, a set of postcodes or a list of streets, and the first one that matches an address decides. See Delivery Region.
  • Can I charge different fees in different areas? Yes. Put the fee on the delivery area itself — that is what per-area fees are for. Leave an area's fee blank for it to use your default fee. You can also price by driving distance instead, with tiered bands or a flat price per km.
  • Where did "Custom Fees by Postal Code" go? Those overrides now live on the delivery areas. A postcode you used to price separately is simply an area with that postcode and that fee. Nothing was lost — existing overrides keep applying until the location is set up as areas.
  • How does the free-delivery-over-amount option work? You set a qualifying order amount. Orders at or above it ship free; orders below it are charged the base delivery fee.
  • How is the per-km flat rate calculated? The route distance is rounded up to the nearest km and multiplied by the per-km rate (e.g. €1.50/km over 3.2 km = 4 × €1.50 = €6.00).
  • Is the delivery minimum separate from the pickup minimum? Yes. The delivery minimum is minimum_order_amount; pickup has its own pickup_minimum_order_amount.
  • Where do I turn delivery on or set delivery prep time and cutoffs? Those are in the broader Online Ordering settings (delivery.enabled, delivery.delay, delivery.same_day_cutoff / next_day_cutoff), not in this section — see Online Ordering.

Relations ​

Depends On ​

  • Locations: Delivery settings are stored on the location's online ordering settings object.
  • Online Ordering: Delivery enable/disable, prep delay, cutoffs, and future-day scheduling live there.

Affects ​

  • Online Ordering storefront: Region, fee, and minimum determine delivery availability and pricing at checkout (storefront behavior not verified here).

Examples ​

The delivery settings are stored as part of the online ordering settings object. The shapes below match StoreOnlineOrderingRequest validation and the Constants::$DEFAULT_ONLINE_ORDERING_SETTING defaults.

Free delivery, one radius area ​

json
{
  "delivery_region": {
    "zones": [
      { "id": "a1", "name": "Delivery area", "shape": "radius", "radius": 10, "exclude": false, "fee": null }
    ]
  },
  "delivery_fee": {
    "type": "Free delivery",
    "minimum_order_amount_for_free_delivery": 0,
    "fee": 0,
    "distance_pricing_enabled": false,
    "distance_pricing_type": "tiered",
    "distance_fees": [],
    "flat_rate_per_km": 0
  },
  "minimum_order_amount": {
    "enabled": false,
    "amount": 10
  }
}

Flat Charge on All Orders + Delivery Minimum ​

json
{
  "delivery_region": {
    "zones": [
      { "id": "a1", "name": "Delivery area", "shape": "radius", "radius": 8, "exclude": false, "fee": null }
    ]
  },
  "delivery_fee": {
    "type": "Charge delivery fee for all orders",
    "fee": 3.5
  },
  "minimum_order_amount": {
    "enabled": true,
    "amount": 15
  }
}

Free Delivery Over a Threshold ​

json
{
  "delivery_fee": {
    "type": "Free delivery for orders over a certain amount",
    "minimum_order_amount_for_free_delivery": 25,
    "fee": 3.5
  }
}

Two postcodes priced differently ​

Each priced postcode is its own delivery area. Anything not covered by an area is not delivered to at all.

json
{
  "delivery_region": {
    "zones": [
      { "id": "a1", "name": "1012", "shape": "postcode", "postal_codes": ["1012"], "exclude": false, "fee": 3 },
      { "id": "a2", "name": "1013", "shape": "postcode", "postal_codes": ["1013"], "exclude": false, "fee": 6 }
    ]
  },
  "delivery_fee": {
    "type": "Charge delivery fee for all orders",
    "fee": 4.5
  }
}

Driving-distance area with tiered distance pricing ​

The area leaves its fee blank, so the tiers price the order.

json
{
  "delivery_region": {
    "zones": [
      { "id": "a1", "name": "Delivery area", "shape": "distance", "max_distance": 12, "exclude": false, "fee": null }
    ]
  },
  "delivery_fee": {
    "type": "Charge delivery fee for all orders",
    "fee": 5,
    "distance_pricing_enabled": true,
    "distance_pricing_type": "tiered",
    "distance_fees": [
      { "max_km": 5, "fee": 3 },
      { "max_km": 10, "fee": 5 }
    ]
  }
}

Driving-distance area with a flat rate per km ​

json
{
  "delivery_region": {
    "zones": [
      { "id": "a1", "name": "Delivery area", "shape": "distance", "max_distance": 12, "exclude": false, "fee": null }
    ]
  },
  "delivery_fee": {
    "type": "Charge delivery fee for all orders",
    "fee": 5,
    "distance_pricing_enabled": true,
    "distance_pricing_type": "flat_rate",
    "flat_rate_per_km": 1.5
  }
}