@dodopayments/convex 0.2.3 → 0.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,6 +22,8 @@ npm install @dodopayments/convex
22
22
 
23
23
  ## Quick Start
24
24
 
25
+ > **Note:** This component does not define a schema. Define your own schema based on your application's needs.
26
+
25
27
  ### 1. Add Component to Convex Config
26
28
 
27
29
  ```typescript
@@ -40,12 +42,6 @@ Create a [Dodo Payments](https://dodopayments.com) account and get the API_KEY a
40
42
 
41
43
  Add your environment variables in the Convex dashboard (**Settings** → **Environment Variables**). You can open the dashboard by running:
42
44
 
43
- ```env
44
- DODO_PAYMENTS_API_KEY=your-dodo-payments-api-key
45
- DODO_PAYMENTS_ENVIRONMENT=test_mode
46
- DODO_PAYMENTS_WEBHOOK_SECRET=your-webhook-secret (if using webhooks)
47
- ```
48
-
49
45
  ```sh
50
46
  npx convex dashboard
51
47
  ```
@@ -60,67 +56,121 @@ Set the following variables:
60
56
 
61
57
  ### 3. Create Internal Query
62
58
 
63
- First, create an internal query to fetch users from your database. This will be used in the payment functions to identify customers.
59
+ First, create an internal query to fetch customers from your database. This will be used in the payment functions to identify customers.
64
60
 
65
61
  ```typescript
66
- // convex/users.ts
62
+ // convex/customers.ts
67
63
  import { internalQuery } from "./_generated/server";
68
64
  import { v } from "convex/values";
69
65
 
70
- // Internal query to fetch user by auth ID
66
+ // Internal query to fetch customer by auth ID
67
+ // Customize this based on your database schema and authentication provider
71
68
  export const getByAuthId = internalQuery({
72
69
  args: { authId: v.string() },
73
70
  handler: async (ctx, { authId }) => {
74
71
  return await ctx.db
75
- .query("users")
72
+ .query("customers")
76
73
  .withIndex("by_auth_id", (q) => q.eq("authId", authId))
77
74
  .first();
78
75
  },
79
76
  });
80
77
  ```
81
78
 
82
- ### 4. Create Payment Functions
79
+ ### 4. Configure DodoPayments Component
83
80
 
84
81
  ```typescript
85
82
  // convex/dodo.ts
86
- import { DodoPayments } from "@dodopayments/convex";
83
+ import { DodoPayments, DodoPaymentsClientConfig } from "@dodopayments/convex";
87
84
  import { components } from "./_generated/api";
88
85
  import { internal } from "./_generated/api";
89
86
 
90
87
  export const dodo = new DodoPayments(components.dodopayments, {
91
- // This function maps your Convex user to a Dodo Payments customer
92
- // Customize it based on your authentication provider and user database
88
+ // This function maps your Convex customer to a Dodo Payments customer
89
+ // Customize it based on your authentication provider and customer database
93
90
 
94
91
  identify: async (ctx) => {
95
92
  const identity = await ctx.auth.getUserIdentity();
96
93
  if (!identity) {
97
- return null; // User is not logged in
94
+ return null; // Customer is not logged in
98
95
  }
99
96
 
100
- // Use ctx.runQuery() to lookup user from your database
101
- const user = await ctx.runQuery(internal.users.getByAuthId, {
97
+ // Use ctx.runQuery() to lookup customer from your database
98
+ const customer = await ctx.runQuery(internal.customers.getByAuthId, {
102
99
  authId: identity.subject,
103
100
  });
104
101
 
105
- if (!user) {
106
- return null; // User not found in database
102
+ if (!customer) {
103
+ return null; // Customer not found in database
107
104
  }
108
105
 
109
106
  return {
110
- dodoCustomerId: user.dodoCustomerId, // Replace user.dodoCustomerId with your field storing Dodo Payments customer ID
107
+ dodoCustomerId: customer.dodoCustomerId, // Replace customer.dodoCustomerId with your field storing Dodo Payments customer ID
111
108
  };
112
109
  },
113
110
  apiKey: process.env.DODO_PAYMENTS_API_KEY!,
114
111
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT as
115
112
  | "test_mode"
116
113
  | "live_mode",
117
- });
114
+ } as DodoPaymentsClientConfig);
118
115
 
119
116
  // Export the API methods for use in your app
120
117
  export const { checkout, customerPortal } = dodo.api();
121
118
  ```
122
119
 
123
- ### 5. Set Up Webhooks (Optional)
120
+ ### 5. Define Payment Actions
121
+
122
+ ```typescript
123
+ // convex/payments.ts
124
+ import { action } from "./_generated/server";
125
+ import { v } from "convex/values";
126
+ import { checkout } from "./dodo";
127
+
128
+ export const createCheckout = action({
129
+ args: {
130
+ product_cart: v.array(
131
+ v.object({
132
+ product_id: v.string(),
133
+ quantity: v.number(),
134
+ }),
135
+ ),
136
+ returnUrl: v.optional(v.string()),
137
+ },
138
+ handler: async (ctx, args) => {
139
+ return await checkout(ctx, {
140
+ payload: {
141
+ product_cart: args.product_cart,
142
+ return_url: args.returnUrl,
143
+ billing_currency: "USD",
144
+ feature_flags: {
145
+ allow_discount_code: true,
146
+ },
147
+ },
148
+ });
149
+ },
150
+ });
151
+ ```
152
+
153
+ ### 6. Frontend Usage
154
+
155
+ ```tsx
156
+ import { useAction } from "convex/react";
157
+ import { api } from "../convex/_generated/api";
158
+
159
+ export function CheckoutButton() {
160
+ const createCheckout = useAction(api.payments.createCheckout);
161
+
162
+ const handleCheckout = async () => {
163
+ const { checkout_url } = await createCheckout({
164
+ product_cart: [{ product_id: "prod_123", quantity: 1 }],
165
+ });
166
+ window.location.href = checkout_url;
167
+ };
168
+
169
+ return <button onClick={handleCheckout}>Buy Now</button>;
170
+ }
171
+ ```
172
+
173
+ ### 7. Set Up Webhooks (Optional)
124
174
 
125
175
  For handling Dodo Payments webhooks, create a file `convex/http.ts`:
126
176
 
@@ -178,59 +228,6 @@ Add your webhook secret in the Convex dashboard (**Settings** → **Environment
178
228
 
179
229
  - `DODO_PAYMENTS_WEBHOOK_SECRET=your-webhook-secret`
180
230
 
181
- ### 6. Define Payment Actions
182
-
183
- ```typescript
184
- // convex/payments.ts
185
- import { action } from "./_generated/server";
186
- import { v } from "convex/values";
187
- import { checkout } from "./dodo";
188
-
189
- export const createCheckout = action({
190
- args: {
191
- product_cart: v.array(
192
- v.object({
193
- product_id: v.string(),
194
- quantity: v.number(),
195
- }),
196
- ),
197
- returnUrl: v.optional(v.string()),
198
- },
199
- handler: async (ctx, args) => {
200
- return await checkout(ctx, {
201
- payload: {
202
- product_cart: args.product_cart,
203
- return_url: args.returnUrl,
204
- billing_currency: "USD",
205
- feature_flags: {
206
- allow_discount_code: true,
207
- },
208
- },
209
- });
210
- },
211
- });
212
- ```
213
-
214
- ### 7. Frontend Usage
215
-
216
- ```tsx
217
- import { useAction } from "convex/react";
218
- import { api } from "../convex/_generated/api";
219
-
220
- export function CheckoutButton() {
221
- const createCheckout = useAction(api.payments.createCheckout);
222
-
223
- const handleCheckout = async () => {
224
- const { checkout_url } = await createCheckout({
225
- product_cart: [{ product_id: "prod_123", quantity: 1 }],
226
- });
227
- window.location.href = checkout_url;
228
- };
229
-
230
- return <button onClick={handleCheckout}>Buy Now</button>;
231
- }
232
- ```
233
-
234
231
  ---
235
232
 
236
233
  ## Prompt for LLM
@@ -282,18 +279,19 @@ Then add the required environment variables (e.g., DODO_PAYMENTS_API_KEY, DODO_P
282
279
  DODO_PAYMENTS_API_KEY=your-api-key
283
280
  DODO_PAYMENTS_ENVIRONMENT=test_mode
284
281
 
285
- Step 3: Create an internal query to fetch users from your database.
282
+ Step 3: Create an internal query to fetch customers from your database.
286
283
 
287
- // convex/users.ts
284
+ // convex/customers.ts
288
285
  import { internalQuery } from "./_generated/server";
289
286
  import { v } from "convex/values";
290
287
 
291
- // Internal query to fetch user by auth ID
288
+ // Internal query to fetch customer by auth ID
289
+ // Customize this based on your database schema and authentication provider
292
290
  export const getByAuthId = internalQuery({
293
291
  args: { authId: v.string() },
294
292
  handler: async (ctx, { authId }) => {
295
293
  return await ctx.db
296
- .query("users")
294
+ .query("customers")
297
295
  .withIndex("by_auth_id", (q) => q.eq("authId", authId))
298
296
  .first();
299
297
  },
@@ -302,13 +300,13 @@ export const getByAuthId = internalQuery({
302
300
  Step 4: Create your payment functions file.
303
301
 
304
302
  // convex/dodo.ts
305
- import { DodoPayments } from "@dodopayments/convex";
303
+ import { DodoPayments, DodoPaymentsClientConfig } from "@dodopayments/convex";
306
304
  import { components } from "./_generated/api";
307
305
  import { internal } from "./_generated/api";
308
306
 
309
307
  export const dodo = new DodoPayments(components.dodopayments, {
310
308
  // This function maps your Convex user to a Dodo Payments customer
311
- // Customize it based on your authentication provider and user database
309
+ // Customize it based on your authentication provider and customer database
312
310
 
313
311
  identify: async (ctx) => {
314
312
  const identity = await ctx.auth.getUserIdentity();
@@ -316,22 +314,22 @@ export const dodo = new DodoPayments(components.dodopayments, {
316
314
  return null; // User is not logged in
317
315
  }
318
316
 
319
- // Use ctx.runQuery() to lookup user from your database
320
- const user = await ctx.runQuery(internal.users.getByAuthId, {
317
+ // Use ctx.runQuery() to lookup customer from your database
318
+ const customer = await ctx.runQuery(internal.customers.getByAuthId, {
321
319
  authId: identity.subject,
322
320
  });
323
321
 
324
- if (!user) {
325
- return null; // User not found in database
322
+ if (!customer) {
323
+ return null; // Customer not found in database
326
324
  }
327
325
 
328
326
  return {
329
- dodoCustomerId: user.dodoCustomerId, // Replace user.dodoCustomerId with your field storing Dodo Payments customer ID
327
+ dodoCustomerId: customer.dodoCustomerId, // Replace customer.dodoCustomerId with your field storing Dodo Payments customer ID
330
328
  };
331
329
  },
332
330
  apiKey: process.env.DODO_PAYMENTS_API_KEY!,
333
331
  environment: process.env.DODO_PAYMENTS_ENVIRONMENT as "test_mode" | "live_mode",
334
- });
332
+ } as DodoPaymentsClientConfig);
335
333
 
336
334
  // Export the API methods for use in your app
337
335
  export const { checkout, customerPortal } = dodo.api();
@@ -1,12 +1,15 @@
1
1
  import type { CheckoutSessionPayload } from "@dodopayments/core/checkout";
2
- import { GenericActionCtx } from "convex/server";
2
+ import { GenericActionCtx, FunctionReference, GenericDataModel } from "convex/server";
3
3
  type CustomerPortalArgs = {
4
4
  send_email?: boolean;
5
5
  };
6
+ type RunActionCtx = {
7
+ runAction: GenericActionCtx<GenericDataModel>["runAction"];
8
+ };
6
9
  export interface DodoPaymentsComponent {
7
10
  lib: {
8
- checkout: any;
9
- customerPortal: any;
11
+ checkout: FunctionReference<"action", "internal">;
12
+ customerPortal: FunctionReference<"action", "internal">;
10
13
  };
11
14
  }
12
15
  export type DodoPaymentsClientConfig = {
@@ -28,14 +31,18 @@ export declare class DodoPayments {
28
31
  * Creates a Dodo Payments checkout session.
29
32
  * Uses session checkout with full feature support.
30
33
  */
31
- checkout: (ctx: any, args: {
34
+ checkout: (ctx: RunActionCtx, args: {
32
35
  payload: CheckoutSessionPayload;
33
- }) => Promise<any>;
36
+ }) => Promise<{
37
+ checkout_url: string;
38
+ }>;
34
39
  /**
35
40
  * Retrieves a URL for the customer portal.
36
- * This function is designed to be called from a public Convex query in your app.
41
+ * Requires the user to be identified via the identify function in the config.
37
42
  */
38
- customerPortal: (ctx: any, args?: CustomerPortalArgs) => Promise<any>;
43
+ customerPortal: (ctx: any, args?: CustomerPortalArgs) => Promise<{
44
+ portal_url: string;
45
+ }>;
39
46
  };
40
47
  }
41
48
  export {};
@@ -1,9 +1,13 @@
1
1
  export declare const checkout: import("convex/server").RegisteredAction<"public", {
2
+ apiKey: string;
3
+ environment: "test_mode" | "live_mode";
2
4
  payload: {
3
5
  customer?: {
4
- email?: string | undefined;
5
6
  name?: string | undefined;
6
7
  phone_number?: string | undefined;
8
+ email: string;
9
+ } | {
10
+ customer_id: string;
7
11
  } | undefined;
8
12
  billing_address?: {
9
13
  street?: string | undefined;
@@ -23,6 +27,7 @@ export declare const checkout: import("convex/server").RegisteredAction<"public"
23
27
  theme?: string | undefined;
24
28
  show_order_details?: boolean | undefined;
25
29
  show_on_demand_tag?: boolean | undefined;
30
+ force_language?: string | undefined;
26
31
  } | undefined;
27
32
  feature_flags?: {
28
33
  allow_currency_selection?: boolean | undefined;
@@ -33,14 +38,25 @@ export declare const checkout: import("convex/server").RegisteredAction<"public"
33
38
  } | undefined;
34
39
  subscription_data?: {
35
40
  trial_period_days?: number | undefined;
41
+ on_demand?: {
42
+ product_price?: number | undefined;
43
+ product_currency?: string | undefined;
44
+ product_description?: string | undefined;
45
+ adaptive_currency_fees_inclusive?: boolean | undefined;
46
+ mandate_only: boolean;
47
+ } | undefined;
36
48
  } | undefined;
49
+ force_3ds?: boolean | undefined;
37
50
  product_cart: {
51
+ addons?: {
52
+ quantity: number;
53
+ addon_id: string;
54
+ }[] | undefined;
55
+ amount?: number | undefined;
38
56
  product_id: string;
39
57
  quantity: number;
40
58
  }[];
41
59
  };
42
- apiKey: string;
43
- environment: "test_mode" | "live_mode";
44
60
  }, Promise<{
45
61
  checkout_url: string;
46
62
  }>>;
@@ -1,18 +1,25 @@
1
1
  import { action } from './_generated/server.js';
2
2
  import { v } from 'convex/values';
3
- import { buildCheckoutUrl } from '../packages/core/dist/chunk-YWHOVR2R.js';
3
+ import { buildCheckoutUrl } from '../packages/core/dist/chunk-BVTJMX2W.js';
4
4
  import DodoPayments from 'dodopayments';
5
5
 
6
6
  const checkoutSessionPayloadValidator = v.object({
7
7
  product_cart: v.array(v.object({
8
8
  product_id: v.string(),
9
9
  quantity: v.number(),
10
+ addons: v.optional(v.array(v.object({
11
+ addon_id: v.string(),
12
+ quantity: v.number(),
13
+ }))),
14
+ amount: v.optional(v.number()),
10
15
  })),
11
- customer: v.optional(v.object({
12
- email: v.optional(v.string()),
16
+ customer: v.optional(v.union(v.object({
17
+ email: v.string(),
13
18
  name: v.optional(v.string()),
14
19
  phone_number: v.optional(v.string()),
15
- })),
20
+ }), v.object({
21
+ customer_id: v.string(),
22
+ }))),
16
23
  billing_address: v.optional(v.object({
17
24
  street: v.optional(v.string()),
18
25
  city: v.optional(v.string()),
@@ -31,6 +38,7 @@ const checkoutSessionPayloadValidator = v.object({
31
38
  theme: v.optional(v.string()),
32
39
  show_order_details: v.optional(v.boolean()),
33
40
  show_on_demand_tag: v.optional(v.boolean()),
41
+ force_language: v.optional(v.string()),
34
42
  })),
35
43
  feature_flags: v.optional(v.object({
36
44
  allow_currency_selection: v.optional(v.boolean()),
@@ -41,7 +49,15 @@ const checkoutSessionPayloadValidator = v.object({
41
49
  })),
42
50
  subscription_data: v.optional(v.object({
43
51
  trial_period_days: v.optional(v.number()),
52
+ on_demand: v.optional(v.object({
53
+ mandate_only: v.boolean(),
54
+ product_price: v.optional(v.number()),
55
+ product_currency: v.optional(v.string()),
56
+ product_description: v.optional(v.string()),
57
+ adaptive_currency_fees_inclusive: v.optional(v.boolean()),
58
+ })),
44
59
  })),
60
+ force_3ds: v.optional(v.boolean()),
45
61
  });
46
62
  const checkout = action({
47
63
  args: {
@@ -1 +1 @@
1
- {"version":3,"file":"lib.js","sources":["../../src/component/lib.ts"],"sourcesContent":["import { action } from \"../component/_generated/server\";\nimport { v } from \"convex/values\";\nimport {\n buildCheckoutUrl,\n type CheckoutSessionPayload,\n} from \"@dodopayments/core/checkout\";\nimport DodoPayments from \"dodopayments\";\n\nconst checkoutSessionPayloadValidator = v.object({\n product_cart: v.array(\n v.object({\n product_id: v.string(),\n quantity: v.number(),\n }),\n ),\n customer: v.optional(\n v.object({\n email: v.optional(v.string()),\n name: v.optional(v.string()),\n phone_number: v.optional(v.string()),\n }),\n ),\n billing_address: v.optional(\n v.object({\n street: v.optional(v.string()),\n city: v.optional(v.string()),\n state: v.optional(v.string()),\n country: v.string(),\n zipcode: v.optional(v.string()),\n }),\n ),\n return_url: v.optional(v.string()),\n allowed_payment_method_types: v.optional(v.array(v.string())),\n billing_currency: v.optional(v.string()),\n show_saved_payment_methods: v.optional(v.boolean()),\n confirm: v.optional(v.boolean()),\n discount_code: v.optional(v.string()),\n metadata: v.optional(v.record(v.string(), v.string())),\n customization: v.optional(\n v.object({\n theme: v.optional(v.string()),\n show_order_details: v.optional(v.boolean()),\n show_on_demand_tag: v.optional(v.boolean()),\n }),\n ),\n feature_flags: v.optional(\n v.object({\n allow_currency_selection: v.optional(v.boolean()),\n allow_discount_code: v.optional(v.boolean()),\n allow_phone_number_collection: v.optional(v.boolean()),\n allow_tax_id: v.optional(v.boolean()),\n always_create_new_customer: v.optional(v.boolean()),\n }),\n ),\n subscription_data: v.optional(\n v.object({\n trial_period_days: v.optional(v.number()),\n }),\n ),\n});\n\nexport const checkout = action({\n args: {\n payload: checkoutSessionPayloadValidator,\n apiKey: v.string(),\n environment: v.union(v.literal(\"test_mode\"), v.literal(\"live_mode\")),\n },\n returns: v.object({ checkout_url: v.string() }),\n handler: async (\n _,\n { payload, apiKey, environment },\n ): Promise<{ checkout_url: string }> => {\n const checkoutUrl = await buildCheckoutUrl({\n sessionPayload: payload as CheckoutSessionPayload,\n bearerToken: apiKey,\n environment,\n type: \"session\",\n });\n return { checkout_url: checkoutUrl };\n },\n});\n\nexport const customerPortal = action({\n args: {\n dodoCustomerId: v.string(),\n send_email: v.optional(v.boolean()),\n apiKey: v.string(),\n environment: v.union(v.literal(\"test_mode\"), v.literal(\"live_mode\")),\n },\n returns: v.object({ portal_url: v.string() }),\n handler: async (\n _,\n { dodoCustomerId, send_email, apiKey, environment },\n ): Promise<{ portal_url: string }> => {\n if (!dodoCustomerId) {\n throw new Error(\"dodoCustomerId is required for customerPortal.\");\n }\n\n const dodopayments = new DodoPayments({\n bearerToken: apiKey,\n environment,\n });\n\n const params = {\n send_email: Boolean(send_email),\n };\n\n const session = await dodopayments.customers.customerPortal.create(\n dodoCustomerId,\n params,\n );\n return { portal_url: session.link };\n },\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lib.js","sources":["../../src/component/lib.ts"],"sourcesContent":["import { action } from \"../component/_generated/server\";\nimport { v } from \"convex/values\";\nimport {\n buildCheckoutUrl,\n type CheckoutSessionPayload,\n} from \"@dodopayments/core/checkout\";\nimport DodoPayments from \"dodopayments\";\n\nconst checkoutSessionPayloadValidator = v.object({\n product_cart: v.array(\n v.object({\n product_id: v.string(),\n quantity: v.number(),\n addons: v.optional(\n v.array(\n v.object({\n addon_id: v.string(),\n quantity: v.number(),\n }),\n ),\n ),\n amount: v.optional(v.number()),\n }),\n ),\n customer: v.optional(\n v.union(\n v.object({\n email: v.string(),\n name: v.optional(v.string()),\n phone_number: v.optional(v.string()),\n }),\n v.object({\n customer_id: v.string(),\n }),\n ),\n ),\n billing_address: v.optional(\n v.object({\n street: v.optional(v.string()),\n city: v.optional(v.string()),\n state: v.optional(v.string()),\n country: v.string(),\n zipcode: v.optional(v.string()),\n }),\n ),\n return_url: v.optional(v.string()),\n allowed_payment_method_types: v.optional(v.array(v.string())),\n billing_currency: v.optional(v.string()),\n show_saved_payment_methods: v.optional(v.boolean()),\n confirm: v.optional(v.boolean()),\n discount_code: v.optional(v.string()),\n metadata: v.optional(v.record(v.string(), v.string())),\n customization: v.optional(\n v.object({\n theme: v.optional(v.string()),\n show_order_details: v.optional(v.boolean()),\n show_on_demand_tag: v.optional(v.boolean()),\n force_language: v.optional(v.string()),\n }),\n ),\n feature_flags: v.optional(\n v.object({\n allow_currency_selection: v.optional(v.boolean()),\n allow_discount_code: v.optional(v.boolean()),\n allow_phone_number_collection: v.optional(v.boolean()),\n allow_tax_id: v.optional(v.boolean()),\n always_create_new_customer: v.optional(v.boolean()),\n }),\n ),\n subscription_data: v.optional(\n v.object({\n trial_period_days: v.optional(v.number()),\n on_demand: v.optional(\n v.object({\n mandate_only: v.boolean(),\n product_price: v.optional(v.number()),\n product_currency: v.optional(v.string()),\n product_description: v.optional(v.string()),\n adaptive_currency_fees_inclusive: v.optional(v.boolean()),\n }),\n ),\n }),\n ),\n force_3ds: v.optional(v.boolean()),\n});\n\nexport const checkout = action({\n args: {\n payload: checkoutSessionPayloadValidator,\n apiKey: v.string(),\n environment: v.union(v.literal(\"test_mode\"), v.literal(\"live_mode\")),\n },\n returns: v.object({ checkout_url: v.string() }),\n handler: async (\n _,\n { payload, apiKey, environment },\n ): Promise<{ checkout_url: string }> => {\n const checkoutUrl = await buildCheckoutUrl({\n sessionPayload: payload as CheckoutSessionPayload,\n bearerToken: apiKey,\n environment,\n type: \"session\",\n });\n return { checkout_url: checkoutUrl };\n },\n});\n\nexport const customerPortal = action({\n args: {\n dodoCustomerId: v.string(),\n send_email: v.optional(v.boolean()),\n apiKey: v.string(),\n environment: v.union(v.literal(\"test_mode\"), v.literal(\"live_mode\")),\n },\n returns: v.object({ portal_url: v.string() }),\n handler: async (\n _,\n { dodoCustomerId, send_email, apiKey, environment },\n ): Promise<{ portal_url: string }> => {\n if (!dodoCustomerId) {\n throw new Error(\"dodoCustomerId is required for customerPortal.\");\n }\n\n const dodopayments = new DodoPayments({\n bearerToken: apiKey,\n environment,\n });\n\n const params = {\n send_email: Boolean(send_email),\n };\n\n const session = await dodopayments.customers.customerPortal.create(\n dodoCustomerId,\n params,\n );\n return { portal_url: session.link };\n },\n});\n"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -24,7 +24,7 @@ class DodoPayments {
24
24
  },
25
25
  /**
26
26
  * Retrieves a URL for the customer portal.
27
- * This function is designed to be called from a public Convex query in your app.
27
+ * Requires the user to be identified via the identify function in the config.
28
28
  */
29
29
  customerPortal: async (ctx, args) => {
30
30
  const identity = await this.config.identify(ctx);
@@ -5270,6 +5270,12 @@ var SubscriptionExpiredPayloadSchema = objectType({
5270
5270
  timestamp: stringType().transform((d) => new Date(d)),
5271
5271
  data: SubscriptionSchema
5272
5272
  });
5273
+ var SubscriptionUpdatedPayloadSchema = objectType({
5274
+ business_id: stringType(),
5275
+ type: literalType("subscription.updated"),
5276
+ timestamp: stringType().transform((d) => new Date(d)),
5277
+ data: SubscriptionSchema
5278
+ });
5273
5279
  var LicenseKeyCreatedPayloadSchema = objectType({
5274
5280
  business_id: stringType(),
5275
5281
  type: literalType("license_key.created"),
@@ -5298,6 +5304,7 @@ var WebhookPayloadSchema = discriminatedUnionType("type", [
5298
5304
  SubscriptionCancelledPayloadSchema,
5299
5305
  SubscriptionFailedPayloadSchema,
5300
5306
  SubscriptionExpiredPayloadSchema,
5307
+ SubscriptionUpdatedPayloadSchema,
5301
5308
  LicenseKeyCreatedPayloadSchema
5302
5309
  ]);
5303
5310
 
@@ -6226,6 +6233,9 @@ async function handleWebhookPayload(payload, config, context) {
6226
6233
  if (payload.type === "subscription.expired") {
6227
6234
  await callHandler(config.onSubscriptionExpired, payload);
6228
6235
  }
6236
+ if (payload.type === "subscription.updated") {
6237
+ await callHandler(config.onSubscriptionUpdated, payload);
6238
+ }
6229
6239
  if (payload.type === "license_key.created") {
6230
6240
  await callHandler(config.onLicenseKeyCreated, payload);
6231
6241
  }