@dodopayments/nuxt 0.1.4 → 0.2.0

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
@@ -32,9 +32,9 @@ export default defineNuxtConfig({
32
32
  bearerToken: process.env.NUXT_PRIVATE_BEARER_TOKEN,
33
33
  webhookKey: process.env.NUXT_PRIVATE_BEARER_TOKEN,
34
34
  environment: process.env.NUXT_PRIVATE_ENVIRONMENT,
35
- returnUrl: process.env.NUXT_PRIVATE_RETURNURL
35
+ returnUrl: process.env.NUXT_PRIVATE_RETURNURL,
36
36
  },
37
- }
37
+ },
38
38
  });
39
39
  ```
40
40
 
@@ -47,11 +47,11 @@ export default defineEventHandler((event) => {
47
47
  const {
48
48
  private: { bearerToken, environment, returnUrl },
49
49
  } = useRuntimeConfig();
50
-
50
+
51
51
  const handler = checkoutHandler({
52
52
  bearerToken: bearerToken,
53
- environment: env,
54
- returnUrl: returnUrl
53
+ environment: environment,
54
+ returnUrl: returnUrl,
55
55
  });
56
56
 
57
57
  return handler(event);
@@ -60,7 +60,6 @@ export default defineEventHandler((event) => {
60
60
 
61
61
  - Accepts GET requests with `productId` as a query parameter.
62
62
 
63
-
64
63
  ### 3. Customer Portal API Route
65
64
 
66
65
  Create a new file at `server/routes/api/customer-portal.get.ts`:
@@ -68,16 +67,16 @@ Create a new file at `server/routes/api/customer-portal.get.ts`:
68
67
  ```ts
69
68
  export default defineEventHandler((event) => {
70
69
  const {
71
- private: { bearerToken, environment }
72
- } = useRuntimeConfig()
70
+ private: { bearerToken, environment },
71
+ } = useRuntimeConfig();
73
72
 
74
73
  const handler = customerPortalHandler({
75
74
  bearerToken,
76
75
  environment: environment,
77
- })
76
+ });
78
77
 
79
- return handler(event)
80
- })
78
+ return handler(event);
79
+ });
81
80
  ```
82
81
 
83
82
  - Accepts GET requests with `customer_id` as a query parameter.
@@ -89,20 +88,19 @@ Create a new file at `server/routes/api/webhook.post.ts`:
89
88
 
90
89
  ```ts
91
90
  export default defineEventHandler((event) => {
92
- const {
93
- private: { webhookKey }
94
- } = useRuntimeConfig()
95
-
96
- const handler = Webhooks({
97
- webhookKey: webhookKey,
98
- onPayload: async (payload: any) => {
99
- // Handle here
100
- }
101
- })
91
+ const {
92
+ private: { webhookKey },
93
+ } = useRuntimeConfig();
102
94
 
103
- return handler(event)
104
- })
95
+ const handler = Webhooks({
96
+ webhookKey: webhookKey,
97
+ onPayload: async (payload: any) => {
98
+ // Handle here
99
+ },
100
+ });
105
101
 
102
+ return handler(event);
103
+ });
106
104
  ```
107
105
 
108
106
  - Only POST requests are supported. Signature is verified using `webhookSecret`.
@@ -127,7 +125,6 @@ NUXT_PRIVATE_RETURN_URL=""
127
125
 
128
126
  ---
129
127
 
130
-
131
128
  ## Prompt for LLM
132
129
 
133
130
  ```
@@ -209,6 +206,15 @@ Dynamic Checkout (POST): Parameters are sent as a JSON body. Supports both one-t
209
206
  - Docs - One Time Payment Product: https://docs.dodopayments.com/api-reference/payments/post-payments
210
207
  - Docs - Subscription Product: https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions
211
208
 
209
+ Checkout Sessions (POST) - (Recommended) A more customizable checkout experience:
210
+ - Parameters are sent as a JSON body. Supports both one-time and recurring payments.
211
+ - Returns: {"checkout_url": "https://checkout.dodopayments.com/session/..."}
212
+ - For a complete list of supported POST body fields, refer to:
213
+ - Docs - One Time Payment Product: https://docs.dodopayments.com/api-reference/payments/post-payments
214
+ - Docs - Subscription Product: https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions
215
+ - Required fields for checkout sessions:
216
+ - product_cart (array): Array of products with product_id and quantity
217
+
212
218
  Error Handling: If productId is missing or other query parameters are invalid, the handler will return a 400 response.
213
219
 
214
220
  If Customer Portal API Route is selected:
@@ -291,7 +297,6 @@ Event Routing: Calls the appropriate event handler based on the payload type. Su
291
297
  - onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>
292
298
  - onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>
293
299
  - onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>
294
- - onSubscriptionPaused?: (payload: WebhookPayload) => Promise<void>
295
300
  - onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>
296
301
  - onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>
297
302
  - onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>
@@ -312,4 +317,4 @@ webhookKey: useRuntimeConfig().private.webhookKey
312
317
  Important: Never commit sensitive environment variables directly into your version control. Use environment variables for all sensitive information.
313
318
 
314
319
  If the user needs assistance setting up environment variables for their specific deployment environment, ask them what platform they are using (e.g., Vercel, Netlify, AWS, etc.), and provide guidance.
315
- ```
320
+ ```
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dodopayments/nuxt",
3
3
  "configKey": "dodopayments",
4
- "version": "0.1.4",
4
+ "version": "0.2.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
7
7
  "unbuild": "3.5.0"
@@ -1,31 +1,69 @@
1
1
  import {
2
2
  buildCheckoutUrl,
3
3
  checkoutQuerySchema,
4
- dynamicCheckoutBodySchema
4
+ dynamicCheckoutBodySchema,
5
+ checkoutSessionPayloadSchema
5
6
  } from "@dodopayments/core/checkout";
6
- import { getQuery, readBody, sendRedirect, createError } from "h3";
7
+ import { getQuery, readBody, createError } from "h3";
7
8
  export function checkoutHandler(config) {
8
9
  return async (event) => {
9
10
  if (event.method === "POST") {
10
11
  const body = await readBody(event);
11
- const { success, data, error } = dynamicCheckoutBodySchema.safeParse(body);
12
- if (!success) {
12
+ if (config.type === "dynamic") {
13
+ const { success, data, error } = dynamicCheckoutBodySchema.safeParse(body);
14
+ if (!success) {
15
+ throw createError({
16
+ statusCode: 400,
17
+ statusMessage: "Invalid request body",
18
+ data: error.format()
19
+ });
20
+ }
21
+ try {
22
+ const url = await buildCheckoutUrl({
23
+ body: data,
24
+ ...config,
25
+ type: "dynamic"
26
+ });
27
+ return { checkout_url: url };
28
+ } catch (error2) {
29
+ throw createError({ statusCode: 400, statusMessage: error2.message });
30
+ }
31
+ } else {
32
+ const { success, data, error } = checkoutSessionPayloadSchema.safeParse(body);
33
+ if (!success) {
34
+ throw createError({
35
+ statusCode: 400,
36
+ statusMessage: "Invalid checkout session payload",
37
+ data: error.format()
38
+ });
39
+ }
40
+ try {
41
+ const url = await buildCheckoutUrl({
42
+ sessionPayload: data,
43
+ ...config,
44
+ type: "session"
45
+ });
46
+ return { checkout_url: url };
47
+ } catch (error2) {
48
+ throw createError({ statusCode: 400, statusMessage: error2.message });
49
+ }
50
+ }
51
+ } else {
52
+ const queryParams = getQuery(event);
53
+ if (!queryParams.productId) {
13
54
  throw createError({
14
55
  statusCode: 400,
15
- statusMessage: "Invalid request body",
16
- data: error.format()
56
+ statusMessage: "Please provide productId query parameter"
17
57
  });
18
58
  }
19
- try {
20
- const url = await buildCheckoutUrl({ body: data, ...config, type: "dynamic" });
21
- return sendRedirect(event, url, 302);
22
- } catch (error2) {
23
- throw createError({ statusCode: 400, statusMessage: error2.message });
24
- }
25
- } else {
26
- const queryParams = getQuery(event);
27
59
  const { success, data, error } = checkoutQuerySchema.safeParse(queryParams);
28
60
  if (!success) {
61
+ if (error.errors.some((e) => e.path.toString() === "productId")) {
62
+ throw createError({
63
+ statusCode: 400,
64
+ statusMessage: "Please provide productId query parameter"
65
+ });
66
+ }
29
67
  throw createError({
30
68
  statusCode: 400,
31
69
  statusMessage: "Invalid query parameters",
@@ -34,7 +72,7 @@ export function checkoutHandler(config) {
34
72
  }
35
73
  try {
36
74
  const url = await buildCheckoutUrl({ queryParams: data, ...config });
37
- return sendRedirect(event, url, 302);
75
+ return { checkout_url: url };
38
76
  } catch (error2) {
39
77
  throw createError({ statusCode: 400, statusMessage: error2.message });
40
78
  }
@@ -20,7 +20,10 @@ export function customerPortalHandler(config) {
20
20
  );
21
21
  return sendRedirect(event, session.link, 302);
22
22
  } catch (error) {
23
- return { status: 500, body: `Failed to create customer portal session: ${error.message}` };
23
+ return {
24
+ status: 500,
25
+ body: `Failed to create customer portal session: ${error.message}`
26
+ };
24
27
  }
25
28
  };
26
29
  }
@@ -39,7 +39,10 @@ export function Webhooks(config) {
39
39
  try {
40
40
  payload = JSON.parse(rawString);
41
41
  } catch {
42
- throw createError({ statusCode: 400, statusMessage: "Invalid JSON payload" });
42
+ throw createError({
43
+ statusCode: 400,
44
+ statusMessage: "Invalid JSON payload"
45
+ });
43
46
  }
44
47
  const { success, data, error } = WebhookPayloadSchema.safeParse(payload);
45
48
  if (!success) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dodopayments/nuxt",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "Dodo Payments Nuxt integration",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -20,7 +20,7 @@
20
20
  "dev": "rollup -c -w"
21
21
  },
22
22
  "dependencies": {
23
- "@dodopayments/core": "^0.1.13",
23
+ "@dodopayments/core": "^0.2.0",
24
24
  "@nuxt/module-builder": "^1.0.1"
25
25
  },
26
26
  "devDependencies": {