https://www.loom.com/share/2767f799df9d48519c737a1d082fc3f4?sid=967802e9-5bfb-438d-96cd-2f6fcbd2f69b
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- RECURSEML_SUMMARY:START -->
## High-level PR Summary
This PR adds a "Grant Product" feature to the dashboard's customer page,
allowing administrators to manually grant products to users, teams, or
custom customers. The UI has been updated to rename "Items" to
"Customers" in the navigation, and the page now includes a dialog for
selecting a product and quantity (for stackable products) to grant.
Additionally, the backend payment logic has been enhanced to properly
set `currentPeriodEnd` and `cancelAtPeriodEnd` when canceling
conflicting subscriptions during product grants.
⏱️ Estimated Review Time: 15-30 minutes
<details>
<summary>💡 Review Order Suggestion</summary>
| Order | File Path |
|-------|-----------|
| 1 |
`apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/sidebar-layout.tsx`
|
| 2 |
`apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/customers/page.tsx`
|
| 3 |
`apps/dashboard/src/app/(main)/(protected)/projects/[projectId]/payments/customers/page-client.tsx`
|
| 4 | `apps/backend/src/lib/payments.tsx` |
| 5 |
`packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts`
|
</details>
<details>
<summary>⚠️ Inconsistent Changes Detected</summary>
| File Path | Warning |
|-----------|---------|
|
`packages/template/src/lib/stack-app/apps/implementations/server-app-impl.ts`
| This appears to be a simple variable rename (cache to itemsCache) that
seems unrelated to adding grant product functionality to the dashboard |
</details>
[](https://discord.gg/n3SsVDAW6U)
[
<!-- RECURSEML_SUMMARY:END -->
<!-- ELLIPSIS_HIDDEN -->
----
> [!IMPORTANT]
> Adds "Grant Product" feature to dashboard, enabling admins to grant
products to customers, with new API endpoints, UI updates, and backend
logic enhancements.
>
> - **Behavior**:
> - Adds "Grant Product" feature to dashboard's customer page, allowing
admins to grant products to users, teams, or custom customers.
> - Updates UI to rename "Items" to "Customers" in navigation and adds
dialogs for product selection and quantity.
> - Enhances backend payment logic to set `currentPeriodEnd` and
`cancelAtPeriodEnd` when canceling conflicting subscriptions.
> - **API**:
> - New endpoints in `route.ts` for listing customer products and
granting products.
> - Implements `grantProductToCustomer()` in `payments.tsx` to handle
product grants.
> - **SDK**:
> - Adds `grantProduct` (server) and `listProducts` (client/server)
methods.
> - Updates `client-app-impl.ts` and `server-app-impl.ts` to support new
product functionalities.
> - **Models**:
> - Adds `CustomerProduct` and `CustomerProductsList` types in
`customers/index.ts`.
> - **Misc**:
> - Introduces `PRODUCT_ALREADY_GRANTED` error in `known-errors.tsx`.
> - Updates tests in `products.test.ts` and other test files to cover
new product grant scenarios.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for f0d112f578. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>
----
<!-- ELLIPSIS_HIDDEN -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Dashboard: New "Customers" page to view customers, grant products, and
manage items with dialogs and selectors for users, teams, or custom IDs.
- API/SDK: Endpoints and client/server SDK methods to list a customer’s
products (paginated) and to grant products.
- **Improvements**
- Error responses for already-owned non-stackable products are now
structured with clear codes and headers.
- Product payloads include server_only, included_items, and new
stackable support.
- **UI**
- Team search table and clickable team rows for faster navigation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- RECURSEML_SUMMARY:START -->
## High-level PR Summary
This PR updates the peer dependency requirements across multiple
package.json files to remove support for React 18.2 and only specify
React 19.0.0-rc.0 or newer as the minimum required version. The change
affects React, React DOM, and their corresponding TypeScript type
packages.
⏱️ Estimated Review Time: 5-15 minutes
<details>
<summary>💡 Review Order Suggestion</summary>
| Order | File Path |
|-------|-----------|
| 1 | `packages/react/package.json` |
| 2 | `packages/stack/package.json` |
| 3 | `packages/template/package-template.json` |
| 4 | `packages/template/package.json` |
</details>
[](https://discord.gg/n3SsVDAW6U)
<!-- RECURSEML_SUMMARY:END -->
<!-- ELLIPSIS_HIDDEN -->
----
> [!IMPORTANT]
> Update peer dependencies to require React 19.0.0 or newer across
multiple packages.
>
> - **Peer Dependencies**:
> - Updated minimum peer dependency to React 19.0.0 for `react`,
`react-dom`, `@types/react`, and `@types/react-dom` in
`packages/react/package.json`, `packages/stack/package.json`, and
`packages/template/package.json`.
> - Removed support for React 18.2 in peer dependencies across all
affected `package.json` files.
> - **Dev Dependencies**:
> - Updated development dependencies to React 19.0.0 in
`packages/react/package.json`, `packages/stack/package.json`, and
`packages/template/package.json`.
> - **Misc**:
> - No runtime behavior changes; only stricter dependency constraints.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for fa6ee35f32. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>
----
<!-- ELLIPSIS_HIDDEN -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Raised peer dependency minimums to React 19.0.0 for react, react-dom,
@types/react, and @types/react-dom across packages.
* Bumped development dependencies used for building and testing to React
19.x.
* Applies to templates, stack packages, UI/shared packages, and
development tooling; no runtime behavior changes—only stricter
dependency requirements.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Konsti Wohlwend <n2d4xc@gmail.com>
<!--
Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md
-->
<!-- RECURSEML_SUMMARY:START -->
## High-level PR Summary
This PR adds a new `priceId` field to the `OneTimePurchase` and
`Subscription` models in the database to store Stripe price identifiers.
The change includes database schema updates, corresponding migration
files, and modifications to payment processing logic to properly track
and store price IDs throughout the purchase flow. The implementation
consistently propagates the price ID from Stripe's API responses through
various payment processing endpoints and webhooks handlers, ensuring the
data is properly stored and synced with the database models.
⏱️ Estimated Review Time: 15-30 minutes
<details>
<summary>💡 Review Order Suggestion</summary>
| Order | File Path |
|-------|-----------|
| 1 | `apps/backend/prisma/schema.prisma` |
| 2 |
`apps/backend/prisma/migrations/20250917193043_store_price_id/migration.sql`
|
| 3 | `apps/backend/src/lib/stripe.tsx` |
| 4 |
`apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx`
|
| 5 |
`apps/backend/src/app/api/latest/internal/payments/test-mode-purchase-session/route.tsx`
|
| 6 |
`apps/backend/src/app/api/latest/integrations/stripe/webhooks/route.tsx`
|
| 7 | `apps/e2e/tests/backend/endpoints/api/v1/stripe-webhooks.test.ts`
|
</details>
<!-- RECURSEML_SUMMARY:END -->
<!-- ELLIPSIS_HIDDEN -->
----
> [!IMPORTANT]
> Add `priceId` field to track Stripe price identifiers in purchase and
subscription models, updating schema, payment logic, and tests.
>
> - **Database Changes**:
> - Add `priceId` field to `OneTimePurchase` and `Subscription` models
in `schema.prisma`.
> - Update database schema with migration
`20250917193043_store_price_id/migration.sql`.
> - **Payment Processing**:
> - Update `processStripeWebhookEvent()` in `webhooks/route.tsx` to
handle `priceId`.
> - Modify `POST` handlers in `purchase-session/route.tsx` and
`test-mode-purchase-session/route.tsx` to include `priceId` in metadata.
> - Update `syncStripeSubscriptions()` in `stripe.tsx` to sync
`priceId`.
> - **Testing**:
> - Add tests in `stripe-webhooks.test.ts` to validate `priceId`
handling in webhook and purchase flows.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for 4950494d62. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>
----
<!-- ELLIPSIS_HIDDEN -->
<!-- RECURSEML_ANALYSIS:START -->
## Review by RecurseML
_🔍 Review performed on
[e48ffa6..4950494](e48ffa67ee...4950494d62)_
| Severity | Location | Issue
| Delete |
|:----------:|----------|-------|:--------:|
|  |
[apps/e2e/tests/backend/endpoints/api/v1/stripe-webhooks.test.ts:153](https://github.com/stack-auth/stack-auth/pull/900#discussion_r2356623574)
| The field `priceId` uses camelCase instead of the required snake_case
for API parameters |
[
|
|  |
[apps/e2e/tests/backend/endpoints/api/v1/stripe-webhooks.test.ts:245](https://github.com/stack-auth/stack-auth/pull/900#discussion_r2356623664)
| The field `priceId` uses camelCase instead of the required snake_case
for API parameters |
[
|
|  |
[apps/e2e/tests/backend/endpoints/api/v1/stripe-webhooks.test.ts:358](https://github.com/stack-auth/stack-auth/pull/900#discussion_r2356623721)
| The field `priceId` uses camelCase instead of the required snake_case
for API parameters |
[
|
<details>
<summary>✅ Files analyzed, no issues (4)</summary>
• `apps/backend/src/lib/stripe.tsx`
•
`apps/backend/src/app/api/latest/payments/purchases/purchase-session/route.tsx`
•
`apps/backend/src/app/api/latest/integrations/stripe/webhooks/route.tsx`
•
`apps/backend/src/app/api/latest/internal/payments/test-mode-purchase-session/route.tsx`
</details>
<details>
<summary>⏭️ Files skipped (trigger manually) (2)</summary>
| Locations | Trigger Analysis |
|-----------|:------------------:|
`apps/backend/prisma/migrations/20250917193043_store_price_id/migration.sql`
|
[
`apps/backend/prisma/schema.prisma` |
[
</details>
[](https://discord.gg/n3SsVDAW6U)
<!-- RECURSEML_ANALYSIS:END -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- New Features
- Persist the selected price ID with one-time purchases and
subscriptions.
- Carry the price ID through payment flows and Stripe metadata for
better tracking and reporting.
- Test mode purchases now also record the price ID.
- Chores
- Database migration adds a price ID field to purchase and subscription
records.
- Tests
- Updated end-to-end tests to validate price ID handling in webhook and
purchase flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Takes `stripeAccountId` out of the schema, adds a new endpoint for
getting a user's account ifo, and adds a new notification banner for
un-onboarded accounts.
<img width="1203" height="524" alt="Screenshot 2025-08-25 at 16 40 18"
src="https://github.com/user-attachments/assets/a2b0626d-dc86-4090-b221-0969ec34f124"
/>
<!-- ELLIPSIS_HIDDEN -->
----
> [!IMPORTANT]
> Enhances payments UX with new UI components, refactors, and expanded
tests, while introducing breaking changes and improved error handling.
>
> - **Behavior**:
> - Removes `stripeAccountId` from schema and adds new endpoint in
`route.ts` for user account info.
> - Adds notification banner for un-onboarded accounts in `layout.tsx`.
> - Updates `createCheckoutUrl` to expect options object.
> - **UI Componets**:
> - Adds `CreateGroupDialog`, `IncludedItemDialog`, `ItemDialog`,
`OfferDialog`, `PriceDialog`, and `ListSection` in `payments` directory.
> - Implements `Stepper` component in `stepper.tsx` for multi-step
processes.
> - Adds `IllustratedInfo` component in `illustrated-info.tsx`.
> - **Refactor**:
> - Refactors `use-hover.tsx` to improve hover detection.
> - Updates `admin-interface.ts` to handle known errors more robustly.
> - Removes feature gating from Payments and Offers pages.
> - **Tests**:
> - Expands E2E and unit tests in `internal-metrics.test.ts` to cover
new payment flows and error handling.
> - **Misc**:
> - Updates `mapProperty` and `removeProperty` functions in `schema.ts`
for better property handling.
> - Adds `StripeAccountInfoNotFound` error in `known-errors.tsx`.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for aed61b5857. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>
----
<!-- ELLIPSIS_HIDDEN -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Stripe onboarding UI, account-status display, and in-app setup flow.
* Quantity support across checkout, test-mode purchases, and purchase
flows.
* Payments dashboard revamp: Offers/Items management, groups, add‑ons,
price editor, included-item dialogs, visual connections, and welcome/DEV
modes.
* **Refactor**
* Stripe account stored per-project and resolved asynchronously;
subscription sync made more robust.
* Payments and Offers pages no longer feature-gated.
* **Breaking Changes**
* createCheckoutUrl now expects an options object ({ offerId }).
* **Tests**
* Expanded E2E and unit tests covering payments, onboarding, and
purchase flows.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Bilal Godil <bg2002@gmail.com>
<!-- ELLIPSIS_HIDDEN -->
> [!IMPORTANT]
> Add Twitch as a new OAuth provider, updating backend logic and UI
components to support Twitch authentication.
>
> - **Behavior**:
> - Add `TwitchProvider` class in `providers/twitch.tsx` to handle OAuth
with Twitch, including user info post-processing.
> - Update `_providers` in `index.tsx` to include `TwitchProvider`.
> - Add `TWITCH` to `StandardOAuthProviderType` enum in `schema.prisma`.
> - **UI Components**:
> - Add Twitch icon and color in `brand-icons.tsx` and `BRAND_COLORS`.
> - Update `ProviderIcon`, `ProviderSettingDialog`, and `OAuthButton` to
support Twitch in `providers.tsx` and `oauth-button.tsx`.
> - **Misc**:
> - Add `twitch` to `standardProviders` in `oauth.tsx`.
>
> <sup>This description was created by </sup>[<img alt="Ellipsis"
src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=stack-auth%2Fstack-auth&utm_source=github&utm_medium=referral)<sup>
for 08c0de5762. You can
[customize](https://app.ellipsis.dev/stack-auth/settings/summaries) this
summary. It will automatically update as commits are pushed.</sup>
<!-- ELLIPSIS_HIDDEN -->
---------
Co-authored-by: Zai Shi <zaishi00@outlook.com>