Skip to content

Order Notes ​

Overview ​

Order notes let customers attach free-text instructions to an order. There are two distinct kinds of note in the backend: per-item notes (one note per line item) and a single order-level note (one overall instruction for the whole order). Each kind has its own per-channel toggle — allow_notes for per-item notes and allow_order_notes for the order-level note — so a merchant can enable one without the other.

Key Purpose: Capture customer special requests and instructions, both per item and for the order as a whole, each independently switchable.

Purpose ​

When notes are enabled for a channel, customers can add a note to individual items and/or a single overall note to the order. The merchant enables each kind independently and configures its input placeholder text in the back office, per channel (In-House for kiosk, Online Settings for online ordering).

Key Concepts ​

  • Per-Item Notes: Stored on the TransactionItem model as a notes string (TransactionItem::getNotes()). Accepted on the create-intent request as items.*.notes (validated nullable|string).
  • Order-Level Note: A single optional note for the whole order, stored on the Transaction model as note (Transaction::getNote()). Accepted on the create-intent request as order_note (validated nullable|string|max:255). This is distinct from the per-item notes and is entered once at checkout.
  • Per-Channel Toggles (two, independent): allow_notes ({enabled, placeholder}) gates per-item notes; allow_order_notes ({enabled, placeholder}) gates the order-level note. Both are stored independently per channel: in the in-house setting for kiosk, and in the online settings for online ordering. A merchant can turn on one without the other — e.g. allow the order-level note but not per-item notes.
  • Backward Compatibility: allow_order_notes was split out of allow_notes after both existed as one combined toggle. If a tenant's saved settings have no allow_order_notes key yet, the API (ShowInHouseSettingsResource, ShowOnlineSettingsResource) mirrors allow_notes for it, and the save request (StoreInHouseSettingsRequest/StoreOnlineSettingsRequest) falls back to the submitted allow_notes value when allow_order_notes is absent from the payload — so pre-split behavior (one toggle controlling both) is preserved until the merchant explicitly configures allow_order_notes.
  • Sanitization (order note): The order note is sanitized server-side by TransactionService::sanitizeOrderNote() — HTML tags are stripped, whitespace is trimmed, the value is capped at 255 characters (Constants::ORDER_NOTE_MAX_LENGTH), and empty/whitespace-only input is stored as null.
  • POS Propagation: Both note kinds are forwarded to POS integrations that consume them — order note and item notes flow to Lightspeed K-Series, Kassanet, MplusKassa, ShopCaisse, and Square (order note); item notes also flow to Kassanet line items.

Actions ​

Enable Notes for a Channel ​

CheckoutNotes.vue renders two independent toggles, one per note kind, in In-House Settings (kiosk) or Online Settings (online ordering):

  • "Allow Item Notes" switch — sets allow_notes.enabled (per-item notes).
  • "Allow Order Notes" switch — sets allow_order_notes.enabled (order-level note).

Each toggle reveals its own placeholder textarea only when that toggle is on; the two can be switched on/off independently.

Set Placeholder Text ​

Each note kind has its own placeholder field, both required when their respective toggle is on and capped at 150 characters in the back office (requiredValidator + maxLengthValidator(..., 150) on the CheckoutNotes.vue textarea):

  • The per-item notes placeholder sets allow_notes.placeholder.
  • The order-level note placeholder sets allow_order_notes.placeholder.

Add a Note (Customer) ​

On the storefront, customers add a note per item and/or an order note at checkout.

Location ​

  • Backoffice Route: /in-house/settings (In-House — kiosk channel)
  • Backoffice Route: /online-settings (Online — online ordering channel)

The settings control is the shared CheckoutNotes.vue component, rendered in InHouseSettingsForm.vue (default mode) and OnlineSettingsForm.vue (mode="online-settings").

Fields ​

Notes Enabled (per-item) ​

PropertyValue
Field IDallow_notes.enabled
LabelAllow Item Notes
TypeToggle
Defaultfalse
Validation`required

Description: Enables per-item note input for customers on this channel.


Placeholder Text (per-item) ​

PropertyValue
Field IDallow_notes.placeholder
Label(back-office instruction: "Enter the placeholder text for the per-item 'add note' field. This guides customers in personalizing individual items.")
TypeText (textarea)
DefaultE.g. "For Oliver" or "I'm allergic to mushrooms (backend Constants default; the back-office textarea shows the hint text E.g. "For Oliver" or "I'm allergic to mushrooms")
Validationrequired when allow_notes.enabled is true, otherwise nullable; type string. Max 150 chars enforced in the back office only

Description: Hint text shown in the customer's per-item note input field. The back office requires this when per-item notes are enabled and caps it at 150 characters; the backend itself enforces only string (no length cap on the placeholder).


Order Notes Enabled (order-level) ​

PropertyValue
Field IDallow_order_notes.enabled
LabelAllow Order Notes
TypeToggle
Defaultfalse
Validation`required

Description: Enables the single whole-order note input for customers on this channel, independently of per-item notes. If a tenant has no saved allow_order_notes yet, the back office and API fall back to the value of allow_notes (see Backward Compatibility above).


Placeholder Text (order-level) ​

PropertyValue
Field IDallow_order_notes.placeholder
Label(back-office instruction: "Enter the placeholder text for the order-level note field. This guides customers in adding one instruction for the whole order.")
TypeText (textarea)
DefaultAdd a note for your whole order (backend Constants default; the back-office textarea shows the hint text E.g. "Please ring the doorbell" or "Leave at the front desk")
Validationrequired when allow_order_notes.enabled is true, otherwise nullable; type string. Max 150 chars enforced in the back office only

Description: Hint text shown in the customer's order-level note input field. The back office requires this when order notes are enabled and caps it at 150 characters; the backend itself enforces only string (no length cap on the placeholder).


Note Types ​

Item Notes ​

A free-text note attached to a single line item, stored on TransactionItem::notes.

Example use cases:

  • "No onions"
  • "Extra sauce"
  • "Well done"
  • "Allergies: nuts"

Order Note ​

A single free-text note for the whole order, stored on Transaction::note. Capped at 255 characters.

Example use cases:

  • "Please ring the doorbell"
  • "Leave at door"
  • "For Oliver's birthday"

Per-Channel Settings ​

In-House (Kiosk) ​

Stored in the in-house setting:

json
{
  "allow_notes": {
    "enabled": true,
    "placeholder": "Add special instructions..."
  },
  "allow_order_notes": {
    "enabled": true,
    "placeholder": "Add a note for your whole order"
  }
}

Online Ordering ​

Stored in the online settings:

json
{
  "allow_notes": {
    "enabled": true,
    "placeholder": "E.g. \"For Oliver\" or \"I'm allergic to mushrooms\""
  },
  "allow_order_notes": {
    "enabled": false,
    "placeholder": "Add a note for your whole order"
  }
}

Because the two toggles are independent, a channel can have allow_notes.enabled: true and allow_order_notes.enabled: false (or vice versa), as shown above.


Business Logic ​

Note Flow (configuration → capture) ​

Merchant enables "Allow Item Notes" and/or "Allow Order Notes" + sets placeholder(s) (per channel)
    │
    ├── allow_notes.enabled = true ?
    │   ├── No  → no per-item note input shown to customer
    │   └── Yes → customer may add a note per item
    │                 │
    │                 ▼
    │             Create-intent request: items.*.notes → TransactionItem.notes
    │
    └── allow_order_notes.enabled = true ?
        ├── No  → no order-level note input shown to customer
        └── Yes → customer may add one note for the whole order
                      │
                      ▼
                  Create-intent request: order_note → sanitizeOrderNote() → Transaction.note

Note: the two toggles are checked independently — a channel can show only the per-item note input, only the order-level note input, both, or neither. The order_note / items.*.notes request fields themselves are validated nullable by the backend regardless of the toggle state; the toggles gate whether the storefront/kiosk offers the input, not whether the backend accepts it if sent.

Note Propagation (to POS) ​

Transaction persisted
    │
    ├── Order note  (Transaction::getNote())
    │     → Lightspeed K-Series, Kassanet, MplusKassa, ShopCaisse, Square
    │
    └── Item notes  (TransactionItem::getNotes())
          → Lightspeed K-Series, Kassanet line items, MplusKassa

Business Rules ​

  • Per-item notes are gated by allow_notes.enabled; the order-level note is gated independently by allow_order_notes.enabled. When a flag is false, the customer is not offered that kind of note input.
  • If a tenant's saved settings predate the split (no allow_order_notes key stored), the API mirrors allow_notes for allow_order_notes in responses, and a save request that omits allow_order_notes falls back to the submitted allow_notes value — so old single-toggle behavior is preserved until the merchant explicitly sets allow_order_notes.
  • In the back office, both placeholder fields are required when their respective toggle ("Allow Item Notes" / "Allow Order Notes") is on (requiredValidator) and limited to 150 characters (maxLengthValidator(..., 150)). The backend validates each placeholder only as string (with required/nullable keyed off its own enabled flag) and applies no length cap.
  • The order note is server-sanitized: HTML stripped, trimmed, capped at 255 characters (Constants::ORDER_NOTE_MAX_LENGTH), and empty/whitespace-only values are stored as null.
  • Per-item notes (items.*.notes) are validated nullable|string — there is no backend length cap on item notes.
  • Per-item notes persist on TransactionItem; the order note persists on Transaction. Both are exposed to the customer via OrderDetailResource (item note, order-level note) and forwarded to the POS integrations listed above.

FAQs ​

  • "Is there an order-level note, or only per-item notes?" Both. Per-item notes live on TransactionItem::notes; there is also a single order-level note on Transaction::note (request field order_note), capped at 255 characters.
  • "Can I enable item notes without order notes, or vice versa?" Yes. allow_notes (per-item) and allow_order_notes (order-level) are separate settings, each with its own {enabled, placeholder}, and each toggle in the back office ("Allow Item Notes" / "Allow Order Notes") can be switched independently.
  • "Where are note settings configured?" In two places, each independent: In-House Settings (/in-house/settings, kiosk) and Online Settings (/online-settings, online ordering). Each place has two separate toggles, one for item notes and one for order notes. QR ordering has no allow_notes/allow_order_notes setting in the backend.
  • "Why does my order-level note setting show the same value as my item notes setting?" If allow_order_notes hasn't been saved for that channel yet (e.g. it predates the split into two toggles), the back office and API fall back to the allow_notes value for it. Save the settings page once with the desired "Allow Order Notes" value to set it explicitly.
  • "What is the maximum length for notes?" The order note is capped server-side at 255 characters (Constants::ORDER_NOTE_MAX_LENGTH). Per-item notes have no backend length cap (nullable|string). The 150-character limit applies to the merchant-configured placeholder text for both toggles in the back office, not to customer notes.
  • "What is the default placeholder?" For per-item notes, the backend Constants default is E.g. "For Oliver" or "I'm allergic to mushrooms, and the back-office hint text is E.g. "For Oliver" or "I'm allergic to mushrooms". For the order-level note, the backend Constants default is Add a note for your whole order, and the back-office hint text is E.g. "Please ring the doorbell" or "Leave at the front desk". Both note kinds are off by default (enabled: false).
  • "Do notes reach the POS / kitchen?" Yes. The order note is sent to Lightspeed K-Series, Kassanet, MplusKassa, ShopCaisse, and Square; item notes are sent to Lightspeed K-Series, Kassanet line items, and MplusKassa.

Customer Impact ​

  • When per-item notes are enabled (allow_notes.enabled), customers can add a note per item at checkout; when order-level notes are enabled (allow_order_notes.enabled), customers can add a single overall order note. The two are independent, so a channel may offer only one, both, or neither.
  • Notes are returned in the customer's order detail (OrderDetailResource): each item carries a singular note, and the order carries an order-level note.

Troubleshooting ​

  • No per-item note input shown to the customer → Verify "Allow Item Notes" (allow_notes.enabled) is on for the correct channel: In-House Settings for kiosk, Online Settings for online ordering.
  • No order-level note input shown to the customer → Verify "Allow Order Notes" (allow_order_notes.enabled) is on for the correct channel. This is a separate toggle from "Allow Item Notes" — enabling one does not enable the other.
  • Order note appears truncated → The order note is capped at 255 characters server-side; longer input is trimmed by sanitizeOrderNote().
  • Note not reaching a POS → Confirm the POS integration is one that consumes notes (Lightspeed K-Series, Kassanet, MplusKassa, ShopCaisse, or Square for the order note). Other channels may not forward notes.

Assistant Guidance ​

When answering questions about this feature:

  • Treat "Allow Notes" / "notes setting" as ambiguous — always clarify whether the merchant means the per-item toggle (allow_notes, back-office label "Allow Item Notes") or the order-level toggle (allow_order_notes, back-office label "Allow Order Notes"). They are two separate settings, not one.
  • If a merchant reports their order-level note setting mysteriously matches their item-note setting, explain the backward-compat fallback: allow_order_notes falls back to allow_notes until it's explicitly saved for that channel.
  • Always specify which channel: In-House Settings (/in-house/settings, kiosk) and Online Settings (/online-settings, online ordering) hold separate copies of both toggles. QR ordering has neither setting.
  • The 150-character limit is on the merchant-configured placeholder text in the back office, not on what customers type; the customer-facing order note is capped at 255 characters server-side, and per-item notes have no backend length cap.

Relations ​

Affects ​

  • Transactions: Order note stored on Transaction; item notes on TransactionItem
  • POS integrations: Notes forwarded to Lightspeed K-Series, Kassanet, MplusKassa, ShopCaisse, Square

Examples ​

Notes Enabled (channel setting, both toggles) ​

json
{
  "allow_notes": {
    "enabled": true,
    "placeholder": "Special instructions..."
  },
  "allow_order_notes": {
    "enabled": true,
    "placeholder": "Add a note for your whole order"
  }
}

Create-Intent Request (item note + order note) ​

json
{
  "items": [
    { "id": "item-123", "notes": "No basil, extra cheese" }
  ],
  "order_note": "Please include extra napkins"
}

Persisted Transaction (resolved fields) ​

json
{
  "items": [
    { "name": "Margherita Pizza", "notes": "No basil, extra cheese" }
  ],
  "note": "Please include extra napkins"
}