account · billing · checkout

Purchase your plan

One screen: how you pay, who the invoice goes to, and what you are buying. The billing profile belongs to the workspace being billed, so it outlives this purchase and every renewal reuses it.

Buying for
Billing profile
Prototype — nothing is charged. Card fields accept any well-formed value.
Payment method
Charged today, then on every renewal. Change it any time from Billing.
VISAMASTERCARDAMEX Major cards accepted. Bank debit lands with the payment element.
Payment element · rendered by the payment processor · card data never touches Relay
Enter the long number on the front of the card.
Use the month and year printed on the card, like 11 / 27.
The 3 or 4 digit code on the card.
Billing profile
Who the invoice is made out to. Kept on the workspace, reused on every renewal.
This purchase is for
Billing contact
Enter a first name for the billing contact.
Enter a last name for the billing contact.
Receipts and invoices go here. Your sign-in email stays where it is.
Enter an email that can receive invoices, like billing@company.com.
Billing address
Choose the country the invoice is addressed to. Tax follows from it.
Enter the street address for the invoice.
Enter the city.
Enter the postal code.
Defaults to the legal name, or your name. Only matters once a workspace has more than one profile.
Saved to your personal account’s billing. The plan lives on the account, so the profile does too.
Receipt details optional
Anything your finance team needs printed on the receipt.
Printed on every invoice for this subscription. Edit it from Billing and the change applies from the next invoice.
Authorization
What this prototype models. The two switches above are the two axes the platform actually has: the org plane (orgs.is_personal — a personal account buys Pro, a team workspace buys Team) and whether that org already has a billing profile on file. Everything in the overview is the shipped contract in billing.TIERS: Pro $15/mo; Team $15/seat/mo with a 3-seat floor; the included lines are the enforced limits, not marketing copy. Promotion codes are real (allow_promotion_codes), and a Loop commitment is applied automatically at checkout.
The billing profile belongs to the org, never the user. SPEC.org-plan-model §0: plan is a property of the org; a solo user’s plan is the plan of their personal org. So the profile is saved to the personal account or to the team workspace — the line under the form says which — and a second member never forces a migration. Do not build a per-user billing entity.
What the platform does not have yet.
  • A stored billing profile. StripeProvider.get_or_create_customer creates the customer with name + email only, and org_billing carries no address, tax ID, phone or invoice email. The profile drawn here maps onto Stripe Customer name / email / phone / address / tax_ids (types ca_gst_hst, eu_vat, gb_vat, us_ein, au_abn) and invoice_settings; the receipt notes map onto the invoice footer / custom fields. Store it per org (a billing_profiles table keyed by org_id, one default) and sync it to the customer on save.
  • One build path, and the card step is not it. The gateway contract (SPEC.payment-gateways §2 row 5) makes hosted checkout the required capability and puts in-app card capture out of scope, so the card fields here are a composition, not a build target: the built screen collects the profile first, then opens Checkout with the customer prefilled and tax_id_collection + billing_address_collection on (RCTX-1358). Confirmed still means the webhook said so — the success step shows the pending state first for that reason.
  • Tax. automatic_tax appears nowhere in relay-platform. The tax line reads “from the billing address” and shows no number rather than an invented rate.
  • Annual billing. No annual price is configured (STRIPE_PRICE_PRO / STRIPE_PRICE_TEAM are the only two), so the period toggle is disabled and labelled, never selectable.
  • Team self-serve. billing_upgrade is personal-only and RELAY_SELF_SERVE_ORG_CREATE defaults off. The Team plane is drawn ahead of that gate as the last step of the creation moment (Org onboarding & residency), not as something that works today.
A defect noticed on the way. relay-app plan.ts PLAN_FEATURES still tells a Pro buyer “Unlimited transfers” and “32 768 token limit”; billing.TIERS enforces 500 creates and 8,192 tokens, and the summary never returns feature lines, so that copy is what buyers see. Filed as RCTX-1362. This page draws the contract.
Record. Program map ``relay-board/docs/product/checkout-and-billing-profile.md`` (the argument, the decisions, the Linear map) · engineering ``relay-platform/docs/DESIGN-NOTE.billing-profile.md`` (model, API, processor mapping) · Linear epic RCTX-1356 with RCTX-1357–1361, the annual-billing decision RCTX-1363.
Forms law. Built to GUIDE.forms.md: a visible label on every control, per-field errors shown on submit and cleared on input with focus moved to the first, always-visible hints wired with aria-describedby, autocomplete on identity and card fields, consent unchecked by default with an aria-disabled submit that answers a blocked click by flagging the row, and a confirmation that replaces the form and takes focus.
The success step. Paying replaces the whole checkout, not just the form: the topbar reads Confirming your payment… until the processor’s webhook says otherwise, then Your purchase was successful; the card carries the same included list as the overview (one contract, drawn twice), and the two next actions are the plane’s — a team workspace is offered Invite team members, a personal account See your receipt in Billing. The ceremony is the display face and the mark, not an illustration. Deep links: ?plane=team · ?profile=saved · ?step=success. Press T for dark.