Overview
{{COMPANY_SHORT_NAME}} runs on a Stripe subscription. The workspace is the billing entity — one Stripe customer per workspace, regardless of how many stores or team members you have. Charges happen monthly (or annually with a discount). Your subscription decides which modules are turned on (the core.org_module_flags table) and your usage is checked against per-month quotas.
Three Stripe-side hookups drive everything: stripe-billing-checkout handles upgrades, stripe-billing-portal opens the Stripe Customer Portal where the operator manages cards and invoices, and stripe-billing-webhook writes subscription state back into the database the moment Stripe’s side changes.
What working correctly looks like
- Settings → Billing shows the active plan, the renewal date, and the last invoice status.
- Upgrading from Settings → Billing → Change plan opens Stripe Checkout in a new tab and returns successfully.
- The Manage in Stripe button opens the Customer Portal authenticated as your workspace.
- The Usage card shows current-month consumption against each quota with a colored bar (green <50%, yellow 50–80%, orange 80–100%, red over).
- Module flags in Settings → Workspace → Modules match the plan tier (modules below your tier are visible; modules above show an Upgrade to enable chip).
- A failed Stripe payment fires a
billing_payment_failedemail within minutes and the dashboard shows a yellow banner.
Free trial
Every new workspace starts on a 14-day free trial of the highest-tier features. No card required. During the trial:
- All modules are unlocked.
- Quotas are set at the highest tier’s ceiling.
- The dashboard banner counts down to trial end.
At day 14:
- If you added a card via Choose plan, you transition into that paid plan and the first invoice is generated.
- If you didn’t, the workspace transitions to read-only: data stays, but you can’t create new orders, send communications, or call the API. Add a card any time to resume.
Plan tiers
Three plans plus a custom tier. Pricing is on the pricing page; this list is what you get on each.
- Starter — for solo operators getting off Excel. Single store, up to 3 team members, core CRM + orders + invoicing + email. No SMS, no integrations, no public API.
- Growth — for established operators. Up to 3 stores, unlimited team, all communications channels (email + SMS), all integrations, public API access. Default tier most operators land on.
- Scale — for multi-brand operators. Unlimited stores, all of Growth plus translation pipeline, advanced analytics, audit-log export, IP allowlisting, priority support.
- Custom — if your shape doesn’t fit. Annual contract, custom quotas, SLAs, security review. Email {{CONTACT_EMAIL}}.
Per-module flags
Every workspace has a row in core.org_module_flags that decides what’s on. The plan sets the defaults; admin overrides happen at Settings → Workspace → Modules.
- Disabled modules disappear from the navigation entirely.
- Disabled modules return
403 module_disabledif hit via the API. - Toggling a module off does not delete data; turning it back on restores the existing rows.
- A module above your tier shows a locked chip with an Upgrade CTA.
Quotas
Quotas are tracked monthly, calendar-month resets at 00:00 UTC on the 1st. Live counters at Settings → Billing → Usage.
| Quota | What it counts | What hitting 100% does |
|---|---|---|
api_requests | Successful requests on /integrations/v1/* and /v1/* | Returns 429 quota_exceeded until reset; UI banner. |
email_sends | Outbound emails (transactional + marketing) | Sends are queued_quota; held until reset or upgrade. |
sms_segments | Outbound SMS segments (160 chars / 70 unicode = 1) | Sends are queued_quota; held until reset or upgrade. |
storage_gb | Attached files in object storage | New uploads return 413 storage_quota_exceeded. |
translation_chars | Characters translated this month (UGC pipeline) | New translations queue but do not run; toggle via Settings → Translation. |
seats | Active team members + pending invites | New invites blocked. |
stores | Active stores | New store creation blocked. |
Quota warnings
The billing-notifications-cron runs hourly and emits warnings as you approach a cap. Each warning is dispatched once per quota per period.
- 50% — informational; no banner, just an email to billing-notified members.
- 80% — yellow banner on the dashboard, email to all admins.
- 100% — red banner, email, and the relevant rate-limit / queue behavior kicks in.
Pick which roles get the warning emails at Settings → Billing → Notifications.
Upgrades & the customer portal
Upgrading
- Settings → Billing → Change plan.
- Pick the new tier; choose monthly or annual (annual is −20%).
- Click Continue to Stripe. We open Stripe Checkout in a new tab.
- Enter card and finish. Stripe redirects back to Settings → Billing with a success banner.
stripe-billing-webhookwrites the new plan; module flags update within seconds.
Managing your subscription
Click Manage in Stripe on Settings → Billing. The Customer Portal lets the billing contact:
- Update the card on file.
- Download every invoice as PDF.
- Update the billing address and tax id.
- Switch billing cycles (monthly ↔ annual).
- Cancel the subscription.
The Stripe customer email is the workspace billing contact. It can differ from the workspace owner. Set it at Settings → Billing → Billing contact.
Invoices
Stripe issues an invoice on each renewal. Find them under Manage in Stripe → Invoices in the customer portal. The most recent invoice is also surfaced inline at Settings → Billing → Latest invoice.
- Each invoice is a PDF download.
- Invoices include line items for the subscription plus any usage overages (if your plan allows overages).
- Tax ID printed on the invoice; set yours at Manage in Stripe → Billing details.
- Invoice numbers are Stripe-side, not the per-store invoice numbers used in your CRM.
Failed payments & grace
When Stripe’s charge fails:
- We email the billing contact (
billing_payment_failedtemplate) immediately. - A yellow banner appears on every page until resolved.
- Stripe automatically retries up to 4 times over 10 days (Smart Retries).
- If still unresolved at day 10: workspace transitions to read-only. Data is intact, you can sign in, you can read everything; you can’t create or send. The banner turns red.
- Pay the invoice via Manage in Stripe; the webhook flips the workspace back to active within seconds.
Cancellation
Cancel anytime from the Customer Portal.
- Cancellation takes effect at the end of the current billing period.
- You keep full access until then. The dashboard shows a banner with the cutoff date.
- After the cutoff, the workspace transitions to read-only. Data is retained for 90 days; sign in any time to download or to reactivate.
- After 90 days of read-only inactivity, the workspace is queued for deletion. You get an email 14 days before with a one-click reactivate.
If you only need a break, ask {{CONTACT_EMAIL}} for a pause — we’ll switch you to a $0 hold tier for up to 90 days that retains data without billing.
Settings & permissions
- Settings → Billing — current plan, usage, latest invoice. Owner / admin.
- Settings → Billing → Change plan — opens Stripe Checkout. Owner / admin.
- Settings → Billing → Notifications — who receives quota warnings. Owner / admin.
- Settings → Workspace → Modules — toggle modules within the limits of your plan. Owner / admin.
- Manage in Stripe — opens the Customer Portal authenticated as your workspace. Owner / admin only.
staff and read_only roles cannot see Billing at all — the page returns 403 if visited directly.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Plan changed in Stripe but app still shows old plan | Webhook delayed or missed | Wait 60s; if still wrong, click Refresh from Stripe on Settings → Billing. |
| Stripe Checkout opens but redirect back fails | Pop-up blocker / closed early | Re-open Settings → Billing; if subscription is active in Stripe, it propagates within minutes. |
| Yellow “payment failed” banner won’t go away after paying | Stripe retry hasn’t fired yet | Click Pay invoice in the Customer Portal directly; banner clears within seconds of the webhook. |
API returns 429 quota_exceeded mid-month | You hit the API request cap | Wait for the 1st-of-month reset, upgrade tier, or batch your calls. |
Sends stuck at queued_quota | Hit email or SMS cap | Upgrade or wait for reset; capped sends fire automatically once headroom exists. |
| Invoice not in customer portal | Old invoice on previous Stripe customer (during account merge) | Email {{CONTACT_EMAIL}} with the workspace name and the date. |
| Need a custom plan / annual contract | — | Contact sales. |
Related
- Pricing — current public price points per tier.
- Contact — reach out for plan changes, custom contracts, pause requests.
- Team & roles — seat counts and per-store grants tie back to your plan limits.
- Multi-store workspaces — store counts tie back to your plan limits.
- Audit log — every plan change and module flip is recorded.