Commit Graph

2 Commits

Author SHA1 Message Date
Danny White
9e3a10d557 feat(studio): payment method states for Stripe Projects orgs (#44965)
## What kind of change does this PR introduce?

UI changes for Stripe-managed billing surfaces.

- Resolves DEPR-537
- Related to DEPR-538

## What is the current behaviour?

Stripe-connected organisations still look too self-serve in Studio.

- Payment Methods still reads mostly like ordinary Supabase card
management, even though billing is handled through a Shared Payment
Token via Stripe Projects
- invoice messaging still implies support is the path to changing
payment methods, even for Stripe-managed orgs
- the Subscription Plan flow still needs Stripe-specific guardrails so
users are redirected to the correct upgrade path rather than trying to
self-serve everything in Studio
- the base branch now correctly separates `integration_source` from
`billing_partner`, but this stacked work still needs to carry that split
through the Stripe billing-token surfaces

## What is the new behaviour?

This PR makes the Stripe-managed billing surfaces behave like
Stripe-managed billing surfaces, while leaving AWS and Vercel on the
existing `billing_partner` path.

- Payment Methods now keeps the familiar saved-card row, but augments
Stripe-managed rows with Shared Payment Token context, token status, and
Stripe Projects affordances
- Stripe-managed invoice messaging now points users to Stripe Projects
rather than to support for payment-method changes
- the Subscription Plan flow keeps the existing managed-billing shape,
with Stripe-specific guardrails layered in where plan changes should be
handled outside Studio
- AWS and Vercel continue to use the existing partner-managed alerts and
CTAs driven by `billing_partner` / `billing_via_partner`

| Subscription plan sheet |
| --- |
| <img width="1780" height="448" alt="CleanShot 2026-04-24 at 17 21
43@2x"
src="https://github.com/user-attachments/assets/34c0f3ba-fc42-4d07-97a2-0e4f4cefc55e"
/> |
| _Upgrade instructions_ |
| <img width="1786" height="460" alt="CleanShot 2026-04-24 at 17 20
12@2x"
src="https://github.com/user-attachments/assets/bb67c835-b9b2-4648-b0e1-9c2f8d2317d3"
/> |
| _Downgrade instructions_ | 

> [!NOTE]
> The below screenshots are outdated. The _Shared Payment Token_
terminology has been removed in favour of more generic copy such as
_Stripe Projects token_.

| Stripe payment method states |
| --- |
| <img width="1436" height="234" alt="CleanShot 2026-04-23 at 19 03
49@2x"
src="https://github.com/user-attachments/assets/52ed7a00-dfba-4b66-9a07-a6346692d3c8"
/> |
| _Healthy_ |
| <img width="1434" height="224" alt="CleanShot 2026-04-23 at 19 04
50@2x"
src="https://github.com/user-attachments/assets/94efd943-b7bf-4da2-9e1b-1828aae97126"
/> |
| _Card expiring soon_ |
| <img width="1436" height="236" alt="CleanShot 2026-04-23 at 19 06
51@2x"
src="https://github.com/user-attachments/assets/272cb707-c724-4629-890e-853972e53a18"
/> |
| _Card expired_ |
| <img width="1308" height="238" alt="CleanShot 2026-04-23 at 19 07
21@2x"
src="https://github.com/user-attachments/assets/3eadd2a9-def3-4f43-850e-7d82adfb0b57"
/> |
| _Token expired_ |

## Dependencies

This PR is stacked on:

- #44328

It also depends on the private platform work that exposes Stripe project
connection state and SPT details:

- https://github.com/supabase/platform/pull/31874
- https://github.com/supabase/platform/pull/31940

## Platform dependency status

Most of the remaining platform work for this stack is now covered by the
private dependency below:

- https://github.com/supabase/platform/pull/31940

That PR is expected to provide the SPT details and paid-flow fixes this
Studio work depends on. In practice, the main caveat here is less
“Studio still needs a bunch of new platform work” and more “do not merge
this until `platform#31940` has landed and the end-to-end Stripe-managed
flow has been rechecked”.

## Local testing

Use the same local Stripe setup as the base branch, with
`integration_source: 'stripe_projects'` returned consistently for:

- `/platform/organizations`
- `/platform/organizations/:slug/projects`
- `/platform/projects/:ref`

For payment method demos, the temporary local mock currently lives in
private `platform` on:

- `/platform/organizations/:slug/payments`

That mock can be flipped between:

- healthy token + healthy underlying card
- healthy token + card expiring soon
- healthy token + expired card
- expired token

Then verify:

- the org and project connection affordances from #44328 still render
correctly
- Payment Methods shows Stripe-managed token context rather than
implying ordinary self-serve card management
- regression test ordinary non-Stripe payment methods too, to confirm
the standard saved-card row still renders with the existing `Expires:`
copy and no Shared Payment Token affordances
- invoice messaging points Stripe-managed orgs to Stripe Projects rather
than support
- Subscription Plan keeps the managed-billing guardrails for Stripe
- AWS and Vercel orgs still show the existing partner-managed messaging
rather than the Stripe-specific notices

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Stripe-managed organizations show Stripe Projects billing guidance,
replace in-app payment management with Stripe links, and adjust billing
copy.
* Payment methods support Shared Payment Tokens (SPTs): token
expiry/status badges with tooltips, “Handled via Stripe Projects”
indicator, token last4/expiry display, and disabled local update/delete
actions for SPTs.

* **API**
* Payments response now includes optional shared payment token details
for payment methods.

* **Documentation**
  * Added links to Stripe Projects billing docs in relevant flows.

* **Tests**
  * Updated and added tests covering Stripe-managed and SPT behaviors.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Raúl Barroso <code@raulb.dev>
2026-04-28 12:17:29 +10:00
Danny White
1ab7251060 chore(studio): clarify partnered orgs and projects (#44328)
## What kind of change does this PR introduce?

UI improvements.

- Resolves DEPR-401
- Resolves DEPR-424
- Resolves DEPR-425

## What is the current behaviour?

Studio currently blurs two different concepts together:

- `billing_partner` / `billing_via_partner`, which represent real
billing ownership for marketplace-managed organisations such as AWS and
Vercel
- Stripe connection state, which is not actually partner billing in the
same sense, but was previously being mocked through the same UI paths

That made the Stripe work harder to reason about and left some local
behaviour dependent on temporary overrides rather than the API shape we
want to ship.

## What is the new behaviour?

This PR separates those concerns while keeping the existing AWS and
Vercel marketplace experience intact.

- AWS and Vercel continue to use `billing_partner` /
`billing_via_partner` for billing ownership, lockouts, and manage CTAs
- Stripe display state now comes from `integration_source`, which lets
Studio show Stripe-specific badges and alerts without treating Stripe as
a billing partner
- organisation-level partner UI is unified across AWS, Vercel, and
Stripe, including the org banner, navbar icon treatment, and
organisation cards
- project-level Stripe UI now appears only when the project itself is
marked as Stripe-connected, including the project switcher, project list
surfaces, and a project-level banner
- Stripe-connected organisations are no longer incorrectly blocked
behind the AWS/Vercel-style billing management alerts for invoices,
billing address, payment methods, or plan changes
- banner dismissal is scoped to the relevant org/project and
partner/integration state

## Review order

Most of the diff size here is regression tests and generated types. The
behavioural changes are concentrated in a smaller set of files.

Recommended review order:

1. `integration_source` vs `billing_partner` data-model split and
org/project query mapping
2. org-level UI: partner icon, org banner, org dropdown/card treatment
3. billing gating updates for Stripe vs AWS/Vercel
4. project-level Stripe UI: dropdown, list surfaces, banner
5. tests and generated types

| Stripe Org(s) |
| --- |
| <img width="1024" height="759" alt="Organizations Supabase"
src="https://github.com/user-attachments/assets/d0ef338c-3b41-4c6d-b3bd-f21a2c182840"
/> |

| Vercel Org(s) |
| --- |
| <img width="1024" height="759" alt="Organizations Supabase"
src="https://github.com/user-attachments/assets/1dc57770-3f24-45ac-840f-34680555cde8"
/> |

| AWS Org(s) |
| --- |
| <img width="1024" height="759" alt="Organizations Supabase"
src="https://github.com/user-attachments/assets/7847dad0-ee30-4a65-ab0b-b3b16af0d34f"
/> |

| Stripe Org, Non-Stripe Project |
| --- |
| <img width="1152" height="885" alt="Mallet Toolshed
Supabase-1673E019-792C-462C-B6F8-C5DDB810B331"
src="https://github.com/user-attachments/assets/556fbea3-b5ae-4f2f-96b9-6f66c6654e4a"
/> |

| Stripe Org, Stripe Project |
| --- |
| <img width="1152" height="885" alt="Hammer Toolshed
Supabase-7E86C17C-561F-4221-BD16-EAFF7D41AAE0"
src="https://github.com/user-attachments/assets/94f8daf6-0320-413e-8d56-59f9acaaea15"
/> |

| Vercel Org |
| --- |
| <img width="1024" height="759" alt="Projects Toolshed
Supabase-A7891653-9366-4B99-89DD-789D70CD52E3"
src="https://github.com/user-attachments/assets/c87ee6e8-4451-4866-a905-23a38b2593e3"
/> |

| AWS Org |
| --- |
| <img width="1024" height="759" alt="Projects Toolshed
Supabase-58A43ECE-569E-4541-9463-346A90B02CFF"
src="https://github.com/user-attachments/assets/9350a180-4d58-42a1-ad1a-95893c2e8b12"
/> |

This also removes the old Stripe mock override path in Studio so the
frontend matches the intended API model more closely.

## ~~Dependencies~~ (merged!)

This work depends on the private platform change that exposes
`integration_source` on the relevant organisation and project payloads:

- https://github.com/supabase/platform/pull/31874

_Update: now merged._

## Local testing

### Stripe

If you have the private `platform` repo checked out locally, make sure
your local API returns `integration_source: 'stripe_projects'`
consistently for the Stripe-linked org/project you are testing.

Important responses:

- `/platform/organizations`
- `/platform/organizations/:slug/projects`
- `/platform/projects/:ref`

Verify:

- org banner and org icon show the Stripe connected state
- unopened and opened project switcher both show Stripe only for
Stripe-linked projects
- project cards / table rows show the Stripe chip only for Stripe-linked
projects
- the project-level Stripe banner appears across project surfaces
- billing address, tax ID, invoices, payment methods, and plan changes
remain editable in Studio for Stripe orgs

### Vercel

Use a Vercel Marketplace org with real `billing_partner` /
`billing_via_partner` values.

Important org-level endpoints for local mocking in `platform`:

- `/platform/organizations`
- `/platform/organizations/:slug`
- `/platform/organizations/:slug/billing/subscription`

Project-level Vercel indicators still come from
`/platform/integrations/:slug`, not `integration_source`.

### AWS

Use an AWS Marketplace org with real `billing_partner` /
`billing_via_partner` values.

Important org-level endpoints for local mocking in `platform`:

- `/platform/organizations`
- `/platform/organizations/:slug`
- `/platform/organizations/:slug/billing/subscription`

AWS does not currently have a Stripe-like project-level indicator in
these org/project payloads.

## Notes

- `billing_partner` is no longer the right abstraction for the
Stripe-connected case in this PR. It remains the source of truth for
marketplace billing ownership, while Stripe currently uses
`integration_source` as a connection/display signal.
- I re-ran `pnpm api:codegen` while tightening this PR and kept only the
generated type changes this branch actually depends on, to avoid
unrelated API drift in the review.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Stripe Projects integration added for billing and project flows
* Partner icons/badges shown across org and project lists, dropdowns,
and rows
* Dismissible, partner-specific marketplace/integration banners with
contextual CTA behavior
* Improved partner-billing detection to drive billing UI and
invoice/plan availability

* **Tests**
* Extensive new test coverage for billing UI, partner-managed fallbacks,
banners, icons, and related flows
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-04-23 12:17:24 +10:00