Architecture

Setula uses a two-tier deployment architecture with a Next.js frontend on Vercel and a Node.js backend on Railway. The frontend proxies all API and payment-demo requests to the backend through Next.js rewrites, keeping the browser on a single origin.

Deployment architecture

text
Browser ──→ Vercel (Next.js landing page)
              │  /pay/*  ──→ Railway backend (Node.js HTTP server)
              │  /api/*  ──→ Railway backend
              │
              └── Next.js rewrites proxy to DEMO_BACKEND_ORIGIN

Data flow

text
Next.js frontend → Setula backend → Circle Wallets → Arc Testnet → simulated payout provider

Frontend (Vercel)

  • Framework: Next.js 16 (App Router, Turbopack)
  • UI: React 19 with CSS custom properties
  • Routing: Landing page at /, payment demo proxied at /pay
  • API proxy: Next.js rewrites() forwards /api/* and /pay/* to the backend
  • Deployment: Vercel, with DEMO_BACKEND_ORIGIN as the only sensitive env var

Backend (Railway)

  • Runtime: Node.js 22 with TypeScript (run via tsx)
  • HTTP server: Raw node:http — no Express or framework
  • Validation: Zod 4 for request schemas and env parsing
  • Persistence: Atomic JSON file (.setula-data.json)
  • State machine: Enforces valid payment status transitions
  • Idempotency: All POST endpoints require an Idempotency-Key header
  • CORS: Configurable via CORS_ORIGIN env var; not needed in normal flow due to the proxy
  • Deployment: Railway, with all Circle credentials and secrets server-side

Settlement layer

  • Circle SDK: @circle-fin/developer-controlled-wallets v10.8
  • Wallet type: Developer-controlled EOAs on Arc Testnet
  • Transfer: USDC transfer from sender wallet to recipient wallet
  • Polling: Circle transaction status polled until COMPLETE
  • Evidence: Transaction hash stored and linked to ArcScan
  • Balance check: Sender balance verified before transfer submission

Simulated fiat rails

  • AED funding: Simulated — no real fiat collected
  • Quote: Fixed sandbox rate of 22.75 INR/AED
  • INR payout: Simulated callback — no real INR bank transfer
!

Production note: Licensed UAE funding and India payout partners would replace the simulated fiat rails in production. KYC/KYB controls and legal approval would be required in both jurisdictions.

Diagram

Setula architecture diagram

Security model

  • Circle API keys and entity secret are stored only on Railway (server-side env vars).
  • The payout callback secret (PAYOUT_CALLBACK_SECRET) is shared only between the backend and the payout provider.
  • The Vercel frontend receives only DEMO_BACKEND_ORIGIN — the backend URL.
  • No personal data or invoice details are written to the blockchain.
  • The Arc transaction hash is the only on-chain artifact — used solely for settlement proof.
  • Fiat payout confirmation is independent of chain settlement — a callback with a shared secret is required for DELIVERED.

Technology stack

CategoryTechnology
LanguageTypeScript 7
RuntimeNode.js 22
FrontendNext.js 16 (App Router), React 19, CSS
Backend HTTPnode:http (no framework)
ValidationZod 4
Build (browser)esbuild
Runtime (TS)tsx
Blockchain SDKCircle Developer-Controlled Wallets 10.8
NetworkArc Testnet
Settlement assetUSDC
Hosting (frontend)Vercel
Hosting (backend)Railway
TestingVitest 4 (16 tests)