Skip to content

Payments

Payments exist so the product can be free for most users and great for the users who pay for the extra surface. Tomoda's monetisation is a subscription billed through Stripe — checkout, billing portal, and webhook-driven state sync, all hosted on Stripe rather than reimplemented in-app.

The mechanics

Upgrading is two taps to a Stripe-hosted checkout. Managing the subscription is one tap to the Stripe-hosted billing portal — we don't reimplement the cancellation flow. The backend mirrors Stripe's source of truth on the users row (subscription_status, subscription_plan, subscription_end, stripe_customer_id) and consumes that mirror wherever a feature needs to ask "is this user paying?".

What's shipped

Surface Notes
POST /api/v1/auth/payment/create-checkout-session Mints a Stripe Checkout URL for monthly or yearly.
POST /api/v1/auth/payment/create-portal-session Opens the Stripe-hosted billing portal.
POST /api/v1/payment/webhook Stripe → backend webhook, signature-verified, drives subscription_status / subscription_plan / subscription_end on users.
users.subscription_status, subscription_plan, subscription_end, stripe_customer_id Mirror of Stripe's source of truth.
backend/scripts/create_stripe_prices.go One-shot price seeder per environment.

See also