Skip to content

Locations

Overview

Locations represent physical business locations (stores, restaurants, branches). Each location has its own profiles, address, operating hours, and order settings. All other features are scoped to locations.

Purpose

This page lets you configure your physical business locations with addresses, contact details, operating hours, and order behavior settings.

Key Concepts

  • Location: A physical store, restaurant, or branch with its own settings
  • Payment Profile: Payment provider configuration assigned to the location
  • Branding Profile: Visual theme for kiosk and online ordering at this location
  • Operating Hours: Days and times when customers can place orders
  • Customer prep time: Average minutes needed to prepare an order (affects earliest pickup time)
  • Restricted Dates: Specific dates when the location is closed (holidays, etc.)

Route

  • Backoffice Route: /settings/locations (list)
  • Add Location: /settings/locations/newnew is the literal add-mode sentinel; any other value in that slot puts the form in edit mode
  • Edit Location: /settings/locations/:id

Actions

Add Location

Click "Add Location" to create a new location. Fill in all required fields and save.

Edit Location

Click "Edit" on an existing location to modify its settings.

Export Locations

Export location data for reporting or backup.


Form Sections

Profiles

Assign profiles to this location for centralized management.

FieldTypeRequiredDescription
Payment ProfileSelectNoPayment provider configuration (optional — can be set up later). Hidden for Square-integrated accounts
Billing ProfileSelectNoBilling/invoicing settings (billing_profile_id), used for Upvendo-platform invoicing — a merchant invoiced by a reseller does not need one. Optional on the form and in the API. The form still pre-selects the default billing profile if one is marked default; once set on an existing location the field becomes read-only
Branding ProfileSelectNoVisual theme for kiosk and online ordering. Optional on create and update — the same StoreLocationRequest serves both, and it only checks that the profile exists when one is provided. Consumers fall back to the merchant/platform default branding

Business Logic:

  • Billing profiles flagged incomplete (no Stripe customer yet) stay selectable in the dropdown — the location saves with the link and the Stripe customer ID is stamped on later, once the profile's billing details are completed.
  • A location already linked to a different billing customer cannot be silently re-pointed through this field: the save is rejected with "This location is already linked to a different billing profile." Selecting a profile that no longer exists returns a not-found error.
  • Locations linked the old way carry only stripe_customer_id. When the form loads it resolves the matching profile so the selector shows the existing link, and saves from then on send billing_profile_id.

Status (edit mode only)

A Status selector (Active / Inactive) appears in the location header when editing an existing location.

  • Switching to Inactive while the location has active subscriptions opens a confirmation dialog that requires typing the location name before deactivating.
  • For all other status changes (including reactivating), the change is applied directly.
  • The status control is hidden when adding a new location and may be disabled for locations whose status field is uneditable (e.g. synced locations).

Stripe Card Terminal Address Sync

When a location's Payment Profile uses Stripe for in-person (card terminal) payments, saving the location triggers a background sync that registers a matching Stripe Terminal Location using the location's address. If Stripe rejects the address (most commonly an invalid or incomplete postal code), the rejection is recorded on the location as stripe_terminal_sync_error ({message, failed_at}) and surfaced to the merchant until a later sync succeeds, which clears it automatically:

  • Location form: a warning banner ("Card terminal setup failed") appears at the top of the form, with the detail text "Stripe reported: <message>" and guidance to check the address, especially the postal code, and save again.
  • Locations list: an error-colored "Card terminal sync failed" chip appears next to the location (alongside the "Payment not configured" chip if applicable); hovering it shows the Stripe rejection message.
  • This sync/warning is specific to Stripe in-person payments — it does not apply to Viva Wallet or Square in-person configurations.

General → Location Details

FieldTypeRequiredValidationDescription
Location NameTextYes-Name shown to customers
DescriptionTextareaNo-Internal description
Location TypeSelectYes-Category of location
Preferred Display LanguageSelectYes-Default language for this location

Business Logic:

  • The Preferred Display Language picker only lists languages that are Published. If none are published (or you need another), use the Add Language entry at the bottom of the picker instead of leaving the form. The entry appears for users with the create-language permission; creating a language there also publishes it immediately and selects it — unlike Settings → Languages, where a new language is created Unpublished and must be published separately. Publishing is itself an edit-language action, so a role with create-language but not edit-language can create the language from the picker but the automatic publish step is rejected.
  • For locations imported from a POS (e.g. MplusKassa), a read-only hint reading Imported from POS as "<name>" appears under the Location Name field, showing the original branch name from the POS. This hint is shown whenever the location has a POS-provided name (pos_name), whether or not the merchant has since renamed it — the field itself (pos_name) is not editable by the merchant.

Contact Details

FieldTypeRequiredValidationDescription
EmailEmailYesValid emailContact email
PhonePhoneYesValid phone with country codeContact phone
CategorySelectYes-Business category

Address

The Address section opens with the Country select — always visible, and carrying the hint "Used to search for your address. It is automatically set to match your map pin." — followed by a Search address autocomplete. The four typed fields (Address Line 1, Address Line 2, Postal Code, City) are hidden on a new location until you pick a suggestion, drop or move the map pin (which reverse-geocodes and fills them in), or click Enter address manually. On an existing location that already has an address line, city or postal code, they render straight away. Picking a search suggestion writes the whole formatted address into Address Line 1, and both the suggestion and the pin overwrite Country — the pin is authoritative for country. The coordinates row shows "Drop a pin on the map to set the coordinates" until a pin exists; Edit manually reveals the Latitude/Longitude inputs.

FieldTypeRequiredDescription
Address Line 1TextYesStreet address
Address Line 2TextNoSuite, floor, building
Postal CodeTextYes (form)ZIP/postal code. Required by the back-office form; the API rule itself allows it to be empty
CityTextYesCity name
CountrySelectYesCountry. On a new location it pre-fills from the selected payment profile's country, and stays editable
GeolocationMapYes (to save)Interactive map to set pin
LatitudeNumberYes (to save)Auto-filled from map pin (pinpoint.lat)
LongitudeNumberYes (to save)Auto-filled from map pin (pinpoint.lng)

Business Logic:

  • Geolocation map allows clicking to set coordinates
  • The map never auto-places a pin. Click the map, drag the marker, pick an address from Search address, or use Edit manually to type coordinates
  • Latitude/longitude (pinpoint.lat/pinpoint.lng) are not enforced by the form's field validation, but the save still fails without them: the backend derives the location's timezone and Google address from the pin and returns "We failed to get the address details from the pinpoint location. Please try again later." when there is no usable pin
  • If the geocoded country of the pin does not match the selected Country, the save is rejected with "Country code mismatch. Please check your pinpoint location."
  • The map pin is also required for online-ordering readiness (see the Ready / Partial / Incomplete badge); a location without a pin counts as missing geolocation for online ordering
  • Coordinates used for delivery distance calculations and map display
  • Address shown on receipts and order confirmations

Operating Hours

Define when customers can place orders at this location.

  • Days: Monday through Sunday (checkbox per day)
  • Add Times: Set open/close times per day (multiple time ranges supported)
  • Select All: Apply same hours to all days

Business Logic:

  • Hours determine when online ordering is available
  • Outside operating hours, customers see "Location closed"
  • Multiple time ranges per day supported (e.g., 11:00-14:00, 17:00-22:00)

Restricted Dates

Add dates when the location will be closed (holidays, renovations, etc.).

  • Click "+" to add a restricted date
  • Location will be unavailable for orders on these dates
  • Each row can be a single date or, by enabling Date range, a span from a start date (date_from) to an end date (date_until) — the end date must be on or after the start date
  • A "Repeats every year" (yearly) checkbox makes a single date recur annually. This option is unavailable while a row is in date-range mode

Order Behavior

FieldTypeRequiredDefaultDescription
Customer prep timeNumber (minutes)Yes20Average time to prepare an order (the field shows the hint "Default: 20 minutes"; the Online Ordering page's read-only chip still labels the same value "Preparation time")

Customer prep time is the only control in this section.

Business Logic:

  • Customer prep time: Affects the earliest available pickup, delivery and online eat-in time
    • Earliest time = Now + Customer prep time + Channel Delay (takeout, delivery or eat_in)
    • The same number is quoted in two places and they agree: the nearby-restaurants list customers browse before ordering, and the time-slot picker at checkout. (Verified: app/RawModels/Location.php:2001-2018 is the single rule; getOnlineOrderingPrepTime() at :2072-2087 and app/Services/OrderCapacity/OrderCapacityService.php:86-89 both call it.)

Emily-drafted fields

Emily can pre-fill the location form for you. If you are not already on a location form she opens the new-location form (/settings/locations/new) first, then merges her draft into the fields. Every section she touched shows a chip reading "Emily filled this — review and Save" — the sections wired up for this are the name/description/type/language block, contact details and category, address and map pin, operating hours, restricted dates, and preparation time.

Nothing is saved until you click Save: the draft is inert, and the chip is only a marker in the back office — it is never sent to the server.


Business Rules

  • A location name is required, but it is not required to be unique within the merchant account (the uniqueness check is not currently enforced)
  • Phone is required — validation enforced
  • A location can have only one of each profile type (payment, billing, branding)
  • Operating hours must be set for online ordering to work
  • Locations without operating hours are treated as always closed
  • Customer prep time does not affect all order channels. It is applied to exactly three dining options on the online-ordering channel — delivery, pickup (takeout) and eat-in (For Here) — each with its own delay. Any other dining option gets a prep time of 0, and so do kiosk and table-QR ordering, which are immediate. (Verified: app/RawModels/Location.php:2003-2012 — the match maps Delivery/Pickup/ForHere to delivery/takeout/eat_in, and default => null short-circuits to return 0; app/Services/OrderCapacity/OrderCapacityService.php:126-131 returns 0 for any non-online-ordering channel and for table-QR sessions.) The value is still sent to kiosk devices as settings.average_prep_time_min (app/RawModels/Device.php:927); what the kiosk does with it is not verified here
  • A dormant backfill command exists and must not be run casually. php artisan locations:backfill-average-prep-time shipped to production with the prep-time unification but is unscheduled and has never been run anywhere. It refuses to run on production without --force, and its own error says why: it "changes a live prep promise and can pull the table-QR cutoff back" (app/Console/Commands/DataRepair/BackfillLocationAveragePrepTime.php:63-66, :78-80). Stamping the 20-minute default onto locations that currently read 0 would simultaneously raise their advertised prep time and move their Closing-Time-Minus-Prep-Time table-QR cutoff earlier. Running it is a product decision, not a cleanup.
  • Changes to location settings take effect:
    • Online Ordering: On next page load
    • Kiosk: After app sync/reload

Logic Flows

Location Selection (Online Ordering)

Customer opens Online Ordering


Multiple locations?
├── Yes → Show location selector
│         Customer chooses location
│         Load location's menu and settings

└── No → Load single location automatically

Location-Scoped Settings

Location
├── Profiles (Payment, Billing, Branding)
├── Operating Hours
├── Restricted Dates
├── Order Behavior
├── Menus (assigned)
├── Delivery Zones
├── Order Capacity
└── Devices (kiosks assigned)

Customer Impact

  • Kiosk: Uses assigned location's menu, branding, and settings
  • Online Ordering: Location selector, hours, address displayed
  • Receipts: Location name, address, phone printed
  • Delivery: Location's delivery zones determine availability

FAQs

  • "How do I add a new location?"

  • "Where do I change my store's address?"

  • "How do I set opening hours for my location?"

  • "Can I have different menus per location?"

  • "Why is my location showing as closed?"

  • "How do I close my store for a holiday?"

  • "Where do I set the preparation time?"

  • "Can I use different branding per location?"

  • "Is the payment profile required when I create a location?" No. The payment profile is optional — you can save a location and configure payment later. If it's not set up, the location shows a "Payment not configured" chip in the Settings → Locations list. The chip appears whenever the location has no payment profile; it is not suppressed for Square-integrated accounts, even though the Payment Profile selector itself is hidden for them.

  • "Which profile is actually mandatory to create a location?" None. Payment, Billing and Branding are all optional at creation — the form submits with none of them selected, and the API accepts all three as empty. A fresh merchant can create their first location before setting up branding or billing. The form still pre-selects a default for each profile type if one is marked as default, so they often look pre-filled.

  • "What is the 'Ready / Partial / Incomplete' badge next to my location?" It's an online-ordering completion indicator. A location is Ready only when Address, Business hours, and Geolocation (map pin) are all set; Partial if some are set; Incomplete if none. Hovering the badge lists exactly which fields are missing.

  • "My location says it's missing 'Geolocation' even though I typed the address — why?" The map pin (latitude/longitude) is tracked separately from the typed address and is required for online ordering. Drop a pin on the map (or use "Edit manually" to enter coordinates) in the Address section — an address with no pin still counts as missing geolocation.

  • "How do I deactivate a location instead of deleting it?" Open the location in edit mode and use the Status selector to switch between Active and Inactive. If the location has active subscriptions, you'll get a confirmation dialog and must type the location name to deactivate.

  • "What's the difference between deactivating and deleting a location?" Deactivating sets the status to Inactive and is reversible. Delete Location is permanent and can't be undone — and because deleting affects all linked branding, you'll be asked to type the location name to confirm.

  • "How do I set a recurring closure, like the same holiday every year?" In Restricted Dates, add a date and tick "Repeats every year" so it recurs annually. You can also switch a row to Date range mode to close across a span of consecutive days.

  • "I changed the payment profile and got a warning — what does it mean?" Changing the payment profile means you'll need to reconfigure the payment terminal on all of that location's kiosks. Continue only if you're prepared to re-pair the terminals.

  • "Why can't I edit the type or timezone on one of my locations?" Locations synced from MplusKassa have type and timezone locked because they come from the MplusKassa branch and can't be overridden in Upvendo. The Location Name is editable even for MplusKassa-synced locations — you can rename it freely; the original POS branch name is kept and shown as a read-only hint under the Location Name field (e.g. Imported from POS as "<name>") for reference.

  • "How do I export my locations?" On the Settings → Locations list, click Export (top right). It downloads an Excel file named locations_export_<date>.xlsx and respects any active search filter.

  • "Is a postal code required for a location address?" Yes. Address Line 1, Postal Code, City and Country are all required by the form; only Address Line 2 is optional. (The API rule for postal code allows it to be empty, but the form won't submit without it — and Stripe card-terminal registration needs a valid postal code.) The Country field also auto-syncs to match your map pin, so dropping/moving the pin can update the country.

  • "Why do I see a 'Card terminal setup failed' warning on my location?" Your location's Payment Profile uses Stripe for in-person (card terminal) payments, and Stripe rejected the location's address when trying to register a matching Terminal Location — most often an invalid or incomplete postal code. Double-check the address (especially Postal Code) under Address and save again; the warning banner on the form and the "Card terminal sync failed" chip in the locations list both clear automatically once a sync succeeds.


Troubleshooting

  • Location not showing in online ordering → Check if operating hours are set and location is enabled
  • Wrong times showing → Verify timezone in account settings and operating hours
  • Location shows as closed → Check operating hours and restricted dates
  • Map pin in wrong place → Click on map to reposition or enter coordinates manually
  • Can't save location → Ensure phone number is filled in (required field)
  • "My location is not found" / location not ready for online ordering → This is almost always a missing map pin (Geolocation). Open the location in Settings → Locations, go to Address → Geolocation, and click the map to drop a pin (or use "Edit manually" to enter coordinates), then Save. The typed address does not set the pin on its own; a location with no pin (or a pin at 0,0) keeps showing "Missing: Geolocation" and stays Partial/Incomplete for online ordering.
  • "Card terminal setup failed" warning / "Card terminal sync failed" chip → The location's Payment Profile uses Stripe for in-person payments and Stripe rejected the address when syncing the Terminal Location (commonly a bad postal code). Fix the address under Address and save; the warning clears automatically once the next sync succeeds.

Assistant Guidance

When answering questions about locations:

  • Use clear navigation: "Go to Settings → Locations"
  • For new locations, walk through the form sections in order
  • If location appears closed, check: operating hours, restricted dates, timezone
  • For multi-location merchants, clarify which location they're asking about
  • Mention that profiles (payment, billing, branding) are assigned per location
  • Preparation time affects when customers can place orders — suggest 15-30 min for most restaurants
  • For MplusKassa-synced locations, only type and timezone are locked — the name is editable (the original POS name stays visible as a hint)
  • A "Card terminal setup failed" warning or "Card terminal sync failed" chip means Stripe rejected the location's address (usually the postal code) while syncing the card terminal — point the merchant to fix the address, not the payment profile itself

Relations

Depends On

  • Merchant Account: Locations belong to merchant
  • Profiles: Payment, Billing, Branding profiles assigned to locations

Affects

  • All location-scoped features:
    • Menus
    • Delivery Zones
    • Order Capacity
    • Devices
    • Business Hours
    • Inventory