paybondpaybond
Sign in

Self-serve signup and plan selection

Which plans should use /signup, which ones should not, and how the UI connects to Gateway and Harbor.

Self-serve signup and plan selection

Paybond’s public /signup flow is intentionally narrow. It exists for the self-serve plans only:

PlanShould use /signup?Best fit
FreeYesEvaluation, prototypes, and low-volume trial workflows
StarterYesOne production workflow with predictable monthly cost
TeamYesMultiple agent products that need private dashboards and audit exports
BusinessYesProduction teams that need SSO / RBAC and managed policy workflows
EnterpriseNoContract-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:

  1. The browser enters through /signup?plan=<plan_id>.
  2. The Next.js app posts to public app routes:
    • POST /api/billing/free-signup
    • POST /api/billing/checkout-session
    • GET /api/billing/checkout-status
  3. Those routes proxy to the Go gateway public billing surface:
    • POST /v1/public/billing/free-signup
    • POST /v1/public/billing/checkout-session
    • GET /v1/public/billing/checkout-status
    • POST /v1/public/billing/activate-owner
  4. The gateway is authoritative for signup provisioning. It creates or finalizes the org, tenant, owner, Stripe customer, and subscription rows.
  5. Owner activation sets the password and mints the first authenticated session for the tenant admin.
  6. After activation, the authenticated console reads billing state from gateway routes such as /v1/billing/overview.
  7. For Harbor-bound runtime calls, the gateway signs tenant JWT claims including pb_plan, pb_status, pb_features, and pb_limits.
  8. 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.