OAuth & Webhook Flows
This page describes implemented flows in apps/api and apps/web.
Square Connect Flow
OAuth State Security
State is HMAC-signed and expiring (10-minute TTL), not trusted blindly.
If state validation fails, callback redirects with failure diagnostics.
OAuth Host Safety
Authorization URL host is hard-guarded to:
connect.squareupsandbox.comconnect.squareup.com
Web client also validates/normalizes URL before redirect.
Webhook Flow
Route: POST /api/v1/webhooks/square
This is a fast-ack model with asynchronous processing to keep provider retries low.
Poll Fallback
Route: POST /api/v1/internal/cron/square-poll-payments
- protected by
X-Cron-Secret - scans active Square connections
- refreshes expiring access tokens when needed (180s buffer)
- calls
ListPaymentsusing watermark checkpoint (clamped tonow()) - executes same ingestion path as webhooks
Webhook Retry Sweeper
Route: POST /api/v1/internal/cron/process-pending-webhooks
- protected by
X-Cron-Secret - scans
pos_webhook_events_rawrows whereprocessed=falsewithin the last 7 days - caps at 200 events per run
- routes by provider to
processSquareWebhookorprocessCloverWebhook - both processors are idempotent; safe to retry
This is the recovery path when async webhook processing fails after the raw event is stored. It is the only recovery path for Clover (which has no ListPayments-equivalent poll).
Clover Integration
Clover OAuth, webhook receive, and ingestion are fully implemented. See POS Integrations for the full details (notification-only webhook payloads, REST payment fetch, signature verification fail-closed in production, multi-merchant rejection).