> ## Documentation Index
> Fetch the complete documentation index at: /docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Square POS-native commerce setup

> Connect Square for provider-native catalog, order, payment-evidence, and reconciliation operations.

Square is a POS-native integration. It supplies provider catalog and inventory
inputs and can own certified order projection, fulfillment, in-person tender,
refund, and reconciliation behavior, but it never becomes a browser payment
processor. Crave's organization-owned catalog and typed location overlays stay
authoritative for storefront pricing, availability, and schedules. Stripe is
the only online processor. For `PAY_AT_STORE`, Square is the settlement adapter
and provider-recorded cash is preferred; a certified audited-cash fallback
remains merchant authority, not a second adapter.

## Activation flow

**1. Connect Square via OAuth**

Authorize the requested merchant, customer, catalog, order, payment, refund,
card, gift-card, inventory, location, and loyalty scopes.

**2. Map one Square location**

Bind the Crave location to the exact Square location after currency,
timezone, and capability checks.

**3. Import, review, and publish the canonical catalog**

Stage Square objects against stable Crave identities, resolve mapping
conflicts, apply target-location price and availability overlays, and
publish a fresh reviewed snapshot. Import and reconciliation never publish
automatically or overwrite unrelated location overlays.

**4. Activate routing, then certify provider-native readiness**

Activate the reviewed POS-routed policy first; this still does not expose
pay at store. Pair the exact Terminal with a Devices API pairing code, prove
order visibility, native tender, refund, webhook, and reconciliation
behavior, then certify the same active policy revision. Delivery
additionally requires explicit Square Delivery certification and DoorDash
Drive credentials.

## Pay at store flow

1. Crave persists one unpaid canonical order and routes its immutable
   fulfillment identity to Square.
2. Staff starts collection from Crave Orders Manager on the exact certified,
   mapped Square Terminal. A Square POS app running only on a phone is not a
   substitute for a certified Terminal device.
3. Square records the native tender. Signed webhooks and provider readback
   append immutable tender evidence to the existing Crave settlement.
4. Crave marks payment `PAID` only after exact amount, currency, account,
   location, order, and tender evidence match. Fulfillment may progress while
   payment is still `DUE`.

If payment evidence is delayed, the operator sees the certified refresh,
fallback-read, warning, and action-required thresholds plus **Verifying payment
— do not charge again**. Reconciliation retains the same collection identity;
it never starts another charge.

## Authority rules

* Online checkout always uses the order-first Stripe flow. The storefront does
  not load Square Web Payments, tokenize Square cards, or create Square checkout sessions.
* Square payment and tender identifiers enter Crave only as provider-native
  order or webhook evidence bound to the exact tenant, connection, location, and order.
* Square constructs its provider order from mapped catalog variations, taxes,
  discounts, service charges, and an optional order-linked Loyalty reward. The
  resulting provider total must reconcile to Crave's accepted immutable quote;
  Square never rewrites the canonical catalog or customer-facing total.
* Staff tip is recorded on the final Square Payment. DoorDash courier tip and
  the authoritative Drive fee plus tax are Square Order service charges.
* Provider-native split tenders and gift-card evidence remain server-side
  reconciliation inputs. The storefront cannot create or fund them.
* All refunds are admitted through the canonical `Refund`, `RefundAllocation`,
  and `RefundDispatchOperation` owner before a later provider adapter performs a write.
* A refund of the payment that purchased a gift card triggers an idempotent
  Square `ADJUST_DECREMENT` activity with reason `PURCHASE_WAS_REFUNDED`, because
  refunding that funding payment does not reverse the loaded gift-card balance.
* Square Loyalty replaces LIP for Square-authoritative locations. Enrollment,
  reward preview, issue, redemption, point accrual, and webhook projection use
  the Square customer and Loyalty account.
* Provider-native loyalty evidence is reconciled independently from Stripe
  online payment collection; no loyalty action changes the browser processor.
* Enrollment requires a phone that is currently verified on the active Clerk
  session. If the customer has no verified phone, direct them to the
  Clerk-managed profile or reverification flow, obtain a fresh
  `crave-customer` token, and retry enrollment. An E.164-shaped profile value
  or historical Crave timestamp alone is not accepted as proof. Clerk phone
  verification does not accept Square marketing text terms.
* Customer loyalty history is location-scoped at
  `GET /customer/locations/{locationId}/loyalty/ledger`. A Square-authoritative
  location reads the current balance with `RetrieveLoyaltyAccount` and the
  reverse-chronological activity ledger with `SearchLoyaltyEvents` (up to 30
  entries per page). It never falls back to LIP when Square is connected. The
  retained location binding keeps that exclusion in force if Square credentials
  or runtime health degrade, so Crave cannot mutate a second loyalty ledger
  through quote, cart, completion, cancellation, refund, or durable retry
  hooks. A queued LIP mutation rechecks the task location before delivery and
  terminates without a provider call after Square takes authority. Legacy tasks
  without location authority fail closed as well.
* When an administrator approves a customer loyalty claim, Crave resolves the
  claim order's location before choosing the provider. A Square-authoritative
  order writes the approved correction through Square `AdjustLoyaltyPoints`
  with a stable provider idempotency key and retains the returned Square event
  ID. Provider errors leave the claim retryable; Crave never posts that
  adjustment to LIP. Orders at locations without Square authority continue to
  use the configured LIP program.
* Completed Square orders accrue Loyalty points with an order-scoped provider
  idempotency key. A failed or ambiguous accrual is retained as a durable
  `LOYALTY_EFFECT` operation; the worker re-proves the completed Square tenders,
  current tenant and location binding, and returned Loyalty events before it
  marks the cart projection complete.
* Vendor confirmation, ready-for-pickup, and completion actions update the
  exact Square fulfillment before Crave commits the matching local state. Each
  update uses the current Square order version, fulfillment UID, and a stable
  idempotency key. Square-originated fulfillment webhooks apply locally without
  echoing the same transition back to Square.
* Crave subscription is the launch revenue base. Pay at store does not take a
  transaction split from the Square tender, and prepared-but-uncollected or
  no-show loss remains merchant risk under configured identity and exposure limits.

## Delivery with DoorDash Drive

Delivery is fail-closed until the location has fresh capability evidence whose
source is `square_live_pos_delivery_certification`, a selected
`DOORDASH_DRIVE` provider, and valid Drive credentials.

Crave requests a five-minute Drive quote, fingerprints its address and cart
inputs, adds `fee + tax` and courier tip to the Square Order, pays that exact
order, then accepts the same Drive quote. Definite dispatch rejection triggers
idempotent Square refund compensation. An ambiguous timeout is reconciled using
the same external delivery ID and is never auto-refunded while a courier job
might exist. DoorDash webhooks update Crave tracking and the Square delivery
fulfillment.

Active deliveries are also retrieved every 60 seconds when their last
reconciliation is more than two minutes old, so a missing webhook does not
strand tracking state. Order cancellation reaches a conclusive DoorDash cancel
state before Square refund processing begins.

## Webhooks

Create the Square subscription against:

```text theme={null}
https://<sandbox-api-host>/api/v1/webhooks/square
```

Subscribe to the exact events handled by this release:

```text theme={null}
catalog.version.updated
inventory.count.updated
location.created
location.updated
order.created
order.updated
order.fulfillment.updated
payment.created
payment.updated
terminal.checkout.created
terminal.checkout.updated
refund.created
refund.updated
customer.created
customer.updated
customer.deleted
card.created
card.updated
card.disabled
card.forgotten
card.automatically_updated
loyalty.account.created
loyalty.account.updated
loyalty.account.deleted
loyalty.event.created
loyalty.program.created
loyalty.program.updated
loyalty.promotion.created
loyalty.promotion.updated
gift_card.created
gift_card.updated
gift_card.customer_linked
gift_card.customer_unlinked
gift_card.activity.created
gift_card.activity.updated
oauth.authorization.revoked
```

Set `SQUARE_WEBHOOK_SIGNATURE_KEY` only in the sandbox secret manager. Never
paste it into tickets, chat, source control, or browser configuration. Crave
verifies Square's signature over the untouched body and exact notification URL,
then acknowledges only after durable inbox storage.

For DoorDash Drive, register:

```text theme={null}
https://<sandbox-api-host>/api/v1/webhooks/doordash
```

Configure the same Basic or OAuth `Authorization` value in DoorDash and the
`DOORDASH_WEBHOOK_AUTHORIZATION` sandbox secret. Crave compares the exact value
in constant time, durably stores the event, serializes delivery projections,
and retries failures.

## Health and recovery

The Square integration page shows authorization and mapping status, capability
readiness, last reconciliation, last webhook receipt, and pending or failed
events. Use **Reconcile** to refresh locations, catalog, inventory, orders,
payments, refunds, customers, cards, Loyalty programs, promotions, accounts,
events and rewards, plus gift cards and their location activity. Gift-card
account numbers are redacted before reconciliation evidence is stored. Use
**Retry events** after repairing a dependency. A webhook HTTP success means the
event was stored; projection occurs asynchronously and remains observable.

The runtime also enqueues one tenant-scoped full completeness sweep for every
mapped Square location in each UTC day. The durable operation pins the exact
organization, connection, and binding, runs the same canonical path as the
operator action, and records the successful system reconciliation in the
health timeline. Provider or network failures use bounded exponential retry;
an expired read-only lease is safe to replay, while changed binding evidence
fails closed for operator review. Faster catalog, webhook, payment/refund,
checkout-abandonment, Loyalty, and DoorDash workers continue to repair their
own nonterminal domains between full sweeps.

## Admin endpoints

| Method | Path | Purpose |
| - | - | - |
| `POST` | `/locations/:id/integrations/square/oauth` | Start OAuth |
| `GET` | `/locations/:id/integrations/square` | Status, health, capabilities |
| `GET` | `/locations/:id/integrations/square/locations` | List Square locations |
| `POST` | `/locations/:id/integrations/square/locations` | Preview and confirm mapping |
| `POST` | `/locations/:id/integrations/square/catalog/import` | Import the catalog |
| `POST` | `/locations/:id/integrations/square/reconcile` | Run full reconciliation |
| `POST` | `/locations/:id/integrations/square/events/retry` | Retry failed webhook events |
| `DELETE` | `/locations/:id/integrations/square` | Disconnect after deactivation |

Disconnecting preserves canonical catalog and historical evidence. Active or
degraded commerce modules must be deactivated or rolled back first.

<Snippet file="need-help.mdx" />

### Confirm a location mapping

Use the existing location-binding POST endpoint with `squareLocationId` and
`preview: true` first. Show the returned Crave location, Square location, account
and blocker reasons to the merchant. After confirmation, POST the same
`squareLocationId` with the returned `confirmation` object (`connectionId`,
`bindingId`, `revisionToken`). A changed connection, mapping, policy or displayed
location requires a new preview. Direct saves without confirmation are rejected.
Mapping preparation does not establish menu-sync or routing activation readiness.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.