@dodopayments/better-auth 1.3.5 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-47N33D2M.js +141 -0
- package/dist/chunk-47N33D2M.js.map +1 -0
- package/dist/{chunk-O3BTJOIO.js → chunk-K42Z6SPJ.js} +4 -5
- package/dist/{chunk-O3BTJOIO.js.map → chunk-K42Z6SPJ.js.map} +1 -1
- package/dist/client.d.cts +3 -1
- package/dist/client.d.ts +3 -1
- package/dist/hooks/customer.d.cts +3 -1
- package/dist/hooks/customer.d.ts +3 -1
- package/dist/index.cjs +138 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +179 -8
- package/dist/index.d.ts +179 -8
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/plugins/checkout.cjs +3 -4
- package/dist/plugins/checkout.cjs.map +1 -1
- package/dist/plugins/checkout.d.cts +3 -1
- package/dist/plugins/checkout.d.ts +3 -1
- package/dist/plugins/checkout.js +1 -1
- package/dist/plugins/portal.d.cts +3 -1
- package/dist/plugins/portal.d.ts +3 -1
- package/dist/plugins/usage.cjs +161 -0
- package/dist/plugins/usage.cjs.map +1 -0
- package/dist/plugins/usage.d.cts +177 -0
- package/dist/plugins/usage.d.ts +177 -0
- package/dist/plugins/usage.js +7 -0
- package/dist/plugins/usage.js.map +1 -0
- package/dist/plugins/webhooks.d.cts +3 -1
- package/dist/plugins/webhooks.d.ts +3 -1
- package/dist/{types-yAk7fHrK.d.cts → types-BxuQGgnN.d.cts} +8 -7
- package/dist/{types-yAk7fHrK.d.ts → types-D2QzXmgc.d.ts} +8 -7
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +3 -1
- package/dist/types.d.ts +3 -1
- package/package.json +2 -2
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// src/plugins/usage.ts
|
|
2
|
+
import {
|
|
3
|
+
APIError,
|
|
4
|
+
createAuthEndpoint,
|
|
5
|
+
sessionMiddleware
|
|
6
|
+
} from "better-auth/api";
|
|
7
|
+
import { z } from "zod/v3";
|
|
8
|
+
var EventInputSchema = z.object({
|
|
9
|
+
event_id: z.string(),
|
|
10
|
+
event_name: z.string(),
|
|
11
|
+
metadata: z.record(z.union([z.string(), z.number(), z.boolean()])).nullable().optional(),
|
|
12
|
+
timestamp: z.date({ coerce: true }).transform((d) => d.toISOString()).optional().describe(
|
|
13
|
+
"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."
|
|
14
|
+
)
|
|
15
|
+
});
|
|
16
|
+
var usage = () => (dodopayments) => {
|
|
17
|
+
return {
|
|
18
|
+
// Ingest usage data
|
|
19
|
+
dodoUsageIngest: createAuthEndpoint(
|
|
20
|
+
"/dodopayments/usage/ingest",
|
|
21
|
+
{
|
|
22
|
+
method: "POST",
|
|
23
|
+
body: EventInputSchema,
|
|
24
|
+
use: [sessionMiddleware]
|
|
25
|
+
},
|
|
26
|
+
async (ctx) => {
|
|
27
|
+
if (!ctx.context.session?.user?.id) {
|
|
28
|
+
throw new APIError("BAD_REQUEST", {
|
|
29
|
+
message: "User not found"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (!ctx.context.session?.user.emailVerified) {
|
|
33
|
+
throw new APIError("UNAUTHORIZED", {
|
|
34
|
+
message: "User email not verified"
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const customers = await dodopayments.customers.list({
|
|
39
|
+
email: ctx.context.session.user.email
|
|
40
|
+
});
|
|
41
|
+
let customer = customers.items[0];
|
|
42
|
+
if (!customer) {
|
|
43
|
+
customer = await createCustomer(
|
|
44
|
+
dodopayments,
|
|
45
|
+
ctx.context.session.user.email,
|
|
46
|
+
ctx.context.session.user.name
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const result = await dodopayments.usageEvents.ingest({
|
|
50
|
+
events: [
|
|
51
|
+
{
|
|
52
|
+
event_id: ctx.body.event_id,
|
|
53
|
+
customer_id: customer.customer_id,
|
|
54
|
+
event_name: ctx.body.event_name,
|
|
55
|
+
timestamp: ctx.body.timestamp,
|
|
56
|
+
metadata: ctx.body.metadata
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
});
|
|
60
|
+
return ctx.json({ ingested_count: result.ingested_count });
|
|
61
|
+
} catch (e) {
|
|
62
|
+
if (e instanceof Error) {
|
|
63
|
+
ctx.context.logger.error(
|
|
64
|
+
`User usage ingestion error: ${e.message}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
68
|
+
message: "Failed to record the user usage"
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
),
|
|
73
|
+
// List usage meters
|
|
74
|
+
dodoUsageMetersList: createAuthEndpoint(
|
|
75
|
+
"/dodopayments/usage/meters/list",
|
|
76
|
+
{
|
|
77
|
+
method: "GET",
|
|
78
|
+
query: z.object({
|
|
79
|
+
page_number: z.coerce.number().optional(),
|
|
80
|
+
page_size: z.coerce.number().optional(),
|
|
81
|
+
event_name: z.string().optional(),
|
|
82
|
+
meter_id: z.string().optional(),
|
|
83
|
+
start: z.string().optional(),
|
|
84
|
+
end: z.string().optional()
|
|
85
|
+
}).optional(),
|
|
86
|
+
use: [sessionMiddleware]
|
|
87
|
+
},
|
|
88
|
+
async (ctx) => {
|
|
89
|
+
if (!ctx.context.session?.user?.id) {
|
|
90
|
+
throw new APIError("BAD_REQUEST", {
|
|
91
|
+
message: "User not found"
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (!ctx.context.session?.user.emailVerified) {
|
|
95
|
+
throw new APIError("UNAUTHORIZED", {
|
|
96
|
+
message: "User email not verified"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const customers = await dodopayments.customers.list({
|
|
101
|
+
email: ctx.context.session.user.email
|
|
102
|
+
});
|
|
103
|
+
let customer = customers.items[0];
|
|
104
|
+
if (!customer) {
|
|
105
|
+
customer = await createCustomer(
|
|
106
|
+
dodopayments,
|
|
107
|
+
ctx.context.session.user.email,
|
|
108
|
+
ctx.context.session.user.name
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
const meters = await dodopayments.usageEvents.list({
|
|
112
|
+
customer_id: customer.customer_id,
|
|
113
|
+
...ctx.query
|
|
114
|
+
});
|
|
115
|
+
return ctx.json({ items: meters.items });
|
|
116
|
+
} catch (e) {
|
|
117
|
+
if (e instanceof Error) {
|
|
118
|
+
ctx.context.logger.error(
|
|
119
|
+
`User usage meter list error: ${e.message}`
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
123
|
+
message: "Failed to fetch the user usage"
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
async function createCustomer(dodopayments, email, name) {
|
|
131
|
+
const customer = await dodopayments.customers.create({
|
|
132
|
+
email,
|
|
133
|
+
name
|
|
134
|
+
});
|
|
135
|
+
return customer;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export {
|
|
139
|
+
usage
|
|
140
|
+
};
|
|
141
|
+
//# sourceMappingURL=chunk-47N33D2M.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 { DodoPayments } from \"dodopayments\";\nimport { Event } from \"dodopayments/resources/usage-events.mjs\";\nimport { z } from \"zod/v3\";\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 = () => (dodopayments: DodoPayments) => {\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 customers = await dodopayments.customers.list({\n email: ctx.context.session.user.email,\n });\n\n let customer = customers.items[0];\n\n // upsert the customer, if they don't exist in DodoPayments\n if (!customer) {\n customer = await createCustomer(\n dodopayments,\n ctx.context.session.user.email,\n ctx.context.session.user.name,\n );\n }\n\n const result = await dodopayments.usageEvents.ingest({\n events: [\n {\n event_id: ctx.body.event_id,\n customer_id: customer.customer_id,\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 customers = await dodopayments.customers.list({\n email: ctx.context.session.user.email,\n });\n\n let customer = customers.items[0];\n\n // upsert the customer, if they don't exist in DodoPayments\n if (!customer) {\n customer = await createCustomer(\n dodopayments,\n ctx.context.session.user.email,\n ctx.context.session.user.name,\n );\n }\n\n const meters = await dodopayments.usageEvents.list({\n customer_id: customer.customer_id,\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\nasync function createCustomer(\n dodopayments: DodoPayments,\n email: string,\n name: string,\n) {\n const customer = await dodopayments.customers.create({\n email,\n name,\n });\n\n return customer;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -133,11 +133,10 @@ var checkout = (checkoutOptions = {}) => (dodopayments) => {
|
|
|
133
133
|
sessionPayload: {
|
|
134
134
|
...ctx.body,
|
|
135
135
|
product_cart,
|
|
136
|
-
customer: {
|
|
136
|
+
customer: session?.user.email ? {
|
|
137
137
|
email: session?.user.email,
|
|
138
|
-
name: session?.user.name
|
|
139
|
-
|
|
140
|
-
},
|
|
138
|
+
name: session?.user.name
|
|
139
|
+
} : ctx.body.customer,
|
|
141
140
|
metadata: ctx.body.referenceId ? {
|
|
142
141
|
referenceId: ctx.body.referenceId,
|
|
143
142
|
...ctx.body.metadata
|
|
@@ -174,4 +173,4 @@ var checkout = (checkoutOptions = {}) => (dodopayments) => {
|
|
|
174
173
|
export {
|
|
175
174
|
checkout
|
|
176
175
|
};
|
|
177
|
-
//# sourceMappingURL=chunk-
|
|
176
|
+
//# sourceMappingURL=chunk-K42Z6SPJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/plugins/checkout.ts"],"sourcesContent":["import type DodoPayments from \"dodopayments\";\nimport { APIError, getSessionFromCtx } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\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 (dodopayments: DodoPayments) => {\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: dodopayments.bearerToken,\n environment: dodopayments.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: {\n email: session?.user.email,\n name: session?.user.name,\n ...ctx.body.customer,\n },\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: dodopayments.bearerToken,\n environment: dodopayments.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
|
+
{"version":3,"sources":["../src/plugins/checkout.ts"],"sourcesContent":["import type DodoPayments from \"dodopayments\";\nimport { APIError, getSessionFromCtx } from \"better-auth/api\";\nimport { createAuthEndpoint } from \"better-auth/plugins\";\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 (dodopayments: DodoPayments) => {\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: dodopayments.bearerToken,\n environment: dodopayments.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: dodopayments.bearerToken,\n environment: dodopayments.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":[]}
|
package/dist/client.d.cts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { dodopaymentsClient } from './index.cjs';
|
|
2
2
|
import 'better-auth';
|
|
3
|
-
import '
|
|
3
|
+
import 'dodopayments/resources/usage-events.mjs';
|
|
4
|
+
import './types-BxuQGgnN.cjs';
|
|
4
5
|
import 'dodopayments';
|
|
5
6
|
import 'better-call';
|
|
6
7
|
import 'zod/v3';
|
|
7
8
|
import '@dodopayments/core/webhook';
|
|
9
|
+
import './plugins/usage.cjs';
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { dodopaymentsClient } from './index.js';
|
|
2
2
|
import 'better-auth';
|
|
3
|
-
import '
|
|
3
|
+
import 'dodopayments/resources/usage-events.mjs';
|
|
4
|
+
import './types-D2QzXmgc.js';
|
|
4
5
|
import 'dodopayments';
|
|
5
6
|
import 'better-call';
|
|
6
7
|
import 'zod/v3';
|
|
7
8
|
import '@dodopayments/core/webhook';
|
|
9
|
+
import './plugins/usage.js';
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { User, GenericEndpointContext } from 'better-auth';
|
|
2
|
-
import { D as DodoPaymentsOptions } from '../types-
|
|
2
|
+
import { D as DodoPaymentsOptions } from '../types-BxuQGgnN.cjs';
|
|
3
3
|
import 'dodopayments';
|
|
4
4
|
import 'better-call';
|
|
5
5
|
import 'zod/v3';
|
|
6
6
|
import '@dodopayments/core/webhook';
|
|
7
|
+
import '../plugins/usage.cjs';
|
|
8
|
+
import 'dodopayments/resources/usage-events.mjs';
|
|
7
9
|
|
|
8
10
|
declare const onUserCreate: (options: DodoPaymentsOptions) => (user: User, ctx?: GenericEndpointContext) => Promise<void>;
|
|
9
11
|
declare const onUserUpdate: (options: DodoPaymentsOptions) => (user: User, ctx?: GenericEndpointContext) => Promise<void>;
|
package/dist/hooks/customer.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { User, GenericEndpointContext } from 'better-auth';
|
|
2
|
-
import { D as DodoPaymentsOptions } from '../types-
|
|
2
|
+
import { D as DodoPaymentsOptions } from '../types-D2QzXmgc.js';
|
|
3
3
|
import 'dodopayments';
|
|
4
4
|
import 'better-call';
|
|
5
5
|
import 'zod/v3';
|
|
6
6
|
import '@dodopayments/core/webhook';
|
|
7
|
+
import '../plugins/usage.js';
|
|
8
|
+
import 'dodopayments/resources/usage-events.mjs';
|
|
7
9
|
|
|
8
10
|
declare const onUserCreate: (options: DodoPaymentsOptions) => (user: User, ctx?: GenericEndpointContext) => Promise<void>;
|
|
9
11
|
declare const onUserUpdate: (options: DodoPaymentsOptions) => (user: User, ctx?: GenericEndpointContext) => Promise<void>;
|
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
dodopayments: () => dodopayments,
|
|
25
25
|
dodopaymentsClient: () => dodopaymentsClient,
|
|
26
26
|
portal: () => portal,
|
|
27
|
+
usage: () => usage,
|
|
27
28
|
webhooks: () => webhooks
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -421,11 +422,10 @@ var checkout = (checkoutOptions = {}) => (dodopayments2) => {
|
|
|
421
422
|
sessionPayload: {
|
|
422
423
|
...ctx.body,
|
|
423
424
|
product_cart,
|
|
424
|
-
customer: {
|
|
425
|
+
customer: session?.user.email ? {
|
|
425
426
|
email: session?.user.email,
|
|
426
|
-
name: session?.user.name
|
|
427
|
-
|
|
428
|
-
},
|
|
427
|
+
name: session?.user.name
|
|
428
|
+
} : ctx.body.customer,
|
|
429
429
|
metadata: ctx.body.referenceId ? {
|
|
430
430
|
referenceId: ctx.body.referenceId,
|
|
431
431
|
...ctx.body.metadata
|
|
@@ -533,6 +533,139 @@ var webhooks = (options) => (_dodopayments) => {
|
|
|
533
533
|
};
|
|
534
534
|
};
|
|
535
535
|
|
|
536
|
+
// src/plugins/usage.ts
|
|
537
|
+
var import_api6 = require("better-auth/api");
|
|
538
|
+
var import_v33 = require("zod/v3");
|
|
539
|
+
var EventInputSchema = import_v33.z.object({
|
|
540
|
+
event_id: import_v33.z.string(),
|
|
541
|
+
event_name: import_v33.z.string(),
|
|
542
|
+
metadata: import_v33.z.record(import_v33.z.union([import_v33.z.string(), import_v33.z.number(), import_v33.z.boolean()])).nullable().optional(),
|
|
543
|
+
timestamp: import_v33.z.date({ coerce: true }).transform((d) => d.toISOString()).optional().describe(
|
|
544
|
+
"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."
|
|
545
|
+
)
|
|
546
|
+
});
|
|
547
|
+
var usage = () => (dodopayments2) => {
|
|
548
|
+
return {
|
|
549
|
+
// Ingest usage data
|
|
550
|
+
dodoUsageIngest: (0, import_api6.createAuthEndpoint)(
|
|
551
|
+
"/dodopayments/usage/ingest",
|
|
552
|
+
{
|
|
553
|
+
method: "POST",
|
|
554
|
+
body: EventInputSchema,
|
|
555
|
+
use: [import_api6.sessionMiddleware]
|
|
556
|
+
},
|
|
557
|
+
async (ctx) => {
|
|
558
|
+
if (!ctx.context.session?.user?.id) {
|
|
559
|
+
throw new import_api6.APIError("BAD_REQUEST", {
|
|
560
|
+
message: "User not found"
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
if (!ctx.context.session?.user.emailVerified) {
|
|
564
|
+
throw new import_api6.APIError("UNAUTHORIZED", {
|
|
565
|
+
message: "User email not verified"
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
try {
|
|
569
|
+
const customers = await dodopayments2.customers.list({
|
|
570
|
+
email: ctx.context.session.user.email
|
|
571
|
+
});
|
|
572
|
+
let customer = customers.items[0];
|
|
573
|
+
if (!customer) {
|
|
574
|
+
customer = await createCustomer2(
|
|
575
|
+
dodopayments2,
|
|
576
|
+
ctx.context.session.user.email,
|
|
577
|
+
ctx.context.session.user.name
|
|
578
|
+
);
|
|
579
|
+
}
|
|
580
|
+
const result = await dodopayments2.usageEvents.ingest({
|
|
581
|
+
events: [
|
|
582
|
+
{
|
|
583
|
+
event_id: ctx.body.event_id,
|
|
584
|
+
customer_id: customer.customer_id,
|
|
585
|
+
event_name: ctx.body.event_name,
|
|
586
|
+
timestamp: ctx.body.timestamp,
|
|
587
|
+
metadata: ctx.body.metadata
|
|
588
|
+
}
|
|
589
|
+
]
|
|
590
|
+
});
|
|
591
|
+
return ctx.json({ ingested_count: result.ingested_count });
|
|
592
|
+
} catch (e) {
|
|
593
|
+
if (e instanceof Error) {
|
|
594
|
+
ctx.context.logger.error(
|
|
595
|
+
`User usage ingestion error: ${e.message}`
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
throw new import_api6.APIError("INTERNAL_SERVER_ERROR", {
|
|
599
|
+
message: "Failed to record the user usage"
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
),
|
|
604
|
+
// List usage meters
|
|
605
|
+
dodoUsageMetersList: (0, import_api6.createAuthEndpoint)(
|
|
606
|
+
"/dodopayments/usage/meters/list",
|
|
607
|
+
{
|
|
608
|
+
method: "GET",
|
|
609
|
+
query: import_v33.z.object({
|
|
610
|
+
page_number: import_v33.z.coerce.number().optional(),
|
|
611
|
+
page_size: import_v33.z.coerce.number().optional(),
|
|
612
|
+
event_name: import_v33.z.string().optional(),
|
|
613
|
+
meter_id: import_v33.z.string().optional(),
|
|
614
|
+
start: import_v33.z.string().optional(),
|
|
615
|
+
end: import_v33.z.string().optional()
|
|
616
|
+
}).optional(),
|
|
617
|
+
use: [import_api6.sessionMiddleware]
|
|
618
|
+
},
|
|
619
|
+
async (ctx) => {
|
|
620
|
+
if (!ctx.context.session?.user?.id) {
|
|
621
|
+
throw new import_api6.APIError("BAD_REQUEST", {
|
|
622
|
+
message: "User not found"
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
if (!ctx.context.session?.user.emailVerified) {
|
|
626
|
+
throw new import_api6.APIError("UNAUTHORIZED", {
|
|
627
|
+
message: "User email not verified"
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
try {
|
|
631
|
+
const customers = await dodopayments2.customers.list({
|
|
632
|
+
email: ctx.context.session.user.email
|
|
633
|
+
});
|
|
634
|
+
let customer = customers.items[0];
|
|
635
|
+
if (!customer) {
|
|
636
|
+
customer = await createCustomer2(
|
|
637
|
+
dodopayments2,
|
|
638
|
+
ctx.context.session.user.email,
|
|
639
|
+
ctx.context.session.user.name
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
const meters = await dodopayments2.usageEvents.list({
|
|
643
|
+
customer_id: customer.customer_id,
|
|
644
|
+
...ctx.query
|
|
645
|
+
});
|
|
646
|
+
return ctx.json({ items: meters.items });
|
|
647
|
+
} catch (e) {
|
|
648
|
+
if (e instanceof Error) {
|
|
649
|
+
ctx.context.logger.error(
|
|
650
|
+
`User usage meter list error: ${e.message}`
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
throw new import_api6.APIError("INTERNAL_SERVER_ERROR", {
|
|
654
|
+
message: "Failed to fetch the user usage"
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
)
|
|
659
|
+
};
|
|
660
|
+
};
|
|
661
|
+
async function createCustomer2(dodopayments2, email, name) {
|
|
662
|
+
const customer = await dodopayments2.customers.create({
|
|
663
|
+
email,
|
|
664
|
+
name
|
|
665
|
+
});
|
|
666
|
+
return customer;
|
|
667
|
+
}
|
|
668
|
+
|
|
536
669
|
// src/index.ts
|
|
537
670
|
var dodopayments = (options) => {
|
|
538
671
|
const plugins = options.use.map((use) => use(options.client)).reduce((acc, plugin) => {
|
|
@@ -568,6 +701,7 @@ var dodopayments = (options) => {
|
|
|
568
701
|
dodopayments,
|
|
569
702
|
dodopaymentsClient,
|
|
570
703
|
portal,
|
|
704
|
+
usage,
|
|
571
705
|
webhooks
|
|
572
706
|
});
|
|
573
707
|
//# sourceMappingURL=index.cjs.map
|