Skip to content

Square Integration

Overview

The Square integration connects Upvendo with your Square account so that menu, locations, and inventory stay synchronized, and so that Square handles all customer payments (kiosk via Square Terminal, online ordering via the Square Web Payments SDK).

Key Purpose: Sync your Square catalog, locations, and inventory with Upvendo, and process all kiosk and online payments through Square.

IMPORTANT: Square is a full POS integration. When Square is connected, Square Payments replaces both Stripe (Online Ordering) and Viva Wallet (Kiosk Terminal). Connecting Square sets the merchant's provider_integrated to square.

For the technical details (OAuth scopes, webhooks, sync algorithm, jobs), see the Square Integration Setup doc.

Purpose

The Square page lets you connect your Square account to Upvendo so that menu (categories, modifier groups, items, variant groups), locations, and inventory are synchronized between both systems, and so that Square processes all payments.

Key Concepts

  • Merchant-scoped integration: One Square connection covers the entire merchant account and all of its locations. It is not configured per location.
  • Square handles payments: When Square is connected, the isSquareIntegrated() check (in IntegrationTrait) causes PaymentService to route kiosk terminal payments through processSquarePayment (Square Terminal) instead of Viva Wallet, and online-ordering payments through Square's Web Payments SDK instead of Stripe.
  • Bidirectional sync: For each entity (location, category, modifier group, item, variant group, inventory count) the system decides per-entity whether to push (Upvendo to Square), pull (Square to Upvendo), or skip, based on timestamps and a content hash.
  • Square Terminal Checkout: For kiosk payments, the system creates a Square Order, then a TerminalCheckout on the paired Square Terminal device, and confirms completion via the payment.updated webhook.
  • Sync logs: The integration keeps a rolling log of recent sync operations (capped at 1000 entries) with timestamps, types, and messages; consecutive identical entries are collapsed by updating the timestamp.

Actions

Connect or Reconnect Square Account

From the Settings tab, click Connect with Square to start the OAuth flow and authorize Upvendo to access your Square account. Once connected, the button becomes Reconnect (it re-runs the same OAuth flow).

Run a Manual Sync

From the Status tab (or the Sync Now button at the top of the page), trigger a full sync of locations, menu, and inventory.

Configure the Daily Sync Time

From the Settings tab, set the time of day the automatic daily sync runs. The only configurable sync setting is the daily sync time (plus an internal auto-sync enable flag) -- there are no per-data-type toggles or a sync-direction picker.

Disconnect (Delete) Square

From the Settings tab, click Delete and confirm. This revokes the Square token, removes the integration, and clears Square as the payment provider.

Payment Provider Override

Square Connected?
├── Yes → ALL payments through Square
│         ├── Online Ordering → Square Web Payments SDK
│         └── Kiosk Terminal  → Square Terminal

└── No → Default providers
          ├── Online Ordering → Stripe
          └── Kiosk Terminal  → Viva Wallet

Location

  • Backoffice Route: /square
  • Backend Controller: app/Http/Controllers/Api/BackOffice/SquareIntegrationController.php
  • Vue Views: src/views/square/index.vue (with SquareForm.vue, SquareStatusTab.vue, SquareLogs.vue, SquareDeleteConfirmationDialog.vue)
  • API prefix: /back-office/square

Page Layout

The Square page has two tabs:

TabContents
StatusSync status banner, Sync Now button, connection status, and the sync log history.
SettingsOAuth connect/reconnect (with Merchant ID and token expiry once connected), the Daily Sync Time field, Save, and Delete.

Fields

Connection (Settings tab)

PropertyValue
Fieldis_connected
LabelConnected
TypeDisplay (status alert)

Description: Whether the Square account is connected. When connected, the page also shows the Square merchant_id and the access-token expiry.


Connect with Square

PropertyValue
ActionConnect / Reconnect
TypeOAuth flow

Description: Starts the Square OAuth authorization flow. After authorization you are redirected back to /square/success (or /square/error on failure).


Daily Sync Time

PropertyValue
Fieldsync_time
Label(sync time)
TypeTime picker (24h)
ValidationMust be HH:00 or HH:30 (regex `^([01]?[0-9]

Description: The time of day the automatic daily sync runs (locations, menu, inventory). Stored as a local wall-clock time in settings.sync_time, with the resolved IANA zone in settings.sync_timezone — not converted to UTC, so it does not drift across a DST transition. The resolved zone is returned on the status payload and shown as a read-only caption under the field.

Note: Earlier KB versions documented location_id, sync_items, sync_orders, sync_inventory, and sync_direction fields. Those do not exist. The merchant cannot select a Square location, toggle individual data types, or pick a sync direction -- all sync runs together and direction is decided automatically per entity. Orders are not a "sync setting"; Square Orders are created only as part of payment processing.

Business Logic

Sync Flow

Trigger (manual "Sync Now" or daily auto-sync)
        |
        v
Test connection (fetch merchant info)
        |
        v
Sync Locations  --> Sync Menu (categories -> modifier groups -> items/variant groups)
        |
        v
Sync Inventory
        |
        v
Update sync status + log result

Each entity's direction (push / pull / skip) is decided automatically by comparing the Upvendo updated_at against the last push timestamp and comparing a content hash of the Square entity. See the integration doc for the full algorithm.

Business Rules

  • When Square is connected, the isSquareIntegrated() check causes PaymentService to route kiosk terminal payments through processSquarePayment (Square Terminal) instead of Viva Wallet, and online-ordering payments through Square's Web Payments SDK instead of Stripe.
  • Kiosk terminal payment requires a paired Square Terminal: the device's getSquareTerminalId() must be set; if it is missing, an exception is thrown before contacting Square.
  • If an existing terminal checkout is still PENDING, the system returns the current transaction without creating a duplicate checkout. If it is already COMPLETED, the transaction is returned as-is. If it was canceled/failed, a new checkout is created.
  • Terminal checkout cancellation is attempted via the Square API; failures are logged but do not throw, so the Upvendo transaction can still be updated.
  • Sync logs are capped at 1000 entries; consecutive duplicate entries (same message and type) update the timestamp instead of adding a new row.

FAQs

  • Does connecting Square automatically disable Stripe and Viva Wallet? Effectively yes. Connecting Square sets provider_integrated to square, and payment routing checks isSquareIntegrated() at runtime, so kiosk payments go to Square Terminal and online payments to Square's Web Payments SDK instead of Viva Wallet/Stripe.
  • Can I choose which data types to sync, or the direction? No. There are no per-type toggles or a direction picker. Locations, menu, and inventory all sync together, and the direction is decided automatically per entity from timestamps and a content hash.
  • What happens if the Square Terminal payment fails? The error is logged and an exception is thrown with the Square error message; the kiosk shows a payment failure and allows retry (a new idempotency key is generated for the retry).
  • Do all my Square locations connect at once? Yes. Square is merchant-scoped: one connection imports and syncs all locations under the Square merchant.
  • How do I check sync history? The sync log is shown on the Status tab; it keeps the most recent entries (capped at 1000).

Troubleshooting

Problem: Sync failing

Causes:

  1. Connection expired (token needs refresh / reconnect)
  2. Square API error or rate limit
  3. A specific entity failed to transform

Solutions:

  1. Reconnect Square from the Settings tab
  2. Wait and run Sync Now again
  3. Review the sync log on the Status tab for the failing entity

Problem: Items not syncing

Causes:

  1. The sync hasn't run yet
  2. Item not yet linked to a Square catalog object
  3. A transform/validation error for that item

Solutions:

  1. Click Sync Now on the Status tab
  2. Re-run the sync (new items get linked on the next sync)
  3. Check the sync log for the specific item error

Examples

Status response (representative subset)

json
{
  "is_connected": true,
  "provider": "square",
  "merchant_id": "MLxxxxxxxxxxxx",
  "is_sandbox": false,
  "access_token_expires_at": "2026-07-01T00:00:00Z",
  "is_token_expired": false,
  "sync_time": "03:00",
  "sync_status": { "status": "success" },
  "last_sync_at": "2026-06-16T03:00:12Z"
}

Relations