Skip to main content
Version: 1.0.0
Created: 2026-02-23
Updated: 2026-02-24
Status: 🏗️ Scaffolded (Phase 1 — gateway integration pending sandbox credentials)
Owner: FA (Finance & Accounting)

Overview

This document defines the integration contract between Encore OS’s FA module and Ramp for corporate card and spend management. Ramp provides spend management, corporate cards, ERP/accounting sync (vendors, transaction coding, payables), and an open developer API. This integration enables syncing card transactions into Encore OS for coding, approval workflows, and reconciliation.

Quick Reference


Decision Trees / Pattern Library

  • OAuth vs API key: Use OAuth when the Connect UX involves user authorization in the browser (recommended per Ramp guide). Use API key for server-only or headless sync when OAuth is not required.
  • Pagination: Ramp list endpoints use limit/page or cursor; loop until all pages are fetched for the org’s date range. See v1/pagination.
  • Deduplication: Use fa_card_transactions.ramp_transaction_id as unique key; unique index on that column. On conflict, skip or update per product requirement (spec recommends skip for idempotency).

Common Mistakes


Pre-Flight Checklist

  • Env vars set: RAMP_CLIENT_ID, RAMP_CLIENT_SECRET, RAMP_API_KEY (if used), RAMP_WEBHOOK_SECRET, RAMP_ENVIRONMENT.
  • DB index on fa_card_transactions.ramp_transaction_id for deduplication.
  • Test sandbox connection (request access via Ramp partnerships intake) before production.

Integration Pattern

Type: External API Integration via Edge Functions
Direction: Outbound (Encore OS → Ramp) + Inbound (Webhooks if supported by Ramp)
Authentication: OAuth (recommended for Connect UX) and/or API key; see Ramp docs.ramp.com/developer-api/v1/guides/oauth

Authentication Requirements

Environment Matrix

Credentials

Exact auth mechanism (OAuth scopes, API key headers) MUST be confirmed from live Ramp API documentation at docs.ramp.com/developer-api.

API Endpoints

Ramp API (Outbound)

Reference: docs.ramp.com/developer-api Implementation must use the live API reference for exact paths, methods, request/response schemas, pagination parameters, and webhook payload/shape.

Edge Functions (Inbound/Internal)


Transactions Sync (Pagination and Deduplication)

  • Pagination: Cursor-based: page_size (2-100, default 20) + start (ID of last entity). Loop until no more results. See v1/pagination. Confirmed 2026-02-24.
  • Deduplication: Use Ramp transaction ID as unique key; unique index on fa_card_transactions.ramp_transaction_id. On conflict (same ramp_transaction_id), either skip or update existing row per product requirement (spec recommends skip for idempotency).
  • Incremental sync: If Ramp supports filtering by updated_at or similar, use it to reduce payload; otherwise full date-range fetch with deduplication is acceptable for Phase 1.

Data Flow


Webhook Events

Ramp supports webhooks (see v1/api/webhooks). Implementation must confirm the following from live docs:
  • Signature verification: Implement per Ramp’s webhook docs (e.g. HMAC, webhook secret header, or JWT); store RAMP_WEBHOOK_SECRET in Supabase secrets.
  • Replay protection: Use timestamp window if Ramp provides one (e.g. reject if t outside ±3 min).
  • Event types: e.g. transaction.created, connection/revoked – document exact event names and payload fields when implementing; map to actions below.
  • Actions: Update connection status, trigger incremental sync, or mark transactions; never log full tokens or card numbers.
  • Retries: Ramp retries webhook delivery up to 10 times for 429/5xx responses. Endpoint must respond within 10 seconds. Implement idempotency using event id to handle duplicate deliveries. Confirmed 2026-02-24.

Database Schema

New Tables

fa_ramp_connections
  • id UUID PK
  • organization_id UUID FK, UNIQUE (one connection per org)
  • Ramp entity/account identifier(s)
  • Token columns (encrypted at rest) or reference to secrets
  • connection_status TEXT – connected | disconnected | error | reauth_required
  • last_synced_at TIMESTAMPTZ
  • created_at, updated_at
  • RLS via SECURITY DEFINER helper on organization_id
fa_card_transactions
  • id UUID PK
  • organization_id UUID FK
  • ramp_connection_id UUID FK
  • ramp_transaction_id TEXT UNIQUE (deduplication)
  • Amount, currency, date, merchant, status, etc. (match Ramp API response)
  • GL/vendor coding columns (nullable)
  • created_at, updated_at
  • RLS on organization_id
  • Unique index on ramp_transaction_id

Modified Tables

fa_module_settings
  • ramp_integration_enabled BOOLEAN DEFAULT false

Security Considerations

Token Storage

  • App-level credentials (RAMP_CLIENT_ID, RAMP_CLIENT_SECRET, RAMP_WEBHOOK_SECRET) are stored in Supabase Secrets.
  • Per-organization OAuth tokens (access_token, refresh_token) are stored in encrypted DB columns scoped by organization_id (not in shared Supabase Secrets).
  • Tokens are never exposed to frontend.
  • Edge functions access per-org tokens via service-role queries filtered by organization_id.

Multi-Tenancy

  • All Edge Function queries include organization_id filter
  • RLS policies on fa_ramp_connections and fa_card_transactions enforce organization isolation
  • Audit logging for connect, sync, disconnect, and webhook events

PHI/PII

  • Card transaction metadata (merchant, amount) is not PHI
  • Do not send or log PHI to Ramp; do not log full card numbers or tokens

Error Handling

Ramp API Errors

Retry Strategy

  • Exponential backoff for 429 and 5xx uses 1s, 2s, 4s, 8s, 16s; any Retry-After header takes precedence.
  • Do not retry 4xx (except 429) indefinitely.
  • Rate limit: 200 requests per 10-second rolling window (confirmed from Ramp docs 2026-02-24). Apply the same backoff sequence above on 429 responses.
  • Align with FA-20 Plaid pattern: same backoff array and break on non–rate-limit errors.

Logging

Allowlisted Fields

  • organization_id
  • ramp_connection_id (not tokens)
  • transactions_synced, transactions_skipped
  • sync_duration_ms
  • Webhook event type (not payload secrets)

Prohibited

  • access_token, refresh_token, API keys
  • Full card numbers or sensitive merchant PII

Testing Strategy

  • Unit: Ramp client and transaction mapping (mocked responses); webhook signature verification with test secret.
  • Integration: Connect and sync against Ramp sandbox (request access via Ramp Partnerships Intake); test pagination, date-range filter, and deduplication.
  • E2E: Connect → Sync → View transactions (when UI exists).
  • RLS: Verify tenant isolation on fa_ramp_connections and fa_card_transactions.

Implementation Confirmation Checklist

Before marking integration complete, confirm with live Ramp docs and sandbox:
  • OAuth: scopes, token refresh, and redirect/callback URL requirements.
  • Transactions: exact path, query params (date range, status, limit, page/cursor), response schema; map all required fields to fa_card_transactions.
  • Webhooks: event types, payload shape, signature algorithm and header; implement verification and idempotent handling.
  • Rate limit: 200 requests per 10-second rolling window (confirmed 2026-02-24); honor Retry-After header.
  • Sandbox: request and obtain sandbox credentials; document test entity/card data if provided.

Rollback Strategy

  • Feature flag ramp_integration_enabled disables UI and sync
  • Disabling flag hides Ramp options; existing data remains; no destructive migration required
  • Optional: soft-delete or status column on fa_ramp_connections for reversible disconnect

References