@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.
- package/README.md +75 -5
- package/dist/{chunk-R5TTSJK4.js → chunk-527Y7FSE.js} +28 -19
- package/dist/chunk-527Y7FSE.js.map +1 -0
- package/dist/{chunk-65YIVTFE.js → chunk-6VDYFSNJ.js} +6 -6
- package/dist/chunk-6VDYFSNJ.js.map +1 -0
- package/dist/{chunk-TOPOAYYO.js → chunk-EGRIWRWP.js} +6 -3
- package/dist/chunk-EGRIWRWP.js.map +1 -0
- package/dist/{chunk-HHIXOUFD.js → chunk-XXIDSJPK.js} +4 -4
- package/dist/chunk-XXIDSJPK.js.map +1 -0
- package/dist/{chunk-DTOB4IQZ.js → chunk-YCUWFLKK.js} +15 -12
- package/dist/chunk-YCUWFLKK.js.map +1 -0
- package/dist/{chunk-ARA27DRZ.js → chunk-ZA3TNX5K.js} +11 -9
- package/dist/chunk-ZA3TNX5K.js.map +1 -0
- package/dist/client.d.cts +1 -2
- package/dist/client.d.ts +1 -2
- package/dist/hooks/customer.cjs +27 -18
- package/dist/hooks/customer.cjs.map +1 -1
- package/dist/hooks/customer.d.cts +1 -2
- package/dist/hooks/customer.d.ts +1 -2
- package/dist/hooks/customer.js +1 -1
- package/dist/index.cjs +63 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/plugins/checkout.cjs +5 -5
- package/dist/plugins/checkout.cjs.map +1 -1
- package/dist/plugins/checkout.d.cts +2 -3
- package/dist/plugins/checkout.d.ts +2 -3
- package/dist/plugins/checkout.js +1 -1
- package/dist/plugins/portal.cjs +18 -12
- package/dist/plugins/portal.cjs.map +1 -1
- package/dist/plugins/portal.d.cts +2 -3
- package/dist/plugins/portal.d.ts +2 -3
- package/dist/plugins/portal.js +2 -2
- package/dist/plugins/usage.cjs +14 -9
- package/dist/plugins/usage.cjs.map +1 -1
- package/dist/plugins/usage.d.cts +6 -107
- package/dist/plugins/usage.d.ts +6 -107
- package/dist/plugins/usage.js +2 -2
- package/dist/plugins/webhooks.cjs +3 -3
- package/dist/plugins/webhooks.cjs.map +1 -1
- package/dist/plugins/webhooks.d.cts +2 -3
- package/dist/plugins/webhooks.d.ts +2 -3
- package/dist/plugins/webhooks.js +1 -1
- package/dist/{types-4JE4OwKb.d.cts → types-D0tVSLaf.d.cts} +122 -10
- package/dist/{types-B9rx1bt7.d.ts → types-D0tVSLaf.d.ts} +122 -10
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +1 -2
- package/dist/types.d.ts +1 -2
- package/dist/utils.cjs +5 -2
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +8 -1
- package/dist/utils.d.ts +8 -1
- package/dist/utils.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-65YIVTFE.js.map +0 -1
- package/dist/chunk-ARA27DRZ.js.map +0 -1
- package/dist/chunk-DTOB4IQZ.js.map +0 -1
- package/dist/chunk-HHIXOUFD.js.map +0 -1
- package/dist/chunk-R5TTSJK4.js.map +0 -1
- 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.
|
|
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
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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-
|
|
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 = {}) => (
|
|
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:
|
|
68
|
-
environment:
|
|
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:
|
|
149
|
-
environment:
|
|
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-
|
|
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-
|
|
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 = (
|
|
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 } =
|
|
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,
|
|
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-
|
|
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-
|
|
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 = () => (
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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-
|
|
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-
|
|
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 = () => (
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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-
|
|
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-
|
|
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-
|
|
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';
|
package/dist/hooks/customer.cjs
CHANGED
|
@@ -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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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(
|