From 342baf1fc8f14272e55fc98d534e4e2475fd8746 Mon Sep 17 00:00:00 2001 From: Shanyu Thibaut Juneja Date: Thu, 13 Nov 2025 16:13:05 -0800 Subject: [PATCH 1/5] Adds entity ID filter to product list Enables filtering of products by entity ID. This enhancement allows for more specific product retrieval based on the entity they belong to. --- package/src/sdk/products/prodTypes.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/package/src/sdk/products/prodTypes.ts b/package/src/sdk/products/prodTypes.ts index df497c5..13a50e0 100644 --- a/package/src/sdk/products/prodTypes.ts +++ b/package/src/sdk/products/prodTypes.ts @@ -117,6 +117,7 @@ export interface CreateProductParams { export interface ListProductsParams { customer_id?: string; + entity_id?: string; } export interface DeleteProductParams { From 10cb3d575a26abffcfccb3a4d4f1462fc036a8af Mon Sep 17 00:00:00 2001 From: Shanyu Thibaut Juneja Date: Thu, 13 Nov 2025 16:20:26 -0800 Subject: [PATCH 2/5] add to client methods --- .../react/client/clientProdMethods.ts | 22 +++++++++++++++++-- .../react/client/types/clientProdTypes.ts | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/package/src/libraries/react/client/clientProdMethods.ts b/package/src/libraries/react/client/clientProdMethods.ts index 1ae07f9..876b0f4 100644 --- a/package/src/libraries/react/client/clientProdMethods.ts +++ b/package/src/libraries/react/client/clientProdMethods.ts @@ -1,10 +1,28 @@ import type { AutumnPromise } from "@sdk/response"; import type { Product } from "src/sdk/products/prodTypes"; import type { AutumnClient } from "./ReactAutumnClient"; +import type { ListProductsParams } from "./types/clientProdTypes"; -export async function listProductsMethod(this: AutumnClient): AutumnPromise<{ +export async function listProductsMethod(this: AutumnClient, params?: ListProductsParams): AutumnPromise<{ list: Product[]; }> { - const res = await this.get(`${this.prefix}/products`); + let path = `${this.prefix}/products`; + + // Append query params to the path + // available: customer_id (optional), entity_id (optional) + const queryParams = new URLSearchParams(); + for (const [key, value] of Object.entries(params ?? {})) { + if (value !== undefined) { + queryParams.append(key, String(value)); + } + } + + // minor optimization to avoid adding ? if no query params + const queryString = queryParams.toString(); + if (queryString) { + path += `?${queryString}`; + } + + const res = await this.get(path); return res; } diff --git a/package/src/libraries/react/client/types/clientProdTypes.ts b/package/src/libraries/react/client/types/clientProdTypes.ts index de00380..ebe1bbe 100644 --- a/package/src/libraries/react/client/types/clientProdTypes.ts +++ b/package/src/libraries/react/client/types/clientProdTypes.ts @@ -1,3 +1,4 @@ export interface ListProductsParams { customerId?: string; + entityId?: string; } From eda1b5e63012e192d044e31631952fb2cf36e123 Mon Sep 17 00:00:00 2001 From: Shanyu Thibaut Juneja Date: Thu, 13 Nov 2025 16:21:35 -0800 Subject: [PATCH 3/5] update route --- package/src/libraries/backend/routes/productRoutes.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package/src/libraries/backend/routes/productRoutes.ts b/package/src/libraries/backend/routes/productRoutes.ts index d7a7fb2..43a247f 100644 --- a/package/src/libraries/backend/routes/productRoutes.ts +++ b/package/src/libraries/backend/routes/productRoutes.ts @@ -7,12 +7,15 @@ const listProductsHandler = withAuth({ fn: async ({ autumn, customer_id, + entity_id, }: { autumn: Autumn; customer_id: string; + entity_id?: string; }) => { return await autumn.products.list({ customer_id, + entity_id, }); }, requireCustomer: false, From d68940846d29f1ef82ab3bd4e52ab2ab4ce3bf8d Mon Sep 17 00:00:00 2001 From: Shanyu Thibaut Juneja Date: Thu, 13 Nov 2025 17:39:34 -0800 Subject: [PATCH 4/5] Add entity id selection to pricing table --- package/src/libraries/react/hooks/usePricingTable.tsx | 4 +++- package/src/libraries/react/hooks/usePricingTableBase.tsx | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/package/src/libraries/react/hooks/usePricingTable.tsx b/package/src/libraries/react/hooks/usePricingTable.tsx index f3bcac4..8c99649 100644 --- a/package/src/libraries/react/hooks/usePricingTable.tsx +++ b/package/src/libraries/react/hooks/usePricingTable.tsx @@ -1,9 +1,11 @@ - import { usePricingTableBase } from "./usePricingTableBase"; +import { usePricingTableBase } from "./usePricingTableBase"; import { ProductDetails } from "../client/types/clientPricingTableTypes"; import { AutumnContext, useAutumnContext } from "@/AutumnContext"; export const usePricingTable = (params?: { productDetails?: ProductDetails[]; + entityId?: string; + customerId?: string; }) => { const context = useAutumnContext({ AutumnContext, diff --git a/package/src/libraries/react/hooks/usePricingTableBase.tsx b/package/src/libraries/react/hooks/usePricingTableBase.tsx index 9f7f6fc..cc75ad8 100644 --- a/package/src/libraries/react/hooks/usePricingTableBase.tsx +++ b/package/src/libraries/react/hooks/usePricingTableBase.tsx @@ -195,11 +195,16 @@ export const usePricingTableBase = ({ client: AutumnClient | ConvexAutumnClient; params?: { productDetails?: ProductDetails[]; + entityId?: string; + customerId?: string; }; }) => { const fetcher = async () => { try { - const { data, error } = await client.products.list(); + const { data, error } = await client.products.list({ + customerId: params?.customerId, + entityId: params?.entityId, + }); if (error) throw error; return data?.list || []; From a69d2f6e55d82915971ae1b75f621066ea9b2387 Mon Sep 17 00:00:00 2001 From: Shanyu Thibaut Juneja Date: Thu, 13 Nov 2025 19:38:56 -0800 Subject: [PATCH 5/5] Confirmed works --- .../libraries/backend/routes/productRoutes.ts | 10 ++++++---- package/src/libraries/react/AutumnContext.tsx | 17 +++++++++++------ .../react/client/ReactAutumnClient.tsx | 13 ++++++------- .../react/client/types/clientProdTypes.ts | 1 - .../pricing-table/pricing-table-synced.tsx | 12 +++++++----- .../react/hooks/helpers/useAutumnBase.tsx | 2 +- .../src/libraries/react/hooks/useEntityBase.tsx | 3 ++- .../libraries/react/hooks/usePricingTable.tsx | 1 - .../react/hooks/usePricingTableBase.tsx | 4 +--- .../src/next/client/hooks/usePricingTable.tsx | 1 + 10 files changed, 35 insertions(+), 29 deletions(-) diff --git a/package/src/libraries/backend/routes/productRoutes.ts b/package/src/libraries/backend/routes/productRoutes.ts index 43a247f..fa9cefd 100644 --- a/package/src/libraries/backend/routes/productRoutes.ts +++ b/package/src/libraries/backend/routes/productRoutes.ts @@ -7,15 +7,17 @@ const listProductsHandler = withAuth({ fn: async ({ autumn, customer_id, - entity_id, + searchParams, }: { autumn: Autumn; customer_id: string; - entity_id?: string; + searchParams?: { + entityId?: string; + }; }) => { return await autumn.products.list({ - customer_id, - entity_id, + customer_id: customer_id, + entity_id: searchParams?.entityId, }); }, requireCustomer: false, diff --git a/package/src/libraries/react/AutumnContext.tsx b/package/src/libraries/react/AutumnContext.tsx index 6dcd7b1..996b5dd 100644 --- a/package/src/libraries/react/AutumnContext.tsx +++ b/package/src/libraries/react/AutumnContext.tsx @@ -16,6 +16,7 @@ export interface AutumnContextParams { client: AutumnClient; // Internal + entityId?: string | null; paywallDialog: AutumnDialogContext; attachDialog: AutumnDialogContext; paywallRef: React.RefObject; @@ -27,20 +28,22 @@ export const AutumnContext = createContext({ client: new AutumnClient({ backendUrl: "" }), + entityId: undefined, + paywallDialog: { props: null, - setProps: () => {}, + setProps: () => { }, open: false, - setOpen: () => {}, - setComponent: () => {}, + setOpen: () => { }, + setComponent: () => { }, }, attachDialog: { props: null, - setProps: () => {}, + setProps: () => { }, open: false, - setOpen: () => {}, - setComponent: () => {}, + setOpen: () => { }, + setComponent: () => { }, }, paywallRef: { current: null }, @@ -50,10 +53,12 @@ export const useAutumnContext = ({ AutumnContext, name, errorIfNotInitialized = true, + entityId, }: { AutumnContext: React.Context; name: string; errorIfNotInitialized?: boolean; + entityId?: string | null; }) => { const context = useContext(AutumnContext); diff --git a/package/src/libraries/react/client/ReactAutumnClient.tsx b/package/src/libraries/react/client/ReactAutumnClient.tsx index 702edda..9b3a7f9 100644 --- a/package/src/libraries/react/client/ReactAutumnClient.tsx +++ b/package/src/libraries/react/client/ReactAutumnClient.tsx @@ -103,7 +103,7 @@ export interface IAutumnClient { }; products: { - list(): AutumnPromise<{ list: Product[] }>; + list(args: any): AutumnPromise<{ list: Product[] }>; }; } @@ -211,8 +211,7 @@ export class AutumnClient implements IAutumnClient { `[Autumn] Detected CORS credentials: ${corsResult.includeCredentials}` ); console.warn( - `[Autumn] To disable this warning, you can set includeCredentials={${ - corsResult.includeCredentials ? "true" : "false" + `[Autumn] To disable this warning, you can set includeCredentials={${corsResult.includeCredentials ? "true" : "false" }} in ` ); this.includeCredentials = corsResult.includeCredentials; @@ -260,10 +259,10 @@ export class AutumnClient implements IAutumnClient { body = method === "POST" ? { - ...body, - [this.camelCase ? "customerData" : "customer_data"]: - this.customerData || undefined, - } + ...body, + [this.camelCase ? "customerData" : "customer_data"]: + this.customerData || undefined, + } : undefined; const includeCredentials = await this.shouldIncludeCredentials(); diff --git a/package/src/libraries/react/client/types/clientProdTypes.ts b/package/src/libraries/react/client/types/clientProdTypes.ts index ebe1bbe..6d1e736 100644 --- a/package/src/libraries/react/client/types/clientProdTypes.ts +++ b/package/src/libraries/react/client/types/clientProdTypes.ts @@ -1,4 +1,3 @@ export interface ListProductsParams { - customerId?: string; entityId?: string; } diff --git a/package/src/libraries/react/components/pricing-table/pricing-table-synced.tsx b/package/src/libraries/react/components/pricing-table/pricing-table-synced.tsx index 29af4ac..27f5de3 100644 --- a/package/src/libraries/react/components/pricing-table/pricing-table-synced.tsx +++ b/package/src/libraries/react/components/pricing-table/pricing-table-synced.tsx @@ -13,13 +13,15 @@ import { Loader2 } from "lucide-react"; export default function PricingTable({ productDetails, + entityId, }: { productDetails?: ProductDetails[]; + entityId?: string; }) { const { customer, checkout } = useCustomer({ errorOnNotFound: false }); const [isAnnual, setIsAnnual] = useState(false); - const { products, isLoading, error } = usePricingTable({ productDetails }); + const { products, isLoading, error } = usePricingTable({ productDetails, entityId }); if (isLoading) { return ( @@ -102,7 +104,7 @@ const PricingTableContext = createContext<{ showFeatures: boolean; }>({ isAnnualToggle: false, - setIsAnnualToggle: () => {}, + setIsAnnualToggle: () => { }, products: [], showFeatures: true, }); @@ -206,8 +208,8 @@ export const PricingCard = ({ const isRecommended = productDisplay?.recommend_text ? true : false; const mainPriceDisplay = product.properties?.is_free ? { - primary_text: "Free", - } + primary_text: "Free", + } : product.items[0].display; const featureItems = product.properties?.is_free @@ -219,7 +221,7 @@ export const PricingCard = ({ className={cn( " au-w-full au-h-full au-py-6 au-text-foreground au-border au-rounded-lg au-shadow-sm au-max-w-xl", isRecommended && - "lg:au--translate-y-6 lg:au-shadow-lg dark:au-shadow-zinc-800/80 lg:au-h-[calc(100%+48px)] au-bg-secondary/40", + "lg:au--translate-y-6 lg:au-shadow-lg dark:au-shadow-zinc-800/80 lg:au-h-[calc(100%+48px)] au-bg-secondary/40", className )} > diff --git a/package/src/libraries/react/hooks/helpers/useAutumnBase.tsx b/package/src/libraries/react/hooks/helpers/useAutumnBase.tsx index e2882d8..6b1efc9 100644 --- a/package/src/libraries/react/hooks/helpers/useAutumnBase.tsx +++ b/package/src/libraries/react/hooks/helpers/useAutumnBase.tsx @@ -33,7 +33,7 @@ export const useAutumnBase = ({ }) => { const { attachDialog, paywallDialog } = context || {}; - const { refetch: refetchPricingTable } = usePricingTableBase({ client }); + const { refetch: refetchPricingTable } = usePricingTableBase({ client, params: { entityId: context?.entityId || undefined } }); const attachWithoutDialog = async (params: AttachParams) => { const result = await client.attach(params); diff --git a/package/src/libraries/react/hooks/useEntityBase.tsx b/package/src/libraries/react/hooks/useEntityBase.tsx index 4cfd2d0..8796077 100644 --- a/package/src/libraries/react/hooks/useEntityBase.tsx +++ b/package/src/libraries/react/hooks/useEntityBase.tsx @@ -26,6 +26,7 @@ export const useEntityBase = ({ const context = useAutumnContext({ AutumnContext, name: "useEntity", + entityId, }); const fetchEntity = async () => { @@ -33,7 +34,7 @@ export const useEntityBase = ({ return null; } - + const { data, error } = await client.entities.get(entityId, params); if (error) { diff --git a/package/src/libraries/react/hooks/usePricingTable.tsx b/package/src/libraries/react/hooks/usePricingTable.tsx index 8c99649..08fd481 100644 --- a/package/src/libraries/react/hooks/usePricingTable.tsx +++ b/package/src/libraries/react/hooks/usePricingTable.tsx @@ -5,7 +5,6 @@ import { AutumnContext, useAutumnContext } from "@/AutumnContext"; export const usePricingTable = (params?: { productDetails?: ProductDetails[]; entityId?: string; - customerId?: string; }) => { const context = useAutumnContext({ AutumnContext, diff --git a/package/src/libraries/react/hooks/usePricingTableBase.tsx b/package/src/libraries/react/hooks/usePricingTableBase.tsx index cc75ad8..6e1342b 100644 --- a/package/src/libraries/react/hooks/usePricingTableBase.tsx +++ b/package/src/libraries/react/hooks/usePricingTableBase.tsx @@ -196,13 +196,11 @@ export const usePricingTableBase = ({ params?: { productDetails?: ProductDetails[]; entityId?: string; - customerId?: string; }; }) => { const fetcher = async () => { try { const { data, error } = await client.products.list({ - customerId: params?.customerId, entityId: params?.entityId, }); if (error) throw error; @@ -217,7 +215,7 @@ export const usePricingTableBase = ({ }; const { data, error, mutate } = useSWR( - ["pricing-table", client.backendUrl], + ["pricing-table", client.backendUrl, params?.entityId], fetcher, { ...defaultSWRConfig } ); diff --git a/package/src/next/client/hooks/usePricingTable.tsx b/package/src/next/client/hooks/usePricingTable.tsx index ecd7656..aad3311 100644 --- a/package/src/next/client/hooks/usePricingTable.tsx +++ b/package/src/next/client/hooks/usePricingTable.tsx @@ -4,6 +4,7 @@ import { ProductDetails } from "../../../libraries/react/client/types/clientPric export const usePricingTable = (params?: { productDetails?: ProductDetails[]; + entityId?: string; }) => { const context = useAutumnContext({ AutumnContext,