Skip to main content

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.com
  • connect.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 ListPayments using watermark checkpoint (clamped to now())
  • 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_raw rows where processed=false within the last 7 days
  • caps at 200 events per run
  • routes by provider to processSquareWebhook or processCloverWebhook
  • 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).

Deep Dives

Written byDhruv Doshi