diff --git a/apps/www/src/app/products/hosted-checkout/page.tsx b/apps/www/src/app/products/hosted-checkout/page.tsx new file mode 100644 index 0000000..9363a3b --- /dev/null +++ b/apps/www/src/app/products/hosted-checkout/page.tsx @@ -0,0 +1,82 @@ +import { ProductStoryLayout } from "@/components/stories/ProductStoryLayout"; + +const features = [ + "Embed via URL or iframe — no SDK required", + "Auto-applies your logo, brand color, company name", + "Customer picks payment method; you settle in one asset", + "Idempotent re-render: customer can refresh during sign without losing state", + "Webhook on every state change", +]; + +const apiRequest = `POST /v1/checkout/sessions +{ + "amount": 100.00, + "currency": "USD", + "success_url": "https://yourapp.com/thanks", + "metadata": { "order_id": "ord_123" } +}`; + +const apiResponse = `→ { "url": "https://checkout.useroutr.com/cs_abc123" }`; + +export const metadata = { + title: "Hosted Checkout — Useroutr", + description: + "A drop-in payment page that accepts USDC on five chains, cards via Stripe, bank transfers via ACH or SEPA, and fiat on-ramp through MoneyGram.", +}; + +export default function HostedCheckoutPage() { + return ( + + {/* Hero */} +
+
+

+ Hosted Checkout +

+

+ Branded checkout. +
+ One URL. +

+

+ A drop-in payment page that accepts USDC on five chains, cards via + Stripe, bank transfers via ACH or SEPA, and fiat on-ramp through + MoneyGram. The customer never leaves your brand. +

+
+
+ + {/* Features */} +
+
+

+ What's included +

+
    + {features.map((f) => ( +
  • + + {f} +
  • + ))} +
+
+
+ + {/* API example */} +
+
+

+ API example +

+
+            {apiRequest}
+          
+
+            {apiResponse}
+          
+
+
+
+ ); +} diff --git a/apps/www/src/app/products/invoicing/page.tsx b/apps/www/src/app/products/invoicing/page.tsx new file mode 100644 index 0000000..573f805 --- /dev/null +++ b/apps/www/src/app/products/invoicing/page.tsx @@ -0,0 +1,92 @@ +import { ProductStoryLayout } from "@/components/stories/ProductStoryLayout"; + +const features = [ + "PDF + hosted page generated from the same JSON", + "Line items, taxes, discounts, partial payments", + "Multi-currency: invoice in EUR, settle in USDC", + "Automatic dunning: reminders at +3, +7, +14 days overdue", + "Webhook on invoice.paid, invoice.overdue, invoice.cancelled", + "CSV export for accountants", +]; + +const apiRequest = `POST /v1/invoices +{ + "customer_email": "ap@acme.com", + "customer_name": "Acme Inc.", + "line_items": [ + { "description": "April retainer", "qty": 1, "unit_price": 5000, "amount": 5000 } + ], + "currency": "USD", + "due_date": "2026-05-31" +}`; + +const apiResponse = `→ { + "id": "inv_abc123", + "invoice_number": "INV-2026-042", + "pdf_url": "https://...", + "pay_url": "https://pay.useroutr.com/inv_abc123" +}`; + +export const metadata = { + title: "Invoicing — Useroutr", + description: + "Send a PDF invoice with a payment URL baked in. Customer pays in USDC, card, or bank transfer — you reconcile automatically.", +}; + +export default function InvoicingPage() { + return ( + + {/* Hero */} +
+
+

+ Invoicing +

+

+ Invoices that get paid. +
+ In minutes, not weeks. +

+

+ Send a PDF invoice with a payment URL baked in. Customer pays in + USDC, card, or bank transfer — you reconcile automatically. Built + for B2B teams that hate Stripe-style “click here to enable + Treasury.” +

+
+
+ + {/* Features */} +
+
+

+ What's included +

+
    + {features.map((f) => ( +
  • + + {f} +
  • + ))} +
+
+
+ + {/* API example */} +
+
+

+ API example +

+
+            {apiRequest}
+          
+
+            {apiResponse}
+          
+
+
+
+ ); +} diff --git a/apps/www/src/app/products/page.tsx b/apps/www/src/app/products/page.tsx new file mode 100644 index 0000000..1b58e03 --- /dev/null +++ b/apps/www/src/app/products/page.tsx @@ -0,0 +1,90 @@ +import Link from "next/link"; +import { ArrowRight } from "lucide-react"; +import { PageShell } from "@/components/site/PageShell"; +import type { Metadata } from "next"; + +const products = [ + { + label: "Hosted checkout", + description: "Stripe-style branded checkout. USDC + card + bank, one URL.", + href: "/products/hosted-checkout", + }, + { + label: "Pay by link", + description: "One-link payment requests. No code, no checkout to build.", + href: "/products/pay-by-link", + }, + { + label: "Invoicing", + description: "Send a PDF invoice, get paid in USDC or fiat.", + href: "/products/invoicing", + }, + { + label: "Global payouts", + description: "Bulk disbursements to 174 countries.", + href: "/products/payouts", + }, +]; + +export const metadata: Metadata = { + title: "Products — Useroutr", + description: + "One engine. Four ways to use it. Accept, route, settle, and notify — pick the surface that fits your business.", + alternates: { canonical: "/products" }, +}; + +export default function ProductsIndexPage() { + return ( + +
+ {/* Hero */} +
+

+ Products +

+

+ One engine. +
+ Four ways to use it. +

+

+ The same primitives — accept, route, settle, notify — power every + product on Useroutr. Pick the surface that fits your business. +

+
+ + {/* Product cards */} +
+
+ {products.map((p) => ( + +
+

+ Useroutr +

+

+ {p.label} +

+

+ {p.description} +

+
+
+ Learn more + +
+ + ))} +
+
+
+
+ ); +} diff --git a/apps/www/src/app/products/pay-by-link/page.tsx b/apps/www/src/app/products/pay-by-link/page.tsx new file mode 100644 index 0000000..4a8b9bc --- /dev/null +++ b/apps/www/src/app/products/pay-by-link/page.tsx @@ -0,0 +1,88 @@ +import { ProductStoryLayout } from "@/components/stories/ProductStoryLayout"; + +const features = [ + "Fixed amount, open amount, or pick-from-list", + "Single-use or multi-use links", + "Custom expiry windows", + "Per-link conversion stats (views vs. payments)", + "QR code generated automatically", + "Works with any payment method the customer picks", +]; + +const apiRequest = `POST /v1/payment-links +{ + "amount": 25, + "currency": "USD", + "description": "Coffee subscription · April", + "single_use": false, + "expires_at": "2026-06-01T00:00:00Z" +}`; + +const apiResponse = `→ { + "id": "lnk_abc123", + "url": "https://pay.useroutr.com/abc12345", + "qr_code_url": "data:image/png;base64,..." +}`; + +export const metadata = { + title: "Pay by Link — Useroutr", + description: + "Generate a payment URL with one API call. Share it on email, Slack, WhatsApp, an invoice, or a QR code.", +}; + +export default function PayByLinkPage() { + return ( + + {/* Hero */} +
+
+

+ Pay by Link +

+

+ The link is +
+ the integration. +

+

+ Generate a payment URL with one API call (or one button in the + dashboard). Share it on email, Slack, WhatsApp, an invoice, or a QR + code. Customers pay — you get a webhook. +

+
+
+ + {/* Features */} +
+
+

+ What's included +

+
    + {features.map((f) => ( +
  • + + {f} +
  • + ))} +
+
+
+ + {/* API example */} +
+
+

+ API example +

+
+            {apiRequest}
+          
+
+            {apiResponse}
+          
+
+
+
+ ); +} diff --git a/apps/www/src/app/sitemap.ts b/apps/www/src/app/sitemap.ts index 6847ae2..68dc71f 100644 --- a/apps/www/src/app/sitemap.ts +++ b/apps/www/src/app/sitemap.ts @@ -4,6 +4,13 @@ const baseUrl = "https://useroutr.com"; const useCases = ["marketplaces", "fintech", "ecommerce", "payouts"]; +const productPages = [ + "hosted-checkout", + "pay-by-link", + "invoicing", + "payouts", +]; + export default function sitemap(): MetadataRoute.Sitemap { const now = new Date(); @@ -14,6 +21,18 @@ export default function sitemap(): MetadataRoute.Sitemap { changeFrequency: "weekly", priority: 1, }, + { + url: `${baseUrl}/products`, + lastModified: now, + changeFrequency: "monthly", + priority: 0.9, + }, + ...productPages.map((slug) => ({ + url: `${baseUrl}/products/${slug}`, + lastModified: now, + changeFrequency: "monthly" as const, + priority: 0.85, + })), { url: `${baseUrl}/use-cases`, lastModified: now, diff --git a/apps/www/src/components/v2/Footer.tsx b/apps/www/src/components/v2/Footer.tsx index 0f12806..f22f9df 100644 --- a/apps/www/src/components/v2/Footer.tsx +++ b/apps/www/src/components/v2/Footer.tsx @@ -12,10 +12,10 @@ const columns: { title: string; links: LinkItem[] }[] = [ { title: "Product", links: [ - { label: "Hosted checkout", href: "/#product" }, - { label: "Pay by link", href: "/#product" }, - { label: "Invoices", href: "/#product" }, - { label: "Global payouts", href: "/#product" }, + { label: "Hosted checkout", href: "/products/hosted-checkout" }, + { label: "Pay by link", href: "/products/pay-by-link" }, + { label: "Invoices", href: "/products/invoicing" }, + { label: "Global payouts", href: "/products/payouts" }, { label: "Pricing", href: "/pricing" }, ], },