From ad4f614130c3c839998e15e6cbe8150a842354f5 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 27 May 2026 20:45:25 +0200 Subject: [PATCH] Phase8: Auto bill credit card --- src/app/[locale]/settings/billing/page.tsx | 26 +++------------------- src/lib/db.ts | 2 +- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/app/[locale]/settings/billing/page.tsx b/src/app/[locale]/settings/billing/page.tsx index 91622af..0c73be5 100644 --- a/src/app/[locale]/settings/billing/page.tsx +++ b/src/app/[locale]/settings/billing/page.tsx @@ -1,26 +1,6 @@ import { redirect, notFound } from "next/navigation"; import { getTranslations } from "next-intl/server"; import { getSessionUser } from "@/lib/session"; -import { getOrgBilling } from "@/lib/db"; -import { BillingSettingsForm } from "@/components/settings/billing-form"; - -/** - * /settings/billing — customer-side billing details management. - * - * Owner-only by visibility: non-owner members get a 404 (same - * response as if the page didn't exist). The link to this page - * is also hidden from non-owners on /billing and elsewhere, but - * the page itself enforces too — a non-owner who learns the URL - * still gets 404, not 403, so the page's existence doesn't leak. - * - * First-time visitors see an empty form. Subsequent visits see - * the current values, editable. Save creates or updates via the - * shared upsert path; the row's existence drives whether the - * monthly issuance cron will pick this org up. - */ -import { redirect, notFound } from "next/navigation"; -import { getTranslations } from "next-intl/server"; -import { getSessionUser } from "@/lib/session"; import { getOrgBilling, getOrgBillingConfig } from "@/lib/db"; import { BillingSettingsForm } from "@/components/settings/billing-form"; import { SavedCardSection } from "@/components/settings/saved-card-section"; @@ -40,9 +20,9 @@ import { SavedCardSection } from "@/components/settings/saved-card-section"; * monthly issuance cron will pick this org up. * * Phase 9: also renders the saved-card section (Set up auto-pay / - * Visa •••• 4242, expires 05/27 / Update card / Disable auto-pay / - * Remove card) when billing info is on file, plus a footer note - * explaining that bank transfer is available on request. + * Visa dot-dot-dot 4242, expires MM/YY / Update card / Disable + * auto-pay / Remove card) when billing info is on file, plus a + * footer note explaining that bank transfer is available on request. */ export default async function BillingSettingsPage() { const user = await getSessionUser(); diff --git a/src/lib/db.ts b/src/lib/db.ts index b857861..03b05eb 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -421,7 +421,7 @@ const MIGRATION_SQL = ` created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); - -- Phase 9: saved-card columns. The PaymentMethod id (`pm_xxx`) + -- Phase 9: saved-card columns. The PaymentMethod id ('pm_xxx') -- is the handle for off-session charges; brand/last4/exp are -- display fields. No PAN, CVV, or anything PCI-scope — Stripe -- holds those. The columns are nullable because a fresh org has