@dodopayments/better-auth 1.5.0 → 1.6.2

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.
Files changed (63) hide show
  1. package/README.md +75 -5
  2. package/dist/{chunk-R5TTSJK4.js → chunk-527Y7FSE.js} +28 -19
  3. package/dist/chunk-527Y7FSE.js.map +1 -0
  4. package/dist/{chunk-65YIVTFE.js → chunk-6VDYFSNJ.js} +6 -6
  5. package/dist/chunk-6VDYFSNJ.js.map +1 -0
  6. package/dist/{chunk-TOPOAYYO.js → chunk-EGRIWRWP.js} +6 -3
  7. package/dist/chunk-EGRIWRWP.js.map +1 -0
  8. package/dist/{chunk-HHIXOUFD.js → chunk-XXIDSJPK.js} +4 -4
  9. package/dist/chunk-XXIDSJPK.js.map +1 -0
  10. package/dist/{chunk-DTOB4IQZ.js → chunk-YCUWFLKK.js} +15 -12
  11. package/dist/chunk-YCUWFLKK.js.map +1 -0
  12. package/dist/{chunk-ARA27DRZ.js → chunk-ZA3TNX5K.js} +11 -9
  13. package/dist/chunk-ZA3TNX5K.js.map +1 -0
  14. package/dist/client.d.cts +1 -2
  15. package/dist/client.d.ts +1 -2
  16. package/dist/hooks/customer.cjs +27 -18
  17. package/dist/hooks/customer.cjs.map +1 -1
  18. package/dist/hooks/customer.d.cts +1 -2
  19. package/dist/hooks/customer.d.ts +1 -2
  20. package/dist/hooks/customer.js +1 -1
  21. package/dist/index.cjs +63 -46
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +2 -3
  24. package/dist/index.d.ts +2 -3
  25. package/dist/index.js +7 -7
  26. package/dist/index.js.map +1 -1
  27. package/dist/plugins/checkout.cjs +5 -5
  28. package/dist/plugins/checkout.cjs.map +1 -1
  29. package/dist/plugins/checkout.d.cts +2 -3
  30. package/dist/plugins/checkout.d.ts +2 -3
  31. package/dist/plugins/checkout.js +1 -1
  32. package/dist/plugins/portal.cjs +18 -12
  33. package/dist/plugins/portal.cjs.map +1 -1
  34. package/dist/plugins/portal.d.cts +2 -3
  35. package/dist/plugins/portal.d.ts +2 -3
  36. package/dist/plugins/portal.js +2 -2
  37. package/dist/plugins/usage.cjs +14 -9
  38. package/dist/plugins/usage.cjs.map +1 -1
  39. package/dist/plugins/usage.d.cts +6 -107
  40. package/dist/plugins/usage.d.ts +6 -107
  41. package/dist/plugins/usage.js +2 -2
  42. package/dist/plugins/webhooks.cjs +3 -3
  43. package/dist/plugins/webhooks.cjs.map +1 -1
  44. package/dist/plugins/webhooks.d.cts +2 -3
  45. package/dist/plugins/webhooks.d.ts +2 -3
  46. package/dist/plugins/webhooks.js +1 -1
  47. package/dist/{types-4JE4OwKb.d.cts → types-D0tVSLaf.d.cts} +122 -10
  48. package/dist/{types-B9rx1bt7.d.ts → types-D0tVSLaf.d.ts} +122 -10
  49. package/dist/types.cjs.map +1 -1
  50. package/dist/types.d.cts +1 -2
  51. package/dist/types.d.ts +1 -2
  52. package/dist/utils.cjs +5 -2
  53. package/dist/utils.cjs.map +1 -1
  54. package/dist/utils.d.cts +8 -1
  55. package/dist/utils.d.ts +8 -1
  56. package/dist/utils.js +1 -1
  57. package/package.json +1 -1
  58. package/dist/chunk-65YIVTFE.js.map +0 -1
  59. package/dist/chunk-ARA27DRZ.js.map +0 -1
  60. package/dist/chunk-DTOB4IQZ.js.map +0 -1
  61. package/dist/chunk-HHIXOUFD.js.map +0 -1
  62. package/dist/chunk-R5TTSJK4.js.map +0 -1
  63. package/dist/chunk-TOPOAYYO.js.map +0 -1
package/README.md CHANGED
@@ -188,6 +188,19 @@ webhooks({
188
188
  - **`client`** (required) - DodoPayments client instance
189
189
  - **`createCustomerOnSignUp`** (optional) - Auto-create customers on user signup
190
190
  - **`use`** (required) - Array of plugins to enable (checkout, portal, webhooks)
191
+ - **`getCustomerParams`** (optional) - Function that receives the BetterAuth `User` and returns extra fields to attach to the DodoPayments customer on creation and update (e.g. `metadata`, `phone_number`)
192
+
193
+ ```typescript
194
+ dodopayments({
195
+ client: dodoPayments,
196
+ createCustomerOnSignUp: true,
197
+ use: [portal()],
198
+ getCustomerParams: (user) => ({
199
+ metadata: { userId: user.id },
200
+ phone_number: user.phoneNumber ?? null,
201
+ }),
202
+ })
203
+ ```
191
204
 
192
205
  ### Checkout Plugin Options
193
206
 
@@ -256,6 +269,11 @@ export const { auth, endpoints, client } = BetterAuth({
256
269
  client: dodoPayments,
257
270
  createCustomerOnSignUp: true, // Auto-create customers on signup
258
271
  use: [], // We'll add plugins here in Stage 2
272
+ // Optional: attach metadata or phone_number to DodoPayments customer records
273
+ // getCustomerParams: (user) => ({
274
+ // metadata: { userId: user.id },
275
+ // phone_number: user.phoneNumber ?? null,
276
+ // }),
259
277
  }),
260
278
  ],
261
279
  });
@@ -485,9 +503,6 @@ use: [
485
503
  onSubscriptionRenewed: async (payload) => {
486
504
  console.log("Subscription renewed:", payload);
487
505
  },
488
- onSubscriptionPaused: async (payload) => {
489
- console.log("Subscription paused:", payload);
490
- },
491
506
  onSubscriptionPlanChanged: async (payload) => {
492
507
  console.log("Subscription plan changed:", payload);
493
508
  },
@@ -500,10 +515,52 @@ use: [
500
515
  onSubscriptionExpired: async (payload) => {
501
516
  console.log("Subscription expired:", payload);
502
517
  },
518
+ onSubscriptionUpdated: async (payload) => {
519
+ console.log("Subscription updated:", payload);
520
+ },
503
521
  // License key event handlers
504
522
  onLicenseKeyCreated: async (payload) => {
505
523
  console.log("License key created:", payload);
506
524
  },
525
+ // Abandoned checkout event handlers
526
+ onAbandonedCheckoutDetected: async (payload) => {
527
+ console.log("Abandoned checkout detected:", payload);
528
+ },
529
+ onAbandonedCheckoutRecovered: async (payload) => {
530
+ console.log("Abandoned checkout recovered:", payload);
531
+ },
532
+ // Dunning event handlers
533
+ onDunningStarted: async (payload) => {
534
+ console.log("Dunning started:", payload);
535
+ },
536
+ onDunningRecovered: async (payload) => {
537
+ console.log("Dunning recovered:", payload);
538
+ },
539
+ // Credit event handlers
540
+ onCreditAdded: async (payload) => {
541
+ console.log("Credit added:", payload);
542
+ },
543
+ onCreditDeducted: async (payload) => {
544
+ console.log("Credit deducted:", payload);
545
+ },
546
+ onCreditExpired: async (payload) => {
547
+ console.log("Credit expired:", payload);
548
+ },
549
+ onCreditRolledOver: async (payload) => {
550
+ console.log("Credit rolled over:", payload);
551
+ },
552
+ onCreditRolloverForfeited: async (payload) => {
553
+ console.log("Credit rollover forfeited:", payload);
554
+ },
555
+ onCreditOverageCharged: async (payload) => {
556
+ console.log("Credit overage charged:", payload);
557
+ },
558
+ onCreditManualAdjustment: async (payload) => {
559
+ console.log("Credit manual adjustment:", payload);
560
+ },
561
+ onCreditBalanceLow: async (payload) => {
562
+ console.log("Credit balance low:", payload);
563
+ },
507
564
  }),
508
565
  ],
509
566
 
@@ -525,12 +582,24 @@ Supported Webhook Event Handlers:
525
582
  - onSubscriptionActive: Subscription became active
526
583
  - onSubscriptionOnHold: Subscription was put on hold
527
584
  - onSubscriptionRenewed: Subscription was renewed
528
- - onSubscriptionPaused: Subscription was paused
529
585
  - onSubscriptionPlanChanged: Subscription plan was changed
530
586
  - onSubscriptionCancelled: Subscription was cancelled
531
587
  - onSubscriptionFailed: Subscription failed
532
588
  - onSubscriptionExpired: Subscription expired
589
+ - onSubscriptionUpdated: Subscription was updated
533
590
  - onLicenseKeyCreated: License key was created
591
+ - onAbandonedCheckoutDetected: Abandoned checkout was detected
592
+ - onAbandonedCheckoutRecovered: Abandoned checkout was recovered
593
+ - onDunningStarted: Dunning process started
594
+ - onDunningRecovered: Dunning process recovered
595
+ - onCreditAdded: Credit was added
596
+ - onCreditDeducted: Credit was deducted
597
+ - onCreditExpired: Credit expired
598
+ - onCreditRolledOver: Credit was rolled over
599
+ - onCreditRolloverForfeited: Credit rollover was forfeited
600
+ - onCreditOverageCharged: Credit overage was charged
601
+ - onCreditManualAdjustment: Credit manual adjustment was made
602
+ - onCreditBalanceLow: Credit balance is low
534
603
 
535
604
  COMBINING SELECTED PLUGINS:
536
605
 
@@ -583,5 +652,6 @@ IMPORTANT NOTES:
583
652
  8. The webhook endpoint is automatically created and secured with signature verification (if webhooks plugin is selected)
584
653
  9. Customer portal and subscription listing require user authentication (if portal plugin is selected)
585
654
  10. Handle errors appropriately and test webhook functionality in development before going live
586
- 11. Present all external setup tasks as clear TODO lists with specific environment variable names
655
+ 11. Use getCustomerParams to attach metadata or phone_number to DodoPayments customer records the function receives the BetterAuth User object and runs on every customer creation and update
656
+ 12. Present all external setup tasks as clear TODO lists with specific environment variable names
587
657
  ```
@@ -8,15 +8,20 @@ var onUserCreate = (options) => async (user, ctx) => {
8
8
  });
9
9
  const existingCustomer = customers.items[0];
10
10
  let customerId;
11
+ const additionalParams = options.getCustomerParams ? await options.getCustomerParams(user) : void 0;
11
12
  if (existingCustomer) {
12
13
  await options.client.customers.update(existingCustomer.customer_id, {
13
- name: user.name
14
+ name: user.name,
15
+ metadata: additionalParams?.metadata,
16
+ phone_number: additionalParams?.phone_number
14
17
  });
15
18
  customerId = existingCustomer.customer_id;
16
19
  } else {
17
20
  const newCustomer = await options.client.customers.create({
18
21
  email: user.email,
19
- name: user.name
22
+ name: user.name,
23
+ metadata: additionalParams?.metadata,
24
+ phone_number: additionalParams?.phone_number
20
25
  }, { idempotencyKey: user.id });
21
26
  customerId = newCustomer.customer_id;
22
27
  }
@@ -42,24 +47,28 @@ var onUserCreate = (options) => async (user, ctx) => {
42
47
  var onUserUpdate = (options) => async (user, ctx) => {
43
48
  if (ctx && options.createCustomerOnSignUp) {
44
49
  try {
45
- const customers = await options.client.customers.list({
46
- email: user.email
47
- });
48
- const existingCustomer = customers.items[0];
49
- if (existingCustomer) {
50
- await options.client.customers.update(existingCustomer.customer_id, {
51
- name: user.name
50
+ let customerId = user.dodoCustomerId;
51
+ if (!customerId) {
52
+ const customers = await options.client.customers.list({
53
+ email: user.email
54
+ });
55
+ const existingCustomer = customers.items[0];
56
+ if (!existingCustomer) return;
57
+ customerId = existingCustomer.customer_id;
58
+ ctx.context.internalAdapter.updateUser(user.id, {
59
+ dodoCustomerId: customerId
60
+ }).catch((e) => {
61
+ ctx.context.logger.warn(
62
+ `DodoPayments: failed to backfill dodoCustomerId for user ${user.id}. Error: ${e instanceof Error ? e.message : e}`
63
+ );
52
64
  });
53
- if (!user.dodoCustomerId) {
54
- ctx.context.internalAdapter.updateUser(user.id, {
55
- dodoCustomerId: existingCustomer.customer_id
56
- }).catch((e) => {
57
- ctx.context.logger.warn(
58
- `DodoPayments: failed to backfill dodoCustomerId for user ${user.id}. Error: ${e instanceof Error ? e.message : e}`
59
- );
60
- });
61
- }
62
65
  }
66
+ const additionalParams = options.getCustomerParams ? await options.getCustomerParams(user) : void 0;
67
+ await options.client.customers.update(customerId, {
68
+ name: user.name,
69
+ metadata: additionalParams?.metadata,
70
+ phone_number: additionalParams?.phone_number
71
+ });
63
72
  } catch (e) {
64
73
  if (e instanceof Error) {
65
74
  ctx.context.logger.error(
@@ -78,4 +87,4 @@ export {
78
87
  onUserCreate,
79
88
  onUserUpdate
80
89
  };
81
- //# sourceMappingURL=chunk-R5TTSJK4.js.map
90
+ //# sourceMappingURL=chunk-527Y7FSE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/customer.ts"],"sourcesContent":["import type { GenericEndpointContext, User } from \"better-auth\";\nimport { APIError } from \"better-auth/api\";\nimport type { DodoPaymentsOptions } from \"../types\";\n\nexport const onUserCreate =\n (options: DodoPaymentsOptions) =>\n async (user: User, ctx: GenericEndpointContext | null) => {\n if (ctx && options.createCustomerOnSignUp) {\n try {\n const customers = await options.client.customers.list({\n email: user.email,\n });\n const existingCustomer = customers.items[0];\n\n let customerId: string;\n\n const additionalParams = options.getCustomerParams\n ? await options.getCustomerParams(user)\n : undefined;\n\n if (existingCustomer) {\n await options.client.customers.update(existingCustomer.customer_id, {\n name: user.name,\n metadata: additionalParams?.metadata,\n phone_number: additionalParams?.phone_number,\n });\n customerId = existingCustomer.customer_id;\n } else {\n const newCustomer = await options.client.customers.create({\n email: user.email,\n name: user.name,\n metadata: additionalParams?.metadata,\n phone_number: additionalParams?.phone_number,\n }, { idempotencyKey: user.id });\n customerId = newCustomer.customer_id;\n }\n\n ctx.context.internalAdapter.updateUser(user.id, {\n dodoCustomerId: customerId,\n }).catch((e: unknown) => {\n ctx.context.logger.warn(\n `DodoPayments: failed to store dodoCustomerId for user ${user.id}. Error: ${e instanceof Error ? e.message : e}`,\n );\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: `DodoPayments customer creation failed. Error: ${e.message}`,\n });\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: `DodoPayments customer creation failed. Error: ${e}`,\n });\n }\n }\n };\n\nexport const onUserUpdate =\n (options: DodoPaymentsOptions) =>\n async (user: User, ctx: GenericEndpointContext | null) => {\n if (ctx && options.createCustomerOnSignUp) {\n try {\n let customerId = (user as User & { dodoCustomerId?: string }).dodoCustomerId;\n\n if (!customerId) {\n // Fallback to email lookup if dodoCustomerId is not stored yet\n const customers = await options.client.customers.list({\n email: user.email,\n });\n const existingCustomer = customers.items[0];\n\n if (!existingCustomer) return;\n\n customerId = existingCustomer.customer_id;\n\n // Backfill dodoCustomerId\n ctx.context.internalAdapter.updateUser(user.id, {\n dodoCustomerId: customerId,\n }).catch((e: unknown) => {\n ctx.context.logger.warn(\n `DodoPayments: failed to backfill dodoCustomerId for user ${user.id}. Error: ${e instanceof Error ? e.message : e}`,\n );\n });\n }\n\n const additionalParams = options.getCustomerParams\n ? await options.getCustomerParams(user)\n : undefined;\n\n await options.client.customers.update(customerId, {\n name: user.name,\n metadata: additionalParams?.metadata,\n phone_number: additionalParams?.phone_number,\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments customer update failed. Error: ${e.message}`,\n );\n } else {\n ctx.context.logger.error(\n `DodoPayments customer update failed. Error: ${e}`,\n );\n }\n }\n }\n };\n"],"mappings":";AACA,SAAS,gBAAgB;AAGlB,IAAM,eACX,CAAC,YACD,OAAO,MAAY,QAAuC;AACxD,MAAI,OAAO,QAAQ,wBAAwB;AACzC,QAAI;AACF,YAAM,YAAY,MAAM,QAAQ,OAAO,UAAU,KAAK;AAAA,QACpD,OAAO,KAAK;AAAA,MACd,CAAC;AACD,YAAM,mBAAmB,UAAU,MAAM,CAAC;AAE1C,UAAI;AAEJ,YAAM,mBAAmB,QAAQ,oBAC7B,MAAM,QAAQ,kBAAkB,IAAI,IACpC;AAEJ,UAAI,kBAAkB;AACpB,cAAM,QAAQ,OAAO,UAAU,OAAO,iBAAiB,aAAa;AAAA,UAClE,MAAM,KAAK;AAAA,UACX,UAAU,kBAAkB;AAAA,UAC5B,cAAc,kBAAkB;AAAA,QAClC,CAAC;AACD,qBAAa,iBAAiB;AAAA,MAChC,OAAO;AACL,cAAM,cAAc,MAAM,QAAQ,OAAO,UAAU,OAAO;AAAA,UACxD,OAAO,KAAK;AAAA,UACZ,MAAM,KAAK;AAAA,UACX,UAAU,kBAAkB;AAAA,UAC5B,cAAc,kBAAkB;AAAA,QAClC,GAAG,EAAE,gBAAgB,KAAK,GAAG,CAAC;AAC9B,qBAAa,YAAY;AAAA,MAC3B;AAEA,UAAI,QAAQ,gBAAgB,WAAW,KAAK,IAAI;AAAA,QAC9C,gBAAgB;AAAA,MAClB,CAAC,EAAE,MAAM,CAAC,MAAe;AACvB,YAAI,QAAQ,OAAO;AAAA,UACjB,yDAAyD,KAAK,EAAE,YAAY,aAAa,QAAQ,EAAE,UAAU,CAAC;AAAA,QAChH;AAAA,MACF,CAAC;AAAA,IACH,SAAS,GAAY;AACnB,UAAI,aAAa,OAAO;AACtB,cAAM,IAAI,SAAS,yBAAyB;AAAA,UAC1C,SAAS,iDAAiD,EAAE,OAAO;AAAA,QACrE,CAAC;AAAA,MACH;AAEA,YAAM,IAAI,SAAS,yBAAyB;AAAA,QAC1C,SAAS,iDAAiD,CAAC;AAAA,MAC7D,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEK,IAAM,eACX,CAAC,YACD,OAAO,MAAY,QAAuC;AACxD,MAAI,OAAO,QAAQ,wBAAwB;AACzC,QAAI;AACF,UAAI,aAAc,KAA4C;AAE9D,UAAI,CAAC,YAAY;AAEf,cAAM,YAAY,MAAM,QAAQ,OAAO,UAAU,KAAK;AAAA,UACpD,OAAO,KAAK;AAAA,QACd,CAAC;AACD,cAAM,mBAAmB,UAAU,MAAM,CAAC;AAE1C,YAAI,CAAC,iBAAkB;AAEvB,qBAAa,iBAAiB;AAG9B,YAAI,QAAQ,gBAAgB,WAAW,KAAK,IAAI;AAAA,UAC9C,gBAAgB;AAAA,QAClB,CAAC,EAAE,MAAM,CAAC,MAAe;AACvB,cAAI,QAAQ,OAAO;AAAA,YACjB,4DAA4D,KAAK,EAAE,YAAY,aAAa,QAAQ,EAAE,UAAU,CAAC;AAAA,UACnH;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,mBAAmB,QAAQ,oBAC7B,MAAM,QAAQ,kBAAkB,IAAI,IACpC;AAEJ,YAAM,QAAQ,OAAO,UAAU,OAAO,YAAY;AAAA,QAChD,MAAM,KAAK;AAAA,QACX,UAAU,kBAAkB;AAAA,QAC5B,cAAc,kBAAkB;AAAA,MAClC,CAAC;AAAA,IACH,SAAS,GAAY;AACnB,UAAI,aAAa,OAAO;AACtB,YAAI,QAAQ,OAAO;AAAA,UACjB,+CAA+C,EAAE,OAAO;AAAA,QAC1D;AAAA,MACF,OAAO;AACL,YAAI,QAAQ,OAAO;AAAA,UACjB,+CAA+C,CAAC;AAAA,QAClD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -6,7 +6,7 @@ import {
6
6
  checkoutSessionPayloadSchema,
7
7
  dynamicCheckoutBodySchema
8
8
  } from "@dodopayments/core/checkout";
9
- var checkout = (checkoutOptions = {}) => (dodopayments) => {
9
+ var checkout = (checkoutOptions = {}) => (options) => {
10
10
  return {
11
11
  /**
12
12
  * @deprecated
@@ -64,8 +64,8 @@ var checkout = (checkoutOptions = {}) => (dodopayments) => {
64
64
  ...ctx.body.metadata
65
65
  } : ctx.body.metadata
66
66
  },
67
- bearerToken: dodopayments.bearerToken,
68
- environment: dodopayments.baseURL.includes("test") ? "test_mode" : "live_mode",
67
+ bearerToken: options.client.bearerToken,
68
+ environment: options.client.baseURL.includes("test") ? "test_mode" : "live_mode",
69
69
  returnUrl: checkoutOptions.successUrl ? new URL(
70
70
  checkoutOptions.successUrl,
71
71
  ctx.request?.url
@@ -145,8 +145,8 @@ var checkout = (checkoutOptions = {}) => (dodopayments) => {
145
145
  ctx.request?.url
146
146
  ).toString() : void 0
147
147
  },
148
- bearerToken: dodopayments.bearerToken,
149
- environment: dodopayments.baseURL.includes("test") ? "test_mode" : "live_mode",
148
+ bearerToken: options.client.bearerToken,
149
+ environment: options.client.baseURL.includes("test") ? "test_mode" : "live_mode",
150
150
  type: "session"
151
151
  });
152
152
  const redirectUrl = new URL(checkoutUrl);
@@ -172,4 +172,4 @@ var checkout = (checkoutOptions = {}) => (dodopayments) => {
172
172
  export {
173
173
  checkout
174
174
  };
175
- //# sourceMappingURL=chunk-65YIVTFE.js.map
175
+ //# sourceMappingURL=chunk-6VDYFSNJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/checkout.ts"],"sourcesContent":["import type { DodoPaymentsOptions } from \"../types\";\nimport { APIError, createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { z } from \"zod/v3\";\nimport type { CreateCheckoutResponse, Product } from \"../types\";\nimport {\n buildCheckoutUrl,\n checkoutSessionPayloadSchema,\n dynamicCheckoutBodySchema,\n} from \"@dodopayments/core/checkout\";\n\nexport interface CheckoutOptions {\n /**\n * Optional list of slug -> productId mappings for easy slug checkouts\n */\n products?: Product[] | (() => Promise<Product[]>);\n /**\n * Checkout Success URL\n */\n successUrl?: string;\n /**\n * Only allow authenticated customers to checkout\n */\n authenticatedUsersOnly?: boolean;\n}\n\nexport const checkout =\n (checkoutOptions: CheckoutOptions = {}) =>\n (options: DodoPaymentsOptions) => {\n return {\n /**\n * @deprecated\n */\n dodoCheckout: createAuthEndpoint(\n \"/dodopayments/checkout\",\n {\n method: \"POST\",\n body: dynamicCheckoutBodySchema.extend({\n slug: z.string().optional(),\n referenceId: z.string().optional(),\n }),\n requireRequest: true,\n },\n async (ctx): Promise<CreateCheckoutResponse> => {\n const session = await getSessionFromCtx(ctx);\n\n let dodoPaymentsProductId: string | undefined;\n\n if (ctx.body?.slug) {\n const resolvedProducts =\n typeof checkoutOptions.products === \"function\"\n ? await checkoutOptions.products()\n : checkoutOptions.products;\n\n const productId = resolvedProducts?.find(\n (product) => product.slug === ctx.body.slug,\n )?.productId;\n\n if (!productId) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Product not found\",\n });\n }\n\n dodoPaymentsProductId = productId;\n } else {\n dodoPaymentsProductId = ctx.body.product_id;\n }\n\n if (checkoutOptions.authenticatedUsersOnly && !session?.user.id) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to checkout\",\n });\n }\n\n try {\n const checkoutUrl = await buildCheckoutUrl({\n body: {\n ...ctx.body,\n product_id: dodoPaymentsProductId,\n customer: {\n email: session?.user.email,\n name: session?.user.name,\n ...ctx.body.customer,\n },\n product_cart: dodoPaymentsProductId\n ? [\n {\n product_id: dodoPaymentsProductId,\n quantity: 1,\n },\n ]\n : undefined,\n metadata: ctx.body.referenceId\n ? {\n referenceId: ctx.body.referenceId,\n ...ctx.body.metadata,\n }\n : ctx.body.metadata,\n },\n bearerToken: options.client.bearerToken,\n environment: options.client.baseURL.includes(\"test\")\n ? \"test_mode\"\n : \"live_mode\",\n returnUrl: checkoutOptions.successUrl\n ? new URL(\n checkoutOptions.successUrl,\n ctx.request?.url,\n ).toString()\n : undefined,\n type: \"dynamic\",\n });\n\n const redirectUrl = new URL(checkoutUrl);\n\n return ctx.json({\n url: redirectUrl.toString(),\n redirect: true,\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments checkout creation failed. Error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Checkout creation failed\",\n });\n }\n },\n ),\n dodoCheckoutSession: createAuthEndpoint(\n \"/dodopayments/checkout-session\",\n {\n method: \"POST\",\n body: checkoutSessionPayloadSchema\n .extend({\n slug: z.string().optional(),\n referenceId: z.string().optional(),\n })\n .partial({\n product_cart: true,\n }),\n requireRequest: true,\n },\n async (ctx): Promise<CreateCheckoutResponse> => {\n const session = await getSessionFromCtx(ctx);\n\n let dodoPaymentsProductId: string | undefined;\n\n if (ctx.body?.slug) {\n const resolvedProducts =\n typeof checkoutOptions.products === \"function\"\n ? await checkoutOptions.products()\n : checkoutOptions.products;\n\n const productId = resolvedProducts?.find(\n (product) => product.slug === ctx.body.slug,\n )?.productId;\n\n if (!productId) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Product not found\",\n });\n }\n\n dodoPaymentsProductId = productId;\n }\n\n if (checkoutOptions.authenticatedUsersOnly && !session?.user.id) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"You must be logged in to checkout\",\n });\n }\n\n // Ensure we have a product_cart\n const product_cart = dodoPaymentsProductId\n ? [{ product_id: dodoPaymentsProductId, quantity: 1 }]\n : ctx.body.product_cart;\n\n if (!product_cart || product_cart.length === 0) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Neither product_cart nor slug was provided\",\n });\n }\n\n try {\n const checkoutUrl = await buildCheckoutUrl({\n sessionPayload: {\n ...ctx.body,\n product_cart,\n customer: session?.user.email\n ? {\n email: session?.user.email,\n name: session?.user.name,\n }\n : ctx.body.customer,\n metadata: ctx.body.referenceId\n ? {\n referenceId: ctx.body.referenceId,\n ...ctx.body.metadata,\n }\n : ctx.body.metadata,\n return_url: checkoutOptions.successUrl\n ? new URL(\n checkoutOptions.successUrl,\n ctx.request?.url,\n ).toString()\n : undefined,\n },\n bearerToken: options.client.bearerToken,\n environment: options.client.baseURL.includes(\"test\")\n ? \"test_mode\"\n : \"live_mode\",\n type: \"session\",\n });\n\n const redirectUrl = new URL(checkoutUrl);\n\n return ctx.json({\n url: redirectUrl.toString(),\n redirect: true,\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments checkout creation failed. Error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Checkout session creation failed\",\n });\n }\n },\n ),\n };\n };\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
1
  // src/utils.ts
2
- async function getOrCreateCustomerId(dodopayments, session, internalAdapter) {
2
+ async function getOrCreateCustomerId(dodopayments, session, internalAdapter, getCustomerParams) {
3
3
  const dodoCustomerId = session.user["dodoCustomerId"];
4
4
  if (dodoCustomerId) return dodoCustomerId;
5
5
  const customers = await dodopayments.customers.list({
@@ -7,9 +7,12 @@ async function getOrCreateCustomerId(dodopayments, session, internalAdapter) {
7
7
  });
8
8
  let customer = customers.items[0];
9
9
  if (!customer) {
10
+ const additionalParams = getCustomerParams ? await getCustomerParams(session.user) : void 0;
10
11
  customer = await dodopayments.customers.create({
11
12
  email: session.user.email,
12
- name: session.user.name
13
+ name: session.user.name,
14
+ metadata: additionalParams?.metadata,
15
+ phone_number: additionalParams?.phone_number
13
16
  }, { idempotencyKey: session.user.id });
14
17
  }
15
18
  internalAdapter.updateUser(session.user.id, { dodoCustomerId: customer.customer_id }).catch(() => {
@@ -20,4 +23,4 @@ async function getOrCreateCustomerId(dodopayments, session, internalAdapter) {
20
23
  export {
21
24
  getOrCreateCustomerId
22
25
  };
23
- //# sourceMappingURL=chunk-TOPOAYYO.js.map
26
+ //# sourceMappingURL=chunk-EGRIWRWP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils.ts"],"sourcesContent":["import type { DodoPayments } from \"dodopayments\";\nimport type { User } from \"better-auth\";\n\nexport async function getOrCreateCustomerId(\n dodopayments: DodoPayments,\n session: { user: { id: string; email: string; name: string } & Record<string, unknown> },\n internalAdapter: { updateUser: (id: string, data: Record<string, unknown>) => Promise<unknown> },\n getCustomerParams?: (user: User) => { metadata?: Record<string, string>; phone_number?: string | null } | Promise<{ metadata?: Record<string, string>; phone_number?: string | null }>,\n): Promise<string> {\n const dodoCustomerId = session.user[\"dodoCustomerId\"] as string | undefined;\n if (dodoCustomerId) return dodoCustomerId;\n\n // Fallback to get customer from email if dodoCustomerId doesn't exist\n const customers = await dodopayments.customers.list({\n email: session.user.email,\n });\n let customer = customers.items[0];\n\n if (!customer) {\n const additionalParams = getCustomerParams\n ? await getCustomerParams(session.user as User)\n : undefined;\n\n customer = await dodopayments.customers.create({\n email: session.user.email,\n name: session.user.name,\n metadata: additionalParams?.metadata,\n phone_number: additionalParams?.phone_number,\n }, { idempotencyKey: session.user.id });\n }\n\n internalAdapter\n .updateUser(session.user.id, { dodoCustomerId: customer.customer_id })\n .catch(() => {});\n\n return customer.customer_id;\n}\n"],"mappings":";AAGA,eAAsB,sBACpB,cACA,SACA,iBACA,mBACiB;AACjB,QAAM,iBAAiB,QAAQ,KAAK,gBAAgB;AACpD,MAAI,eAAgB,QAAO;AAG3B,QAAM,YAAY,MAAM,aAAa,UAAU,KAAK;AAAA,IAClD,OAAO,QAAQ,KAAK;AAAA,EACtB,CAAC;AACD,MAAI,WAAW,UAAU,MAAM,CAAC;AAEhC,MAAI,CAAC,UAAU;AACb,UAAM,mBAAmB,oBACrB,MAAM,kBAAkB,QAAQ,IAAY,IAC5C;AAEJ,eAAW,MAAM,aAAa,UAAU,OAAO;AAAA,MAC7C,OAAO,QAAQ,KAAK;AAAA,MACpB,MAAM,QAAQ,KAAK;AAAA,MACnB,UAAU,kBAAkB;AAAA,MAC5B,cAAc,kBAAkB;AAAA,IAClC,GAAG,EAAE,gBAAgB,QAAQ,KAAK,GAAG,CAAC;AAAA,EACxC;AAEA,kBACG,WAAW,QAAQ,KAAK,IAAI,EAAE,gBAAgB,SAAS,YAAY,CAAC,EACpE,MAAM,MAAM;AAAA,EAAC,CAAC;AAEjB,SAAO,SAAS;AAClB;","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "@dodopayments/core/webhook";
5
5
  import { APIError, createAuthEndpoint } from "better-auth/api";
6
6
  import { verifyWebhookPayload } from "@dodopayments/core/webhook";
7
- var webhooks = (options) => (_dodopayments) => {
7
+ var webhooks = (webhookOptions) => (_options) => {
8
8
  return {
9
9
  dodopaymentsWebhooks: createAuthEndpoint(
10
10
  "/dodopayments/webhooks",
@@ -16,7 +16,7 @@ var webhooks = (options) => (_dodopayments) => {
16
16
  cloneRequest: true
17
17
  },
18
18
  async (ctx) => {
19
- const { webhookKey } = options;
19
+ const { webhookKey } = webhookOptions;
20
20
  if (!ctx.request?.body) {
21
21
  throw new APIError("INTERNAL_SERVER_ERROR");
22
22
  }
@@ -54,7 +54,7 @@ var webhooks = (options) => (_dodopayments) => {
54
54
  });
55
55
  }
56
56
  try {
57
- await handleWebhookPayload(event, options);
57
+ await handleWebhookPayload(event, webhookOptions);
58
58
  } catch (e) {
59
59
  if (e instanceof Error) {
60
60
  ctx.context.logger.error(
@@ -77,4 +77,4 @@ var webhooks = (options) => (_dodopayments) => {
77
77
  export {
78
78
  webhooks
79
79
  };
80
- //# sourceMappingURL=chunk-HHIXOUFD.js.map
80
+ //# sourceMappingURL=chunk-XXIDSJPK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/webhooks.ts"],"sourcesContent":["import type { DodoPaymentsOptions } from \"../types\";\nimport {\n handleWebhookPayload,\n WebhookHandlerConfig,\n} from \"@dodopayments/core/webhook\";\nimport { APIError, createAuthEndpoint } from \"better-auth/api\";\nimport { WebhookPayload } from \"@dodopayments/core/schemas\";\nimport { verifyWebhookPayload } from \"@dodopayments/core/webhook\";\nimport type { WebhookResponse } from \"../types\";\n\nexport const webhooks =\n (webhookOptions: WebhookHandlerConfig) => (_options: DodoPaymentsOptions) => {\n return {\n dodopaymentsWebhooks: createAuthEndpoint(\n \"/dodopayments/webhooks\",\n {\n method: \"POST\",\n metadata: {\n isAction: false,\n },\n cloneRequest: true,\n },\n async (ctx): Promise<WebhookResponse> => {\n const { webhookKey } = webhookOptions;\n\n if (!ctx.request?.body) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\");\n }\n const buf = await ctx.request.text();\n let event: WebhookPayload;\n try {\n if (!webhookKey) {\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"DodoPayments webhook webhookKey not found\",\n });\n }\n\n const headers = {\n \"webhook-id\": ctx.request.headers.get(\"webhook-id\") as string,\n \"webhook-timestamp\": ctx.request.headers.get(\n \"webhook-timestamp\",\n ) as string,\n \"webhook-signature\": ctx.request.headers.get(\n \"webhook-signature\",\n ) as string,\n };\n\n event = await verifyWebhookPayload({\n webhookKey,\n headers,\n body: buf,\n });\n } catch (err: unknown) {\n if (err instanceof Error) {\n ctx.context.logger.error(`Webhook Error: ${err.message}`);\n throw new APIError(\"BAD_REQUEST\", {\n message: `Webhook Error: ${err.message}`,\n });\n }\n\n throw new APIError(\"BAD_REQUEST\", {\n message: `Webhook Error: ${err}`,\n });\n }\n\n try {\n await handleWebhookPayload(event, webhookOptions);\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments webhook failed. Error: ${e.message}`,\n );\n }\n\n ctx.context.logger.error(\n `DodoPayments webhook failed. Error: ${e}`,\n );\n\n throw new APIError(\"BAD_REQUEST\", {\n message: \"Webhook error: See server logs for more information.\",\n });\n }\n\n return ctx.json({ received: true });\n },\n ),\n };\n };\n"],"mappings":";AACA;AAAA,EACE;AAAA,OAEK;AACP,SAAS,UAAU,0BAA0B;AAE7C,SAAS,4BAA4B;AAG9B,IAAM,WACX,CAAC,mBAAyC,CAAC,aAAkC;AAC3E,SAAO;AAAA,IACL,sBAAsB;AAAA,MACpB;AAAA,MACA;AAAA,QACE,QAAQ;AAAA,QACR,UAAU;AAAA,UACR,UAAU;AAAA,QACZ;AAAA,QACA,cAAc;AAAA,MAChB;AAAA,MACA,OAAO,QAAkC;AACvC,cAAM,EAAE,WAAW,IAAI;AAEvB,YAAI,CAAC,IAAI,SAAS,MAAM;AACtB,gBAAM,IAAI,SAAS,uBAAuB;AAAA,QAC5C;AACA,cAAM,MAAM,MAAM,IAAI,QAAQ,KAAK;AACnC,YAAI;AACJ,YAAI;AACF,cAAI,CAAC,YAAY;AACf,kBAAM,IAAI,SAAS,yBAAyB;AAAA,cAC1C,SAAS;AAAA,YACX,CAAC;AAAA,UACH;AAEA,gBAAM,UAAU;AAAA,YACd,cAAc,IAAI,QAAQ,QAAQ,IAAI,YAAY;AAAA,YAClD,qBAAqB,IAAI,QAAQ,QAAQ;AAAA,cACvC;AAAA,YACF;AAAA,YACA,qBAAqB,IAAI,QAAQ,QAAQ;AAAA,cACvC;AAAA,YACF;AAAA,UACF;AAEA,kBAAQ,MAAM,qBAAqB;AAAA,YACjC;AAAA,YACA;AAAA,YACA,MAAM;AAAA,UACR,CAAC;AAAA,QACH,SAAS,KAAc;AACrB,cAAI,eAAe,OAAO;AACxB,gBAAI,QAAQ,OAAO,MAAM,kBAAkB,IAAI,OAAO,EAAE;AACxD,kBAAM,IAAI,SAAS,eAAe;AAAA,cAChC,SAAS,kBAAkB,IAAI,OAAO;AAAA,YACxC,CAAC;AAAA,UACH;AAEA,gBAAM,IAAI,SAAS,eAAe;AAAA,YAChC,SAAS,kBAAkB,GAAG;AAAA,UAChC,CAAC;AAAA,QACH;AAEA,YAAI;AACF,gBAAM,qBAAqB,OAAO,cAAc;AAAA,QAClD,SAAS,GAAY;AACnB,cAAI,aAAa,OAAO;AACtB,gBAAI,QAAQ,OAAO;AAAA,cACjB,uCAAuC,EAAE,OAAO;AAAA,YAClD;AAAA,UACF;AAEA,cAAI,QAAQ,OAAO;AAAA,YACjB,uCAAuC,CAAC;AAAA,UAC1C;AAEA,gBAAM,IAAI,SAAS,eAAe;AAAA,YAChC,SAAS;AAAA,UACX,CAAC;AAAA,QACH;AAEA,eAAO,IAAI,KAAK,EAAE,UAAU,KAAK,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  getOrCreateCustomerId
3
- } from "./chunk-TOPOAYYO.js";
3
+ } from "./chunk-EGRIWRWP.js";
4
4
 
5
5
  // src/plugins/portal.ts
6
6
  import { APIError, createAuthEndpoint, sessionMiddleware } from "better-auth/api";
7
7
  import { z } from "zod/v3";
8
- var portal = () => (dodopayments) => {
8
+ var portal = () => (options) => {
9
9
  return {
10
10
  dodoPortal: createAuthEndpoint(
11
11
  "/dodopayments/customer/portal",
@@ -26,11 +26,12 @@ var portal = () => (dodopayments) => {
26
26
  }
27
27
  try {
28
28
  const customerId = await getOrCreateCustomerId(
29
- dodopayments,
29
+ options.client,
30
30
  ctx.context.session,
31
- ctx.context.internalAdapter
31
+ ctx.context.internalAdapter,
32
+ options.getCustomerParams
32
33
  );
33
- const customerSession = await dodopayments.customers.customerPortal.create(customerId);
34
+ const customerSession = await options.client.customers.customerPortal.create(customerId);
34
35
  return ctx.json({
35
36
  url: customerSession.link,
36
37
  redirect: true
@@ -78,11 +79,12 @@ var portal = () => (dodopayments) => {
78
79
  }
79
80
  try {
80
81
  const customerId = await getOrCreateCustomerId(
81
- dodopayments,
82
+ options.client,
82
83
  ctx.context.session,
83
- ctx.context.internalAdapter
84
+ ctx.context.internalAdapter,
85
+ options.getCustomerParams
84
86
  );
85
- const subscriptions = await dodopayments.subscriptions.list({
87
+ const subscriptions = await options.client.subscriptions.list({
86
88
  customer_id: customerId,
87
89
  // page number is 0-indexed
88
90
  page_number: ctx.query?.page ? ctx.query.page - 1 : void 0,
@@ -138,11 +140,12 @@ var portal = () => (dodopayments) => {
138
140
  }
139
141
  try {
140
142
  const customerId = await getOrCreateCustomerId(
141
- dodopayments,
143
+ options.client,
142
144
  ctx.context.session,
143
- ctx.context.internalAdapter
145
+ ctx.context.internalAdapter,
146
+ options.getCustomerParams
144
147
  );
145
- const payments = await dodopayments.payments.list({
148
+ const payments = await options.client.payments.list({
146
149
  customer_id: customerId,
147
150
  // page number is 0-indexed
148
151
  page_number: ctx.query?.page ? ctx.query.page - 1 : void 0,
@@ -168,4 +171,4 @@ var portal = () => (dodopayments) => {
168
171
  export {
169
172
  portal
170
173
  };
171
- //# sourceMappingURL=chunk-DTOB4IQZ.js.map
174
+ //# sourceMappingURL=chunk-YCUWFLKK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/portal.ts"],"sourcesContent":["import { APIError, createAuthEndpoint, sessionMiddleware } from \"better-auth/api\";\nimport { z } from \"zod/v3\";\nimport type {\n CustomerPortalResponse,\n DodoPaymentsOptions,\n PaymentItems,\n SubscriptionItems,\n} from \"../types\";\nimport { getOrCreateCustomerId } from \"../utils\";\n\nexport const portal = () => (options: DodoPaymentsOptions) => {\n return {\n dodoPortal: createAuthEndpoint(\n \"/dodopayments/customer/portal\",\n {\n method: \"GET\",\n use: [sessionMiddleware],\n },\n async (ctx): Promise<CustomerPortalResponse> => {\n if (!ctx.context.session?.user.id) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"User not found\",\n });\n }\n\n if (!ctx.context.session?.user.emailVerified) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"User email not verified\",\n });\n }\n\n try {\n const customerId = await getOrCreateCustomerId(\n options.client,\n ctx.context.session,\n ctx.context.internalAdapter,\n options.getCustomerParams,\n );\n\n const customerSession =\n await options.client.customers.customerPortal.create(customerId);\n\n return ctx.json({\n url: customerSession.link,\n redirect: true,\n });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments customer portal creation failed. Error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Customer portal creation failed\",\n });\n }\n },\n ),\n dodoSubscriptions: createAuthEndpoint(\n \"/dodopayments/customer/subscriptions/list\",\n {\n method: \"GET\",\n query: z\n .object({\n page: z.coerce.number().optional(),\n limit: z.coerce.number().optional(),\n status: z\n .enum([\n \"active\",\n \"cancelled\",\n \"on_hold\",\n \"pending\",\n \"failed\",\n \"expired\",\n ])\n .optional(),\n })\n .optional(),\n use: [sessionMiddleware],\n },\n async (ctx): Promise<SubscriptionItems> => {\n if (!ctx.context.session.user.id) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"User not found\",\n });\n }\n\n if (!ctx.context.session?.user.emailVerified) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"User email not verified\",\n });\n }\n\n try {\n const customerId = await getOrCreateCustomerId(\n options.client,\n ctx.context.session,\n ctx.context.internalAdapter,\n options.getCustomerParams,\n );\n\n const subscriptions = await options.client.subscriptions.list({\n customer_id: customerId,\n // page number is 0-indexed\n page_number: ctx.query?.page ? ctx.query.page - 1 : undefined,\n page_size: ctx.query?.limit,\n status: ctx.query?.status,\n });\n\n return ctx.json({ items: subscriptions.items });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments subscriptions list failed. Error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"DodoPayments subscriptions list failed\",\n });\n }\n },\n ),\n dodoPayments: createAuthEndpoint(\n \"/dodopayments/customer/payments/list\",\n {\n method: \"GET\",\n query: z\n .object({\n page: z.coerce.number().optional(),\n limit: z.coerce.number().optional(),\n status: z\n .enum([\n \"succeeded\",\n \"failed\",\n \"cancelled\",\n \"processing\",\n \"requires_customer_action\",\n \"requires_merchant_action\",\n \"requires_payment_method\",\n \"requires_confirmation\",\n \"requires_capture\",\n \"partially_captured\",\n \"partially_captured_and_capturable\",\n ])\n .optional(),\n })\n .optional(),\n use: [sessionMiddleware],\n },\n async (ctx): Promise<PaymentItems> => {\n if (!ctx.context.session.user.id) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"User not found\",\n });\n }\n\n if (!ctx.context.session?.user.emailVerified) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"User email not verified\",\n });\n }\n\n try {\n const customerId = await getOrCreateCustomerId(\n options.client,\n ctx.context.session,\n ctx.context.internalAdapter,\n options.getCustomerParams,\n );\n\n const payments = await options.client.payments.list({\n customer_id: customerId,\n // page number is 0-indexed\n page_number: ctx.query?.page ? ctx.query.page - 1 : undefined,\n page_size: ctx.query?.limit,\n status: ctx.query?.status,\n });\n\n return ctx.json({ items: payments.items });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `DodoPayments orders list failed. Error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Orders list failed\",\n });\n }\n },\n ),\n };\n};\n\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getOrCreateCustomerId
3
- } from "./chunk-TOPOAYYO.js";
3
+ } from "./chunk-EGRIWRWP.js";
4
4
 
5
5
  // src/plugins/usage.ts
6
6
  import {
@@ -17,7 +17,7 @@ var EventInputSchema = z.object({
17
17
  "Custom Timestamp. Defaults to current timestamp in UTC. Timestamps that are older that 1 hour or after 5 mins from current timestamp will be rejected."
18
18
  )
19
19
  });
20
- var usage = () => (dodopayments) => {
20
+ var usage = () => (options) => {
21
21
  return {
22
22
  // Ingest usage data
23
23
  dodoUsageIngest: createAuthEndpoint(
@@ -40,11 +40,12 @@ var usage = () => (dodopayments) => {
40
40
  }
41
41
  try {
42
42
  const customerId = await getOrCreateCustomerId(
43
- dodopayments,
43
+ options.client,
44
44
  ctx.context.session,
45
- ctx.context.internalAdapter
45
+ ctx.context.internalAdapter,
46
+ options.getCustomerParams
46
47
  );
47
- const result = await dodopayments.usageEvents.ingest({
48
+ const result = await options.client.usageEvents.ingest({
48
49
  events: [
49
50
  {
50
51
  event_id: ctx.body.event_id,
@@ -96,11 +97,12 @@ var usage = () => (dodopayments) => {
96
97
  }
97
98
  try {
98
99
  const customerId = await getOrCreateCustomerId(
99
- dodopayments,
100
+ options.client,
100
101
  ctx.context.session,
101
- ctx.context.internalAdapter
102
+ ctx.context.internalAdapter,
103
+ options.getCustomerParams
102
104
  );
103
- const meters = await dodopayments.usageEvents.list({
105
+ const meters = await options.client.usageEvents.list({
104
106
  customer_id: customerId,
105
107
  ...ctx.query
106
108
  });
@@ -123,4 +125,4 @@ var usage = () => (dodopayments) => {
123
125
  export {
124
126
  usage
125
127
  };
126
- //# sourceMappingURL=chunk-ARA27DRZ.js.map
128
+ //# sourceMappingURL=chunk-ZA3TNX5K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugins/usage.ts"],"sourcesContent":["import {\n APIError,\n createAuthEndpoint,\n sessionMiddleware,\n} from \"better-auth/api\";\nimport type { DodoPaymentsOptions } from \"../types\";\nimport { Event } from \"dodopayments/resources/usage-events.mjs\";\nimport { z } from \"zod/v3\";\nimport { getOrCreateCustomerId } from \"../utils\";\n\nconst EventInputSchema = z.object({\n event_id: z.string(),\n event_name: z.string(),\n metadata: z\n .record(z.union([z.string(), z.number(), z.boolean()]))\n .nullable()\n .optional(),\n timestamp: z\n // NOTE: coerce because the date object gets converted to a string over network requests\n // but we still want to enforce that it's a Date type\n .date({ coerce: true })\n .transform((d) => d.toISOString())\n .optional()\n .describe(\n \"Custom Timestamp. Defaults to current timestamp in UTC.\\\n Timestamps that are older that 1 hour or after 5 mins from\\\n current timestamp will be rejected.\",\n ),\n});\n\nexport const usage = () => (options: DodoPaymentsOptions) => {\n return {\n // Ingest usage data\n dodoUsageIngest: createAuthEndpoint(\n \"/dodopayments/usage/ingest\",\n {\n method: \"POST\",\n body: EventInputSchema,\n use: [sessionMiddleware],\n },\n async (ctx): Promise<{ ingested_count: number }> => {\n if (!ctx.context.session?.user?.id) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"User not found\",\n });\n }\n\n if (!ctx.context.session?.user.emailVerified) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"User email not verified\",\n });\n }\n\n try {\n const customerId = await getOrCreateCustomerId(\n options.client,\n ctx.context.session,\n ctx.context.internalAdapter,\n options.getCustomerParams,\n );\n\n const result = await options.client.usageEvents.ingest({\n events: [\n {\n event_id: ctx.body.event_id,\n customer_id: customerId,\n event_name: ctx.body.event_name,\n timestamp: ctx.body.timestamp,\n metadata: ctx.body.metadata,\n },\n ],\n });\n\n return ctx.json({ ingested_count: result.ingested_count });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `User usage ingestion error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to record the user usage\",\n });\n }\n },\n ),\n\n // List usage meters\n dodoUsageMetersList: createAuthEndpoint(\n \"/dodopayments/usage/meters/list\",\n {\n method: \"GET\",\n query: z\n .object({\n page_number: z.coerce.number().optional(),\n page_size: z.coerce.number().optional(),\n event_name: z.string().optional(),\n meter_id: z.string().optional(),\n start: z.string().optional(),\n end: z.string().optional(),\n })\n .optional(),\n use: [sessionMiddleware],\n },\n async (ctx): Promise<{ items: Event[] }> => {\n if (!ctx.context.session?.user?.id) {\n throw new APIError(\"BAD_REQUEST\", {\n message: \"User not found\",\n });\n }\n\n if (!ctx.context.session?.user.emailVerified) {\n throw new APIError(\"UNAUTHORIZED\", {\n message: \"User email not verified\",\n });\n }\n\n try {\n const customerId = await getOrCreateCustomerId(\n options.client,\n ctx.context.session,\n ctx.context.internalAdapter,\n options.getCustomerParams,\n );\n\n const meters = await options.client.usageEvents.list({\n customer_id: customerId,\n ...ctx.query,\n });\n\n return ctx.json({ items: meters.items });\n } catch (e: unknown) {\n if (e instanceof Error) {\n ctx.context.logger.error(\n `User usage meter list error: ${e.message}`,\n );\n }\n\n throw new APIError(\"INTERNAL_SERVER_ERROR\", {\n message: \"Failed to fetch the user usage\",\n });\n }\n },\n ),\n };\n};\n\n"],"mappings":"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","names":[]}
package/dist/client.d.cts CHANGED
@@ -1,8 +1,7 @@
1
1
  export { dodopaymentsClient } from './index.cjs';
2
- export { C as CreateCheckoutResponse, a as CustomerPortalResponse, e as DodoPaymentsEndpoints, D as DodoPaymentsOptions, P as PaymentItems, b as Product, S as SubscriptionItems, W as WebhookResponse } from './types-4JE4OwKb.cjs';
2
+ export { C as CreateCheckoutResponse, a as CustomerPortalResponse, e as DodoPaymentsEndpoints, D as DodoPaymentsOptions, P as PaymentItems, b as Product, S as SubscriptionItems, W as WebhookResponse } from './types-D0tVSLaf.cjs';
3
3
  import 'dodopayments/resources/usage-events.mjs';
4
4
  import 'better-auth';
5
5
  import 'zod/v3';
6
- import './plugins/usage.cjs';
7
6
  import 'dodopayments';
8
7
  import '@dodopayments/core/webhook';
package/dist/client.d.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  export { dodopaymentsClient } from './index.js';
2
- export { C as CreateCheckoutResponse, a as CustomerPortalResponse, e as DodoPaymentsEndpoints, D as DodoPaymentsOptions, P as PaymentItems, b as Product, S as SubscriptionItems, W as WebhookResponse } from './types-B9rx1bt7.js';
2
+ export { C as CreateCheckoutResponse, a as CustomerPortalResponse, e as DodoPaymentsEndpoints, D as DodoPaymentsOptions, P as PaymentItems, b as Product, S as SubscriptionItems, W as WebhookResponse } from './types-D0tVSLaf.js';
3
3
  import 'dodopayments/resources/usage-events.mjs';
4
4
  import 'better-auth';
5
5
  import 'zod/v3';
6
- import './plugins/usage.js';
7
6
  import 'dodopayments';
8
7
  import '@dodopayments/core/webhook';
@@ -33,15 +33,20 @@ var onUserCreate = (options) => async (user, ctx) => {
33
33
  });
34
34
  const existingCustomer = customers.items[0];
35
35
  let customerId;
36
+ const additionalParams = options.getCustomerParams ? await options.getCustomerParams(user) : void 0;
36
37
  if (existingCustomer) {
37
38
  await options.client.customers.update(existingCustomer.customer_id, {
38
- name: user.name
39
+ name: user.name,
40
+ metadata: additionalParams?.metadata,
41
+ phone_number: additionalParams?.phone_number
39
42
  });
40
43
  customerId = existingCustomer.customer_id;
41
44
  } else {
42
45
  const newCustomer = await options.client.customers.create({
43
46
  email: user.email,
44
- name: user.name
47
+ name: user.name,
48
+ metadata: additionalParams?.metadata,
49
+ phone_number: additionalParams?.phone_number
45
50
  }, { idempotencyKey: user.id });
46
51
  customerId = newCustomer.customer_id;
47
52
  }
@@ -67,24 +72,28 @@ var onUserCreate = (options) => async (user, ctx) => {
67
72
  var onUserUpdate = (options) => async (user, ctx) => {
68
73
  if (ctx && options.createCustomerOnSignUp) {
69
74
  try {
70
- const customers = await options.client.customers.list({
71
- email: user.email
72
- });
73
- const existingCustomer = customers.items[0];
74
- if (existingCustomer) {
75
- await options.client.customers.update(existingCustomer.customer_id, {
76
- name: user.name
75
+ let customerId = user.dodoCustomerId;
76
+ if (!customerId) {
77
+ const customers = await options.client.customers.list({
78
+ email: user.email
79
+ });
80
+ const existingCustomer = customers.items[0];
81
+ if (!existingCustomer) return;
82
+ customerId = existingCustomer.customer_id;
83
+ ctx.context.internalAdapter.updateUser(user.id, {
84
+ dodoCustomerId: customerId
85
+ }).catch((e) => {
86
+ ctx.context.logger.warn(
87
+ `DodoPayments: failed to backfill dodoCustomerId for user ${user.id}. Error: ${e instanceof Error ? e.message : e}`
88
+ );
77
89
  });
78
- if (!user.dodoCustomerId) {
79
- ctx.context.internalAdapter.updateUser(user.id, {
80
- dodoCustomerId: existingCustomer.customer_id
81
- }).catch((e) => {
82
- ctx.context.logger.warn(
83
- `DodoPayments: failed to backfill dodoCustomerId for user ${user.id}. Error: ${e instanceof Error ? e.message : e}`
84
- );
85
- });
86
- }
87
90
  }
91
+ const additionalParams = options.getCustomerParams ? await options.getCustomerParams(user) : void 0;
92
+ await options.client.customers.update(customerId, {
93
+ name: user.name,
94
+ metadata: additionalParams?.metadata,
95
+ phone_number: additionalParams?.phone_number
96
+ });
88
97
  } catch (e) {
89
98
  if (e instanceof Error) {
90
99
  ctx.context.logger.error(