ArchitectureEdge Functions

Edge Functions

Staccato uses two Supabase Edge Functions (Deno/TypeScript) to interact with Square’s API. This keeps Square API credentials server-side.

process-payment

Processes payments through Square’s Payments API.

Endpoint: POST /functions/v1/process-payment

Request

interface ProcessPaymentRequest {
  sourceId: string;         // Payment token (card nonce or Apple Pay token)
  amount: number;           // Amount in cents
  currency: string;         // "USD"
  idempotencyKey: string;   // UUID to prevent duplicate charges
  note?: string;            // Optional payment note
  referenceId?: string;     // Optional reference ID
}

Response

interface ProcessPaymentResponse {
  paymentId: string;    // Square payment ID
  orderId?: string;     // Square order ID (if created)
  status: string;       // "COMPLETED", "PENDING", etc.
  amount: number;       // Amount charged (cents)
  currency: string;     // "USD"
}

cURL Example

curl -X POST \
  'https://YOUR-PROJECT.supabase.co/functions/v1/process-payment' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer YOUR_ANON_KEY' \
  -d '{
    "sourceId": "cnon:card-nonce-ok",
    "amount": 495,
    "currency": "USD",
    "idempotencyKey": "unique-key-123",
    "note": "Caffe Latte"
  }'

Flow

  1. iOS app collects payment source (card nonce or Apple Pay token)
  2. Calls Edge Function with payment details
  3. Edge Function validates configuration and request
  4. Creates payment via Square Payments API
  5. Returns payment result to iOS app

sync-square-order

Syncs orders from the Supabase database to Square POS for staff visibility.

Endpoint: POST /functions/v1/sync-square-order

Request

interface SyncSquareOrderRequest {
  orderId: string;           // Supabase order ID
  orderNumber: string;       // Display number (e.g., "SC-A042")
  items: SyncOrderItem[];    // Order line items
  subtotal: number;          // In cents
  tax: number;
  tip: number;
  total: number;
  idempotencyKey: string;
}
 
interface SyncOrderItem {
  name: string;
  quantity: number;
  unitPrice: number;         // In cents
  totalPrice: number;
  notes?: string;
  modifiers: SyncItemModifier[];
}
 
interface SyncItemModifier {
  name: string;
  priceAdjustment: number;   // In cents
}

Response

interface SyncSquareOrderResponse {
  squareOrderId: string;     // Square order ID
}

Flow

  1. After order is created in Supabase, OrderService calls this function
  2. Edge Function transforms items to Square line item format
  3. Creates order in Square with location, items, and tip as service charge
  4. Returns Square order ID, which is saved back to the order record
  5. Non-blocking: If sync fails, the order still succeeds in Supabase

Shared Utilities

_shared/square-client.ts

  • SquareClient class for making authenticated requests to Square API
  • Handles createPayment() and createOrder() calls
  • Types: SquarePaymentRequest, SquareOrderRequest, SquareLineItem, SquareModifier

_shared/cors.ts

  • CORS headers for cross-origin requests from the iOS app

Environment Variables

Set via supabase secrets set:

VariablePurpose
SQUARE_ACCESS_TOKENSquare API access token
SQUARE_LOCATION_IDSquare location ID

Deployment

# Deploy both functions
supabase functions deploy process-payment
supabase functions deploy sync-square-order
 
# View logs
supabase functions logs process-payment
supabase functions logs sync-square-order