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 activate Menu Sync
Resolve catalog exceptions and activate a fresh, reviewed snapshot. Square owns price, tax,
discounts, availability, and schedule after activation.
4
Verify commerce readiness
Confirm checkout, webhook, and reconciliation health in the Dashboard before accepting traffic.
Delivery additionally requires explicit Square Delivery certification and DoorDash Drive
credentials.
Authority rules
- A connected and mapped Square location uses Square Payments. Stripe is not a fallback after Square has started a checkout.
- Crave never receives raw card or gift-card data. Square Web Payments returns a token that the server uses with the mapped seller and location.
- Square calculates the order using mapped catalog variations, automatic taxes, automatic discounts, service charges, and an optional order-linked Loyalty reward. A customer-entered Crave coupon is rejected for Square commerce.
- Staff tip is recorded on the final Square Payment. DoorDash courier tip and the authoritative Drive fee plus tax are Square Order service charges.
- Gift cards can partially authorize first; one final card, wallet, or stored
card pays the remaining balance. Saved cards require authenticated customer
ownership, buyer verification, and explicit consent. When a customer selects
a saved card, the storefront passes its opaque Card ID back to Square Web
Payments
Card.tokenizewith the current amount, currency, buyer contact,customerInitiated=true, andsellerKeyedIn=false. Only the resulting authenticated one-time payment token is used as the Square payment source; the deprecated separateverificationTokenfield is not part of the Crave payment contract. The selected Card ID remains server-side ownership evidence. The storefront sends the current versionedcardSaveConsentobject only after the customer selects “Save this card securely with Square for future orders.” Before calling SquareCreateCard, Crave writes immutable tenant-, customer-, connection-, and checkout-scoped consent evidence. Removing a saved card disables it in Square and records a separate revocation event. Crave stores a separate Square customer identity for each connected Square seller account, so cards and Loyalty never cross merchant boundaries when one Crave organization operates multiple Square accounts. - Authenticated customers can buy a new digital Square gift card in Crave. A non-gift-card Square payment must complete before activation; the card is linked to the same Square customer and its full number is returned once over a private, no-store response. Crave projections, logs, and webhook storage retain only safe IDs or redacted values.
- Full and partial refunds return to gift-card tenders first, then the remaining card or wallet tenders. Mixed outcomes are surfaced as action required.
- A refund of the payment that purchased a gift card triggers an idempotent
Square
ADJUST_DECREMENTactivity with reasonPURCHASE_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.
- Checkout reads the member quote from
GET .../loyalty/quote. A first-time member joins through the separate, explicitly consentedPOST .../loyalty/enrollmentmutation before earning can begin; applying a reward never enrolls a customer as a side effect. Enrollment, reward apply, and reward removal require the current cart revision and an idempotency key, and each refreshes the Square payment session before payment can continue. - Enrollment requires a phone that the active Crave customer has verified by
OTP. Checkout can add that factor to the current customer through
POST /customer/phone-verificationand confirm it throughPOST /customer/phone-verification/confirmation; an E.164-shaped profile value alone is not accepted as proof. Crave’s one-time verification consent 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 withRetrieveLoyaltyAccountand the reverse-chronological activity ledger withSearchLoyaltyEvents(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
AdjustLoyaltyPointswith 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_EFFECToperation; 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.
Delivery with DoorDash Drive
Delivery is fail-closed until the location has fresh capability evidence whose source issquare_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.
Apple Pay domains
Apple Pay requires the storefront’s exact HTTPS domain to be registered for this Square application. Crave proxies Square’s currentapple-developer-merchantid-domain-association file at
/.well-known/apple-developer-merchantid-domain-association without an
extension or long-lived cache. Then add the host under Apple Pay in Square
Developer Console, using Sandbox mode for a sandbox storefront and Production
mode for production. Apple Pay cannot be verified on localhost.
Webhooks
Create the Square subscription against: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:
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
Disconnecting preserves canonical catalog and historical evidence. Active or
degraded commerce modules must be deactivated or rolled back first.
Slack Community
Ask questions and get help from the Crave team and community.
Email Support
Reach out to hello@craveup.com for direct support.