Self-serve signup and plan selection
Paybond’s public /signup flow is intentionally narrow. It exists for the self-serve plans only:
| Plan | Should use /signup? | Best fit |
|---|---|---|
| Free | Yes | Evaluation, prototypes, and low-volume trial workflows |
| Starter | Yes | One production workflow with predictable monthly cost |
| Team | Yes | Multiple agent products that need private dashboards and audit exports |
| Business | Yes | Production teams that need SSO / RBAC and managed policy workflows |
| Enterprise | No | Contract-led rollout, procurement review, custom terms, and bespoke support expectations |
If the buyer needs Enterprise-style rollout, the UI should send them to /contact/sales, not to the public signup form.
UI entry points
- Landing page: primary self-serve entry for buyers who are ready to start immediately.
- Pricing page: canonical plan comparison and plan-specific CTA source.
- Signup page: form entry for Free, Starter, Team, and Business after a plan is chosen.
The UI should keep the rule simple: Free, Starter, Team, Business go to /signup; Enterprise goes to contact sales.
Backend wiring
The public signup path spans the Next.js admin app, the Go gateway, Stripe for paid plans, and Harbor runtime enforcement:
- The browser enters through
/signup?plan=<plan_id>. - The Next.js app posts to public app routes:
POST /api/billing/free-signupPOST /api/billing/checkout-sessionGET /api/billing/checkout-status
- Those routes proxy to the Go gateway public billing surface:
POST /v1/public/billing/free-signupPOST /v1/public/billing/checkout-sessionGET /v1/public/billing/checkout-statusPOST /v1/public/billing/activate-owner
- The gateway is authoritative for signup provisioning. It creates or finalizes the org, tenant, owner, Stripe customer, and subscription rows.
- Owner activation sets the password and mints the first authenticated session for the tenant admin.
- After activation, the authenticated console reads billing state from gateway routes such as
/v1/billing/overview. - For Harbor-bound runtime calls, the gateway signs tenant JWT claims including
pb_plan,pb_status,pb_features, andpb_limits. - Harbor (Rust) enforces the runtime subset of commercial rules from those claims: write blocking on suspended or canceled subscriptions, monthly caps, settled-volume caps, and feature gates such as managed policy workflows.
Why Go and Rust both matter here
The Go gateway owns:
- plan selection and Stripe checkout setup
- tenant and owner provisioning
- authenticated billing views
- Harbor access-token minting with commercial claims
The Rust Harbor service owns:
- runtime plan-gate enforcement for write paths
- cap checks that cannot be trusted to UI copy alone
- commercial claim interpretation on escrow and policy operations
That split is deliberate: the UI can describe a plan, but only the gateway and Harbor can enforce it.
Operational notes
- Signup runs before any tenant session exists, so the browser must never be trusted to authorize a tenant directly.
- The requested realm is only a proposed identifier; the gateway reserves and finalizes it.
- Stripe cancellation should return the buyer to pricing with enough plan context to resume signup.
- Activation retries should preserve the activation token so transient failures do not strand the user.