orvacon

Adapters

Bring-your-own-database and the framework bridge.

Adapters bridge orvacon to your infrastructure. There are two kinds — a database adapter (where orvacon persists payments, events, and the ledger) and a framework adapter (the HTTP glue).

Database — bring your own

orvacon imposes no database. You pass a DatabaseAdapter; the core does every read and write through it, inside the transactions it asks for, so a state transition and its ledger row commit together — there is never a half-applied state.

Supabase / Postgres

@orvacon/adapter-supabase connects directly to Postgres (transactions, advisory locks) and pairs with a generated schema carrying default-deny row-level security.

lib/orva.ts
import { supabaseAdapter } from "@orvacon/adapter-supabase";
import postgres from "postgres";

// `prepare: false` is load-bearing behind a serverless pooler (Supabase, PgBouncer).
const sql = postgres(process.env.SUPABASE_DB_URL!, { prepare: false });
const database = supabaseAdapter({ sql });

Generate the schema + RLS migration with the CLI:

npx orvacon generate --write   # → supabase/migrations/<timestamp>_orvacon.sql

The RLS keys off each payment's userId (e.g. a Supabase auth.uid()). A guest payment has no owner and is visible only to the server (the service role / direct connection) — auth.uid() = null never matches a row, a deliberate posture. Any Postgres works underneath: Supabase, Neon, RDS, or your own; a Drizzle ORM adapter is on the roadmap.

Framework — Next.js

@orvacon/adapter-nextjs turns orvacon into App Router route handlers — the gateway-callback route, with signed-webhook delivery drained through after().

app/api/orva/callback/[connector]/route.ts
import { toNextJsHandler } from "@orvacon/adapter-nextjs";
import { orva } from "@/lib/orva";

export const { POST } = toNextJsHandler(orva, {
  returnUrl: { success: "/checkout/done", failure: "/checkout/failed" },
});

The finalize and state writes settle before the browser is redirected, so the user lands on the real outcome; the signed outbound webhook is drained in the background.

Make the callback route public

The gateway redirects the browser to this route with no session — exclude /api/orva/callback from your middleware, or an auth check silently strands payments.

The core itself is framework-agnostic — it speaks Web-standard Request/Response via toWebHandler, so other framework adapters are a thin wrapper; v1 ships the Next.js one.

On this page