diff --git a/.env.example b/.env.example index 17e2dea..fc18e3c 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,14 @@ NOMBA_PARENT_ACCOUNT_ID= NOMBA_CLIENT_ID= NOMBA_CLIENT_SECRET= +# Sandbox connectivity checks (POST /v1/sandbox/nomba/*) — always used +# instead of the vars above, regardless of what those point at. Lets you +# verify the Nomba integration works even when NOMBA_CLIENT_ID/SECRET above +# have been switched to live credentials. +NOMBA_SANDBOX_BASE_URL=https://sandbox.nomba.com +NOMBA_TEST_CLIENT_ID= +NOMBA_TEST_CLIENT_SECRET= + # Inbound webhook signature verification (Nomba → Somba) WEBHOOK_SIGNING_SECRET= diff --git a/README.md b/README.md index 8c34c7b..a367ea4 100644 --- a/README.md +++ b/README.md @@ -44,12 +44,13 @@ It shows the entry points, the outbox, relay shards, event queues, workers, the - [PRD.md](./PRD.md) describes the product in plain English - [docs/](./docs/) contains the supporting documentation pages -- [somba/](./somba/) is the placeholder Python package structure -- [tests/](./tests/) is the placeholder test structure -- [scripts/](./scripts/) contains developer helper stubs +- [somba/](./somba/) is the FastAPI application: API routers, background workers (charge, recovery, reconciliation sweep, verify pass), the Nomba client, and the Alembic migrations +- [tests/](./tests/) is the real test suite (unit + integration) +- [scripts/](./scripts/) contains developer helper scripts (topic setup, demo seeding) +- [frontend/](./frontend/) is the React + Vite docs site and landing page — includes the interactive API docs, a dashboard (email/password auth, named API keys), and a sandbox page for testing the Nomba integration without touching live credentials -## Notes +## Status -This repository is still at scaffold stage. The current files are documentation and placeholders only, so the next step is implementation once the product shape is finalized. +Somba is implemented and running. The API is live at `https://somba-jade.vercel.app`, backed by Postgres and a Redpanda-based outbox relay, with a full test suite (unit + integration) passing in CI. The docs above describe the design; the code is the current source of truth for exact request/response shapes. > Somba by Team setld diff --git a/frontend/index.html b/frontend/index.html index d36f808..72da041 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -4,13 +4,42 @@ + + Somba — Recurring billing infrastructure for Nomba merchants + + + + + + + + + + + + + + + + + + + - Somba — Recurring billing infrastructure for Nomba merchants
diff --git a/frontend/public/og-image.png b/frontend/public/og-image.png new file mode 100644 index 0000000..9e4e042 Binary files /dev/null and b/frontend/public/og-image.png differ diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 2b9429b..058d44f 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -3,6 +3,7 @@ import Landing from './pages/Landing' import Signup from './pages/Signup' import Login from './pages/Login' import ApiKeys from './pages/ApiKeys' +import Sandbox from './pages/Sandbox' import DocsLayout from './layouts/DocsLayout' import Introduction from './pages/docs/Introduction' @@ -41,6 +42,7 @@ export default function App() { } /> } /> } /> + } /> }> } /> diff --git a/frontend/src/components/ProfileMenu.jsx b/frontend/src/components/ProfileMenu.jsx index 0947e53..a94c4f5 100644 --- a/frontend/src/components/ProfileMenu.jsx +++ b/frontend/src/components/ProfileMenu.jsx @@ -56,6 +56,13 @@ export default function ProfileMenu() { > API keys + setOpen(false)} + className="block px-4 py-2.5 font-mono text-[13px] text-text transition-colors hover:bg-panel-2" + > + Sandbox + + + + +
+
+
+

Virtual account

+

+ Creates a throwaway sandbox virtual account end-to-end. +

+
+ + {vaResult ? 'ok' : vaError ? 'failed' : 'untested'} + +
+ +

+ Nomba caps sandbox accounts at 2 virtual accounts total per account holder — once + that’s used up, this will fail with a real Nomba error even though nothing is + broken. That’s expected, not a bug. +

+ + + + + +
+ +
+
+
+

Webhook signature

+

+ Checks a payload + secret against a signature entirely in your browser — no + Nomba call, no quota. +

+
+ {whResult && ( + + {whResult.matches ? 'matches' : "doesn't match"} + + )} +
+ +