From Payrexx checkout to a deployed Swiss-sovereign SaaS in under an hour. Same Next.js you already know — wired against a Swiss + European stack.
You need these installed before you start. All free.
node --versionnpm i -g pnpmbrew install supabase/tap/supabaseCloud accounts: Payrexx (free, Swiss), Infomaniak (CHF 6/mo SMTP), Exoscale (free credit), plus optional Matomo Cloud (or self-host on the same Exoscale VM). All Swiss / EU. No US sign-up needed.
Buy a Solo (CHF 199) or Team (CHF 399) licence at already-ch.wait-what.shop/#buy-solo. Payrexx handles the checkout — pay with TWINT, PostFinance, Visa, Mastercard, AmEx, Apple Pay, or Google Pay. Swiss VAT (8.1%) is invoiced automatically.
Within 1–2 minutes you'll get a GitHub repository invite via Infomaniak SMTP. Accept it, then click "Use this template" on the private already-ch-template repo to create your own copy.
git clone https://github.com/YOUR_USERNAME/YOUR_REPO_NAME
cd YOUR_REPO_NAME
pnpm install
Copy the example file and fill it in:
cp .env.example .env.local
The minimum to boot locally:
supabase startSee full env vars reference below.
supabase start
pnpm dev
This boots Next.js on localhost:3000, local Supabase on 54322/54323, and the Payrexx webhook tunnel via the included ngrok config. Hit localhost:3000/health to confirm DB + Redis connections.
Already CH ships a Docker-based deploy flow. Two paths:
Spin up a CHF-billed VM from the pre-built QCOW2 image:
exo compute instance create my-app \
--template "already-ch-coolify" \
--zone ch-gva-2 \
--instance-type standard.medium
The cloud-init script pulls Coolify, wires Caddy with MaxMind GeoIP2 (sets x-geo-country), and seeds the service stack. SSH in, point Coolify at your GitHub repo, click deploy.
If you already run Coolify, import infra/coolify/services.json. The stack defines Next.js, Postgres, Redis, Matomo, GlitchTip, Unleash, and Caddy with sensible defaults.
Payrexx replaces Stripe. Two big differences to keep in mind:
referenceId set to orgId during checkout. Webhooks look up the org by that field.config/billing.ts — duplicates make plan derivation ambiguous.Webhooks are idempotent via the payment_events table. Failed events route to payment_events_failed for /debug-webhook.
// config/billing.ts
export const billingConfig = {
currency: 'CHF',
vatRate: 0.081, // Swiss VAT 8.1%
plans: {
solo: { amount: 19900, gateway: 'pop-up-solo' },
team: { amount: 39900, gateway: 'pop-up-team' },
},
};
Transactional email goes through Infomaniak's Swiss-hosted SMTP. Use nodemailer via lib/messaging/index.ts — never call nodemailer directly. The notify(userId, ...) helper handles channel routing (email, in-app, both).
SMTP_HOST=mail.infomaniak.com
SMTP_PORT=587
SMTP_USER=your-infomaniak-mailbox
SMTP_PASS=your-app-password
SMTP_FROM="Already CH <noreply@your-domain.ch>"
Exoscale runs the whole stack in Geneva (ch-gva-2) or Zurich (ch-dk-2). Coolify on top gives you push-to-deploy without locking into Vercel.
Matomo runs cookie-free on the same Exoscale VM as the app. Because it stores no cookies and uses a daily-rotating fingerprint, no consent banner is required under nFADP or GDPR.
NEXT_PUBLIC_MATOMO_URL=https://analytics.your-domain.ch
NEXT_PUBLIC_MATOMO_SITE_ID=1
The tracker lives in components/providers/analytics-provider.tsx and only runs in production.
Every personal-data processing activity should appear in the data_processing_activities table. The admin UI lives at /admin/data-register and follows the structure required by Art. 12 nFADP (controller, purposes, legal basis, recipients, retention period, transfers, security measures).
Seed entries for Payrexx, Infomaniak, Supabase, Matomo, and GitHub are pre-loaded. Edit them to match your actual processing, then export the register as PDF for your DPO.
Public (build-time, baked into the bundle):
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYNEXT_PUBLIC_MATOMO_URLNEXT_PUBLIC_MATOMO_SITE_IDNEXT_PUBLIC_FRIENDLY_CAPTCHA_SITE_KEYServer-only (inject from macOS Keychain via ~/.keychain-secrets.sh, never put in .env):
DATABASE_URL, DATABASE_URL_DIRECTSUPABASE_SERVICE_ROLE_KEYPAYREXX_API_KEY, PAYREXX_WEBHOOK_SECRETSMTP_PASSMISTRAL_API_KEY (primary AI provider)UNLEASH_API_TOKENGLITCHTIP_DSNCRON_SECRET, BETTER_AUTH_SECRETpnpm dev — Next.js + local Supabase + Caddy reverse proxypnpm test — Vitest unit + integrationpnpm test:e2e — Playwrightpnpm db:migrate — apply Drizzle migrationspnpm db:seed — synthetic test datapnpm already doctor — verify env vars, DB, Payrexx connectionpnpm build — Docker-style standalone build for Coolify16 modules ship in Already CH. Same scope as already, with Swiss-stack defaults.