Square Integration
Square POS is used for in-store operations at Dungeon Books (115 Brunswick St, Jersey City). Multiple projects integrate with Square APIs.
APIs Used
| API | Used By | Purpose |
|---|---|---|
| Catalog API | webshop, store | Product catalog (synced with POS) |
| Inventory API | webshop, store | Real-time stock levels |
| Orders API | webshop | Full order lifecycle |
| Payments API | webshop | Process payments (Web Payments SDK) |
| Locations API | webshop | In-store pickup availability |
Store Rebuild: Sync Architecture
In the store-rebuild, Square is no longer the commerce backend — Saleor is. Square remains the POS system with bidirectional inventory sync:
- Square → Saleor: POS sale triggers webhook → sync app decrements Saleor stock (< 5 sec)
- Saleor → Square: Online order triggers webhook → sync app decrements Square stock
- Shared key: ISBN (Square GTIN ↔ Saleor variant SKU)
- Nightly reconciliation: cron job detects discrepancies > 2 units, alerts
Dead-lettered events stored in Postgres for retry. Structured logging with pino for audit trail.
Product Migration
~1,700 products migrated from Square Catalog → Saleor via store/scripts/migrate-products.ts:
- Maps Square categories to Saleor product types
- Enriches books with Open Library metadata (author, publisher, page count)
- Batch creates in Saleor (50 at a time)
- Supports
--dry-run,--update,--limit
Guild: Membership & Loyalty Integration
In guild, Square is the cash register — we integrate with it, not build on it. Payload CMS owns member identity and loyalty state.
| API | Purpose |
|---|---|
| Customers API | Link Square customer ID to Payload member |
| Customer Custom Attributes API | Push tier, points, and status to POS customer profile |
| Orders API / Webhooks | Receive payment.updated → log purchase → award loyalty points |
Custom Attributes
Four attributes namespaced to the Guild app (not customer notes — safe for shops that use notes):
| Key | Display | Example |
|---|---|---|
guild_tier | Guild Tier | "Gold" |
guild_points | Guild Points | "1,500 ($15.00)" |
guild_status | Membership Status | "active" |
guild_member_id | Guild Member ID | "42" |
Synced after: purchase (Square webhook), subscription change (Stripe webhook), point redemption.
What We Don’t Use
- Square Loyalty API — we own loyalty logic
- Square Subscriptions API — billing is via Stripe
- Square customer notes — reserved for staff use, not safe to overwrite for other shops
Related
- store-rebuild — ecommerce architecture (Medusa sync)
- guild — membership & loyalty platform
- webshop — legacy Square-as-backend approach