@polar-sh/better-auth 0.1.2 → 1.0.1
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 +361 -64
- package/dist/index.cjs +648 -406
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1156 -181
- package/dist/index.d.ts +1156 -181
- package/dist/index.js +646 -405
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -1,401 +1,10 @@
|
|
|
1
|
-
// src/endpoints/checkout.ts
|
|
2
|
-
import { APIError, getSessionFromCtx } from "better-auth/api";
|
|
3
|
-
import { createAuthEndpoint } from "better-auth/plugins";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
var checkout = (options) => createAuthEndpoint(
|
|
6
|
-
"/checkout",
|
|
7
|
-
{
|
|
8
|
-
method: "GET",
|
|
9
|
-
query: z.object({
|
|
10
|
-
products: z.union([z.array(z.string()), z.string()])
|
|
11
|
-
})
|
|
12
|
-
},
|
|
13
|
-
async (ctx) => {
|
|
14
|
-
if (!options.checkout?.enabled) {
|
|
15
|
-
throw new APIError("BAD_REQUEST", {
|
|
16
|
-
message: "Checkout is not enabled"
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
const products = ctx.query.products;
|
|
20
|
-
const session = await getSessionFromCtx(ctx);
|
|
21
|
-
if (options.checkout.authenticatedUsersOnly && !session?.user.id) {
|
|
22
|
-
throw new APIError("UNAUTHORIZED", {
|
|
23
|
-
message: "You must be logged in to checkout"
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
try {
|
|
27
|
-
const checkout2 = await options.client.checkouts.create({
|
|
28
|
-
customerExternalId: session?.user.id,
|
|
29
|
-
products: Array.isArray(products) ? products : [products],
|
|
30
|
-
successUrl: options.checkout.successUrl ? new URL(options.checkout.successUrl, ctx.request?.url).toString() : void 0
|
|
31
|
-
});
|
|
32
|
-
return ctx.redirect(checkout2.url);
|
|
33
|
-
} catch (e) {
|
|
34
|
-
if (e instanceof Error) {
|
|
35
|
-
ctx.context.logger.error(
|
|
36
|
-
`Polar checkout creation failed. Error: ${e.message}`
|
|
37
|
-
);
|
|
38
|
-
}
|
|
39
|
-
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
40
|
-
message: "Checkout creation failed"
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
);
|
|
45
|
-
var checkoutWithSlug = (options) => createAuthEndpoint(
|
|
46
|
-
"/checkout/:slug",
|
|
47
|
-
{
|
|
48
|
-
method: "GET",
|
|
49
|
-
params: z.object({
|
|
50
|
-
slug: z.string()
|
|
51
|
-
})
|
|
52
|
-
},
|
|
53
|
-
async (ctx) => {
|
|
54
|
-
if (!options.checkout?.enabled) {
|
|
55
|
-
throw new APIError("BAD_REQUEST", {
|
|
56
|
-
message: "Checkout is not enabled"
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
const products = await (typeof options.checkout.products === "function" ? options.checkout.products() : options.checkout.products);
|
|
60
|
-
const productId = products.find(
|
|
61
|
-
(product) => product.slug === ctx.params?.["slug"]
|
|
62
|
-
)?.productId;
|
|
63
|
-
if (!productId) {
|
|
64
|
-
throw new APIError("BAD_REQUEST", {
|
|
65
|
-
message: "Product Id not found"
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
const session = await getSessionFromCtx(ctx);
|
|
69
|
-
if (options.checkout.authenticatedUsersOnly && !session?.user.id) {
|
|
70
|
-
throw new APIError("UNAUTHORIZED", {
|
|
71
|
-
message: "You must be logged in to checkout"
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
try {
|
|
75
|
-
const checkout2 = await options.client.checkouts.create({
|
|
76
|
-
customerExternalId: session?.user.id,
|
|
77
|
-
products: [productId],
|
|
78
|
-
successUrl: options.checkout.successUrl ? new URL(options.checkout.successUrl, ctx.request?.url).toString() : void 0
|
|
79
|
-
});
|
|
80
|
-
return ctx.redirect(checkout2.url);
|
|
81
|
-
} catch (e) {
|
|
82
|
-
if (e instanceof Error) {
|
|
83
|
-
ctx.context.logger.error(
|
|
84
|
-
`Polar checkout creation failed. Error: ${e.message}`
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
88
|
-
message: "Checkout creation failed"
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
// src/endpoints/customerPortal.ts
|
|
95
|
-
import { APIError as APIError2, sessionMiddleware } from "better-auth/api";
|
|
96
|
-
import { createAuthEndpoint as createAuthEndpoint2 } from "better-auth/plugins";
|
|
97
|
-
var customerPortal = (options) => createAuthEndpoint2(
|
|
98
|
-
"/portal",
|
|
99
|
-
{
|
|
100
|
-
method: "GET",
|
|
101
|
-
use: [sessionMiddleware]
|
|
102
|
-
},
|
|
103
|
-
async (ctx) => {
|
|
104
|
-
if (!options.enableCustomerPortal) {
|
|
105
|
-
throw new APIError2("BAD_REQUEST", {
|
|
106
|
-
message: "Customer portal is not enabled"
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
if (!ctx.context.session?.user.id) {
|
|
110
|
-
throw new APIError2("BAD_REQUEST", {
|
|
111
|
-
message: "User not found"
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
try {
|
|
115
|
-
const customerSession = await options.client.customerSessions.create({
|
|
116
|
-
customerExternalId: ctx.context.session?.user.id
|
|
117
|
-
});
|
|
118
|
-
return ctx.redirect(customerSession.customerPortalUrl);
|
|
119
|
-
} catch (e) {
|
|
120
|
-
if (e instanceof Error) {
|
|
121
|
-
ctx.context.logger.error(
|
|
122
|
-
`Polar customer portal creation failed. Error: ${e.message}`
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
126
|
-
message: "Customer portal creation failed"
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
// src/endpoints/customerState.ts
|
|
133
|
-
import { APIError as APIError3, sessionMiddleware as sessionMiddleware2 } from "better-auth/api";
|
|
134
|
-
import { createAuthEndpoint as createAuthEndpoint3 } from "better-auth/plugins";
|
|
135
|
-
var customerState = (options) => createAuthEndpoint3(
|
|
136
|
-
"/state",
|
|
137
|
-
{
|
|
138
|
-
method: "GET",
|
|
139
|
-
use: [sessionMiddleware2]
|
|
140
|
-
},
|
|
141
|
-
async (ctx) => {
|
|
142
|
-
if (!ctx.context.session.user.id) {
|
|
143
|
-
throw new APIError3("BAD_REQUEST", {
|
|
144
|
-
message: "User not found"
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
try {
|
|
148
|
-
const state = await options.client.customers.getStateExternal({
|
|
149
|
-
externalId: ctx.context.session?.user.id
|
|
150
|
-
});
|
|
151
|
-
return ctx.json(state);
|
|
152
|
-
} catch (e) {
|
|
153
|
-
if (e instanceof Error) {
|
|
154
|
-
ctx.context.logger.error(
|
|
155
|
-
`Polar subscriptions list failed. Error: ${e.message}`
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
throw new APIError3("INTERNAL_SERVER_ERROR", {
|
|
159
|
-
message: "Subscriptions list failed"
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
);
|
|
164
|
-
|
|
165
|
-
// src/endpoints/webhooks.ts
|
|
166
|
-
import { validateEvent } from "@polar-sh/sdk/webhooks";
|
|
167
|
-
import { APIError as APIError4 } from "better-auth/api";
|
|
168
|
-
import { createAuthEndpoint as createAuthEndpoint4 } from "better-auth/plugins";
|
|
169
|
-
var webhooks = (options) => createAuthEndpoint4(
|
|
170
|
-
"/polar/webhooks",
|
|
171
|
-
{
|
|
172
|
-
method: "POST",
|
|
173
|
-
metadata: {
|
|
174
|
-
isAction: false
|
|
175
|
-
},
|
|
176
|
-
cloneRequest: true
|
|
177
|
-
},
|
|
178
|
-
async (ctx) => {
|
|
179
|
-
const { webhooks: webhooks2 } = options;
|
|
180
|
-
if (!webhooks2) {
|
|
181
|
-
throw new APIError4("NOT_FOUND", {
|
|
182
|
-
message: "Webhooks not enabled"
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
const {
|
|
186
|
-
secret,
|
|
187
|
-
onPayload,
|
|
188
|
-
onCheckoutCreated,
|
|
189
|
-
onCheckoutUpdated,
|
|
190
|
-
onOrderCreated,
|
|
191
|
-
onOrderPaid,
|
|
192
|
-
onOrderRefunded,
|
|
193
|
-
onRefundCreated,
|
|
194
|
-
onRefundUpdated,
|
|
195
|
-
onSubscriptionCreated,
|
|
196
|
-
onSubscriptionUpdated,
|
|
197
|
-
onSubscriptionActive,
|
|
198
|
-
onSubscriptionCanceled,
|
|
199
|
-
onSubscriptionRevoked,
|
|
200
|
-
onSubscriptionUncanceled,
|
|
201
|
-
onProductCreated,
|
|
202
|
-
onProductUpdated,
|
|
203
|
-
onOrganizationUpdated,
|
|
204
|
-
onBenefitCreated,
|
|
205
|
-
onBenefitUpdated,
|
|
206
|
-
onBenefitGrantCreated,
|
|
207
|
-
onBenefitGrantUpdated,
|
|
208
|
-
onBenefitGrantRevoked,
|
|
209
|
-
onCustomerCreated,
|
|
210
|
-
onCustomerUpdated,
|
|
211
|
-
onCustomerDeleted,
|
|
212
|
-
onCustomerStateChanged
|
|
213
|
-
} = webhooks2;
|
|
214
|
-
if (!ctx.request?.body) {
|
|
215
|
-
throw new APIError4("INTERNAL_SERVER_ERROR");
|
|
216
|
-
}
|
|
217
|
-
const buf = await ctx.request.text();
|
|
218
|
-
let event;
|
|
219
|
-
try {
|
|
220
|
-
if (!secret) {
|
|
221
|
-
throw new APIError4("INTERNAL_SERVER_ERROR", {
|
|
222
|
-
message: "Polar webhook secret not found"
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
const headers = {
|
|
226
|
-
"webhook-id": ctx.request.headers.get("webhook-id"),
|
|
227
|
-
"webhook-timestamp": ctx.request.headers.get(
|
|
228
|
-
"webhook-timestamp"
|
|
229
|
-
),
|
|
230
|
-
"webhook-signature": ctx.request.headers.get(
|
|
231
|
-
"webhook-signature"
|
|
232
|
-
)
|
|
233
|
-
};
|
|
234
|
-
event = validateEvent(buf, headers, secret);
|
|
235
|
-
} catch (err) {
|
|
236
|
-
if (err instanceof Error) {
|
|
237
|
-
ctx.context.logger.error(`${err.message}`);
|
|
238
|
-
throw new APIError4("BAD_REQUEST", {
|
|
239
|
-
message: `Webhook Error: ${err.message}`
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
throw new APIError4("BAD_REQUEST", {
|
|
243
|
-
message: `Webhook Error: ${err}`
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
try {
|
|
247
|
-
if (onPayload) {
|
|
248
|
-
onPayload(event);
|
|
249
|
-
}
|
|
250
|
-
switch (event.type) {
|
|
251
|
-
case "checkout.created":
|
|
252
|
-
if (onCheckoutCreated) {
|
|
253
|
-
onCheckoutCreated(event);
|
|
254
|
-
}
|
|
255
|
-
break;
|
|
256
|
-
case "checkout.updated":
|
|
257
|
-
if (onCheckoutUpdated) {
|
|
258
|
-
onCheckoutUpdated(event);
|
|
259
|
-
}
|
|
260
|
-
break;
|
|
261
|
-
case "order.created":
|
|
262
|
-
if (onOrderCreated) {
|
|
263
|
-
onOrderCreated(event);
|
|
264
|
-
}
|
|
265
|
-
break;
|
|
266
|
-
case "order.paid":
|
|
267
|
-
if (onOrderPaid) {
|
|
268
|
-
onOrderPaid(event);
|
|
269
|
-
}
|
|
270
|
-
break;
|
|
271
|
-
case "subscription.created":
|
|
272
|
-
if (onSubscriptionCreated) {
|
|
273
|
-
onSubscriptionCreated(event);
|
|
274
|
-
}
|
|
275
|
-
break;
|
|
276
|
-
case "subscription.updated":
|
|
277
|
-
if (onSubscriptionUpdated) {
|
|
278
|
-
onSubscriptionUpdated(event);
|
|
279
|
-
}
|
|
280
|
-
break;
|
|
281
|
-
case "subscription.active":
|
|
282
|
-
if (onSubscriptionActive) {
|
|
283
|
-
onSubscriptionActive(event);
|
|
284
|
-
}
|
|
285
|
-
break;
|
|
286
|
-
case "subscription.canceled":
|
|
287
|
-
if (onSubscriptionCanceled) {
|
|
288
|
-
onSubscriptionCanceled(event);
|
|
289
|
-
}
|
|
290
|
-
break;
|
|
291
|
-
case "subscription.uncanceled":
|
|
292
|
-
if (onSubscriptionUncanceled) {
|
|
293
|
-
onSubscriptionUncanceled(event);
|
|
294
|
-
}
|
|
295
|
-
break;
|
|
296
|
-
case "subscription.revoked":
|
|
297
|
-
if (onSubscriptionRevoked) {
|
|
298
|
-
onSubscriptionRevoked(event);
|
|
299
|
-
}
|
|
300
|
-
break;
|
|
301
|
-
case "product.created":
|
|
302
|
-
if (onProductCreated) {
|
|
303
|
-
onProductCreated(event);
|
|
304
|
-
}
|
|
305
|
-
break;
|
|
306
|
-
case "product.updated":
|
|
307
|
-
if (onProductUpdated) {
|
|
308
|
-
onProductUpdated(event);
|
|
309
|
-
}
|
|
310
|
-
break;
|
|
311
|
-
case "organization.updated":
|
|
312
|
-
if (onOrganizationUpdated) {
|
|
313
|
-
onOrganizationUpdated(event);
|
|
314
|
-
}
|
|
315
|
-
break;
|
|
316
|
-
case "benefit.created":
|
|
317
|
-
if (onBenefitCreated) {
|
|
318
|
-
onBenefitCreated(event);
|
|
319
|
-
}
|
|
320
|
-
break;
|
|
321
|
-
case "benefit.updated":
|
|
322
|
-
if (onBenefitUpdated) {
|
|
323
|
-
onBenefitUpdated(event);
|
|
324
|
-
}
|
|
325
|
-
break;
|
|
326
|
-
case "benefit_grant.created":
|
|
327
|
-
if (onBenefitGrantCreated) {
|
|
328
|
-
onBenefitGrantCreated(event);
|
|
329
|
-
}
|
|
330
|
-
break;
|
|
331
|
-
case "benefit_grant.updated":
|
|
332
|
-
if (onBenefitGrantUpdated) {
|
|
333
|
-
onBenefitGrantUpdated(event);
|
|
334
|
-
}
|
|
335
|
-
break;
|
|
336
|
-
case "benefit_grant.revoked":
|
|
337
|
-
if (onBenefitGrantRevoked) {
|
|
338
|
-
onBenefitGrantRevoked(event);
|
|
339
|
-
}
|
|
340
|
-
break;
|
|
341
|
-
case "order.refunded":
|
|
342
|
-
if (onOrderRefunded) {
|
|
343
|
-
onOrderRefunded(event);
|
|
344
|
-
}
|
|
345
|
-
break;
|
|
346
|
-
case "refund.created":
|
|
347
|
-
if (onRefundCreated) {
|
|
348
|
-
onRefundCreated(event);
|
|
349
|
-
}
|
|
350
|
-
break;
|
|
351
|
-
case "refund.updated":
|
|
352
|
-
if (onRefundUpdated) {
|
|
353
|
-
onRefundUpdated(event);
|
|
354
|
-
}
|
|
355
|
-
break;
|
|
356
|
-
case "customer.created":
|
|
357
|
-
if (onCustomerCreated) {
|
|
358
|
-
onCustomerCreated(event);
|
|
359
|
-
}
|
|
360
|
-
break;
|
|
361
|
-
case "customer.updated":
|
|
362
|
-
if (onCustomerUpdated) {
|
|
363
|
-
onCustomerUpdated(event);
|
|
364
|
-
}
|
|
365
|
-
break;
|
|
366
|
-
case "customer.deleted":
|
|
367
|
-
if (onCustomerDeleted) {
|
|
368
|
-
onCustomerDeleted(event);
|
|
369
|
-
}
|
|
370
|
-
break;
|
|
371
|
-
case "customer.state_changed":
|
|
372
|
-
if (onCustomerStateChanged) {
|
|
373
|
-
onCustomerStateChanged(event);
|
|
374
|
-
}
|
|
375
|
-
break;
|
|
376
|
-
}
|
|
377
|
-
} catch (e) {
|
|
378
|
-
if (e instanceof Error) {
|
|
379
|
-
ctx.context.logger.error(`Polar webhook failed. Error: ${e.message}`);
|
|
380
|
-
} else {
|
|
381
|
-
ctx.context.logger.error(`Polar webhook failed. Error: ${e}`);
|
|
382
|
-
}
|
|
383
|
-
throw new APIError4("BAD_REQUEST", {
|
|
384
|
-
message: "Webhook error: See server logs for more information."
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
return ctx.json({ received: true });
|
|
388
|
-
}
|
|
389
|
-
);
|
|
390
|
-
|
|
391
1
|
// src/hooks/customer.ts
|
|
392
|
-
import { APIError
|
|
2
|
+
import { APIError } from "better-auth/api";
|
|
393
3
|
var onUserCreate = (options) => async (user, ctx) => {
|
|
394
4
|
if (ctx && options.createCustomerOnSignUp) {
|
|
395
5
|
try {
|
|
396
|
-
const params = options.getCustomerCreateParams
|
|
397
|
-
user
|
|
398
|
-
session: ctx.context.session.session
|
|
6
|
+
const params = options.getCustomerCreateParams ? await options.getCustomerCreateParams({
|
|
7
|
+
user
|
|
399
8
|
}) : {};
|
|
400
9
|
const { result: existingCustomers } = await options.client.customers.list({ email: user.email });
|
|
401
10
|
const existingCustomer = existingCustomers.items[0];
|
|
@@ -404,25 +13,27 @@ var onUserCreate = (options) => async (user, ctx) => {
|
|
|
404
13
|
await options.client.customers.update({
|
|
405
14
|
id: existingCustomer.id,
|
|
406
15
|
customerUpdate: {
|
|
407
|
-
externalId: user.id
|
|
16
|
+
externalId: user.id,
|
|
17
|
+
...params
|
|
408
18
|
}
|
|
409
19
|
});
|
|
410
20
|
}
|
|
411
21
|
} else {
|
|
412
|
-
await options.client.customers.create({
|
|
22
|
+
const customer = await options.client.customers.create({
|
|
413
23
|
...params,
|
|
414
24
|
email: user.email,
|
|
415
25
|
name: user.name,
|
|
416
26
|
externalId: user.id
|
|
417
27
|
});
|
|
28
|
+
console.log(customer);
|
|
418
29
|
}
|
|
419
30
|
} catch (e) {
|
|
420
31
|
if (e instanceof Error) {
|
|
421
|
-
throw new
|
|
32
|
+
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
422
33
|
message: `Polar customer creation failed. Error: ${e.message}`
|
|
423
34
|
});
|
|
424
35
|
}
|
|
425
|
-
throw new
|
|
36
|
+
throw new APIError("INTERNAL_SERVER_ERROR", {
|
|
426
37
|
message: `Polar customer creation failed. Error: ${e}`
|
|
427
38
|
});
|
|
428
39
|
}
|
|
@@ -433,7 +44,7 @@ var onUserUpdate = (options) => async (user, ctx) => {
|
|
|
433
44
|
try {
|
|
434
45
|
await options.client.customers.updateExternal({
|
|
435
46
|
externalId: user.id,
|
|
436
|
-
|
|
47
|
+
customerUpdateExternalID: {
|
|
437
48
|
email: user.email,
|
|
438
49
|
name: user.name
|
|
439
50
|
}
|
|
@@ -450,16 +61,641 @@ var onUserUpdate = (options) => async (user, ctx) => {
|
|
|
450
61
|
}
|
|
451
62
|
};
|
|
452
63
|
|
|
64
|
+
// src/client.ts
|
|
65
|
+
var polarClient = () => {
|
|
66
|
+
return {
|
|
67
|
+
id: "polar-client",
|
|
68
|
+
$InferServerPlugin: {}
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/plugins/portal.ts
|
|
73
|
+
import { APIError as APIError2 } from "better-auth/api";
|
|
74
|
+
import { sessionMiddleware } from "better-auth/api";
|
|
75
|
+
import { createAuthEndpoint } from "better-auth/plugins";
|
|
76
|
+
import { z } from "zod";
|
|
77
|
+
var portal = () => (polar2) => {
|
|
78
|
+
return {
|
|
79
|
+
portal: createAuthEndpoint(
|
|
80
|
+
"/customer/portal",
|
|
81
|
+
{
|
|
82
|
+
method: "GET",
|
|
83
|
+
use: [sessionMiddleware]
|
|
84
|
+
},
|
|
85
|
+
async (ctx) => {
|
|
86
|
+
if (!ctx.context.session?.user.id) {
|
|
87
|
+
throw new APIError2("BAD_REQUEST", {
|
|
88
|
+
message: "User not found"
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
try {
|
|
92
|
+
const customerSession = await polar2.customerSessions.create({
|
|
93
|
+
customerExternalId: ctx.context.session?.user.id
|
|
94
|
+
});
|
|
95
|
+
return ctx.json({
|
|
96
|
+
url: customerSession.customerPortalUrl,
|
|
97
|
+
redirect: true
|
|
98
|
+
});
|
|
99
|
+
} catch (e) {
|
|
100
|
+
if (e instanceof Error) {
|
|
101
|
+
ctx.context.logger.error(
|
|
102
|
+
`Polar customer portal creation failed. Error: ${e.message}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
106
|
+
message: "Customer portal creation failed"
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
),
|
|
111
|
+
state: createAuthEndpoint(
|
|
112
|
+
"/customer/state",
|
|
113
|
+
{
|
|
114
|
+
method: "GET",
|
|
115
|
+
use: [sessionMiddleware]
|
|
116
|
+
},
|
|
117
|
+
async (ctx) => {
|
|
118
|
+
if (!ctx.context.session.user.id) {
|
|
119
|
+
throw new APIError2("BAD_REQUEST", {
|
|
120
|
+
message: "User not found"
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const state = await polar2.customers.getStateExternal({
|
|
125
|
+
externalId: ctx.context.session?.user.id
|
|
126
|
+
});
|
|
127
|
+
return ctx.json(state);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
if (e instanceof Error) {
|
|
130
|
+
ctx.context.logger.error(
|
|
131
|
+
`Polar subscriptions list failed. Error: ${e.message}`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
135
|
+
message: "Subscriptions list failed"
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
),
|
|
140
|
+
benefits: createAuthEndpoint(
|
|
141
|
+
"/customer/benefits/list",
|
|
142
|
+
{
|
|
143
|
+
method: "GET",
|
|
144
|
+
query: z.object({
|
|
145
|
+
page: z.coerce.number().optional(),
|
|
146
|
+
limit: z.coerce.number().optional()
|
|
147
|
+
}).optional(),
|
|
148
|
+
use: [sessionMiddleware]
|
|
149
|
+
},
|
|
150
|
+
async (ctx) => {
|
|
151
|
+
if (!ctx.context.session.user.id) {
|
|
152
|
+
throw new APIError2("BAD_REQUEST", {
|
|
153
|
+
message: "User not found"
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
try {
|
|
157
|
+
const customerSession = await polar2.customerSessions.create({
|
|
158
|
+
customerExternalId: ctx.context.session?.user.id
|
|
159
|
+
});
|
|
160
|
+
const benefits = await polar2.customerPortal.benefitGrants.list(
|
|
161
|
+
{ customerSession: customerSession.token },
|
|
162
|
+
{
|
|
163
|
+
page: ctx.query?.page,
|
|
164
|
+
limit: ctx.query?.limit
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
return ctx.json(benefits);
|
|
168
|
+
} catch (e) {
|
|
169
|
+
if (e instanceof Error) {
|
|
170
|
+
ctx.context.logger.error(
|
|
171
|
+
`Polar benefits list failed. Error: ${e.message}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
175
|
+
message: "Benefits list failed"
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
),
|
|
180
|
+
subscriptions: createAuthEndpoint(
|
|
181
|
+
"/customer/subscriptions/list",
|
|
182
|
+
{
|
|
183
|
+
method: "GET",
|
|
184
|
+
query: z.object({
|
|
185
|
+
referenceId: z.string().optional(),
|
|
186
|
+
page: z.coerce.number().optional(),
|
|
187
|
+
limit: z.coerce.number().optional(),
|
|
188
|
+
active: z.coerce.boolean().optional()
|
|
189
|
+
}).optional(),
|
|
190
|
+
use: [sessionMiddleware]
|
|
191
|
+
},
|
|
192
|
+
async (ctx) => {
|
|
193
|
+
if (!ctx.context.session.user.id) {
|
|
194
|
+
throw new APIError2("BAD_REQUEST", {
|
|
195
|
+
message: "User not found"
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
if (ctx.query?.referenceId) {
|
|
199
|
+
try {
|
|
200
|
+
const subscriptions = await polar2.subscriptions.list({
|
|
201
|
+
page: ctx.query?.page,
|
|
202
|
+
limit: ctx.query?.limit,
|
|
203
|
+
active: ctx.query?.active,
|
|
204
|
+
metadata: {
|
|
205
|
+
referenceId: ctx.query?.referenceId
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
return ctx.json(subscriptions);
|
|
209
|
+
} catch (e) {
|
|
210
|
+
console.log(e);
|
|
211
|
+
if (e instanceof Error) {
|
|
212
|
+
ctx.context.logger.error(
|
|
213
|
+
`Polar subscriptions list with referenceId failed. Error: ${e.message}`
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
217
|
+
message: "Subscriptions list with referenceId failed"
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
const customerSession = await polar2.customerSessions.create({
|
|
223
|
+
customerExternalId: ctx.context.session?.user.id
|
|
224
|
+
});
|
|
225
|
+
const subscriptions = await polar2.customerPortal.subscriptions.list(
|
|
226
|
+
{ customerSession: customerSession.token },
|
|
227
|
+
{
|
|
228
|
+
page: ctx.query?.page,
|
|
229
|
+
limit: ctx.query?.limit,
|
|
230
|
+
active: ctx.query?.active
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
return ctx.json(subscriptions);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
if (e instanceof Error) {
|
|
236
|
+
ctx.context.logger.error(
|
|
237
|
+
`Polar subscriptions list failed. Error: ${e.message}`
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
241
|
+
message: "Polar subscriptions list failed"
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
),
|
|
246
|
+
orders: createAuthEndpoint(
|
|
247
|
+
"/customer/orders/list",
|
|
248
|
+
{
|
|
249
|
+
method: "GET",
|
|
250
|
+
query: z.object({
|
|
251
|
+
page: z.coerce.number().optional(),
|
|
252
|
+
limit: z.coerce.number().optional(),
|
|
253
|
+
productBillingType: z.enum(["recurring", "one_time"]).optional()
|
|
254
|
+
}).optional(),
|
|
255
|
+
use: [sessionMiddleware]
|
|
256
|
+
},
|
|
257
|
+
async (ctx) => {
|
|
258
|
+
if (!ctx.context.session.user.id) {
|
|
259
|
+
throw new APIError2("BAD_REQUEST", {
|
|
260
|
+
message: "User not found"
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
try {
|
|
264
|
+
const customerSession = await polar2.customerSessions.create({
|
|
265
|
+
customerExternalId: ctx.context.session?.user.id
|
|
266
|
+
});
|
|
267
|
+
const orders = await polar2.customerPortal.orders.list(
|
|
268
|
+
{ customerSession: customerSession.token },
|
|
269
|
+
{
|
|
270
|
+
page: ctx.query?.page,
|
|
271
|
+
limit: ctx.query?.limit,
|
|
272
|
+
productBillingType: ctx.query?.productBillingType
|
|
273
|
+
}
|
|
274
|
+
);
|
|
275
|
+
return ctx.json(orders);
|
|
276
|
+
} catch (e) {
|
|
277
|
+
if (e instanceof Error) {
|
|
278
|
+
ctx.context.logger.error(
|
|
279
|
+
`Polar orders list failed. Error: ${e.message}`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
throw new APIError2("INTERNAL_SERVER_ERROR", {
|
|
283
|
+
message: "Orders list failed"
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
)
|
|
288
|
+
};
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// src/plugins/checkout.ts
|
|
292
|
+
import { APIError as APIError3, getSessionFromCtx } from "better-auth/api";
|
|
293
|
+
import { createAuthEndpoint as createAuthEndpoint2 } from "better-auth/plugins";
|
|
294
|
+
import { z as z2 } from "zod";
|
|
295
|
+
var checkout = (checkoutOptions = {}) => (polar2) => {
|
|
296
|
+
return {
|
|
297
|
+
checkout: createAuthEndpoint2(
|
|
298
|
+
"/checkout",
|
|
299
|
+
{
|
|
300
|
+
method: "POST",
|
|
301
|
+
body: z2.object({
|
|
302
|
+
products: z2.union([z2.array(z2.string()), z2.string()]).optional(),
|
|
303
|
+
slug: z2.string().optional(),
|
|
304
|
+
referenceId: z2.string().optional(),
|
|
305
|
+
customFieldData: z2.record(
|
|
306
|
+
z2.string(),
|
|
307
|
+
z2.union([z2.string(), z2.number(), z2.boolean()])
|
|
308
|
+
).optional(),
|
|
309
|
+
metadata: z2.record(
|
|
310
|
+
z2.string(),
|
|
311
|
+
z2.union([z2.string(), z2.number(), z2.boolean()])
|
|
312
|
+
).optional()
|
|
313
|
+
})
|
|
314
|
+
},
|
|
315
|
+
async (ctx) => {
|
|
316
|
+
const session = await getSessionFromCtx(ctx);
|
|
317
|
+
let productIds = [];
|
|
318
|
+
if (ctx.body.slug) {
|
|
319
|
+
const resolvedProducts = await (typeof checkoutOptions.products === "function" ? checkoutOptions.products() : checkoutOptions.products);
|
|
320
|
+
const productId = resolvedProducts?.find(
|
|
321
|
+
(product) => product.slug === ctx.body.slug
|
|
322
|
+
)?.productId;
|
|
323
|
+
if (!productId) {
|
|
324
|
+
throw new APIError3("BAD_REQUEST", {
|
|
325
|
+
message: "Product not found"
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
productIds = [productId];
|
|
329
|
+
} else {
|
|
330
|
+
productIds = Array.isArray(ctx.body.products) ? ctx.body.products.filter((id) => id !== void 0) : [ctx.body.products].filter((id) => id !== void 0);
|
|
331
|
+
}
|
|
332
|
+
if (checkoutOptions.authenticatedUsersOnly && !session?.user.id) {
|
|
333
|
+
throw new APIError3("UNAUTHORIZED", {
|
|
334
|
+
message: "You must be logged in to checkout"
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
const checkout2 = await polar2.checkouts.create({
|
|
339
|
+
customerExternalId: session?.user.id,
|
|
340
|
+
products: productIds,
|
|
341
|
+
successUrl: checkoutOptions.successUrl ? new URL(
|
|
342
|
+
checkoutOptions.successUrl,
|
|
343
|
+
ctx.request?.url
|
|
344
|
+
).toString() : void 0,
|
|
345
|
+
metadata: ctx.body.referenceId ? {
|
|
346
|
+
referenceId: ctx.body.referenceId,
|
|
347
|
+
...ctx.body.metadata
|
|
348
|
+
} : ctx.body.metadata,
|
|
349
|
+
customFieldData: ctx.body.customFieldData
|
|
350
|
+
});
|
|
351
|
+
return ctx.json({
|
|
352
|
+
url: checkout2.url,
|
|
353
|
+
redirect: true
|
|
354
|
+
});
|
|
355
|
+
} catch (e) {
|
|
356
|
+
if (e instanceof Error) {
|
|
357
|
+
ctx.context.logger.error(
|
|
358
|
+
`Polar checkout creation failed. Error: ${e.message}`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
throw new APIError3("INTERNAL_SERVER_ERROR", {
|
|
362
|
+
message: "Checkout creation failed"
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
)
|
|
367
|
+
};
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
// src/plugins/usage.ts
|
|
371
|
+
import {
|
|
372
|
+
APIError as APIError4,
|
|
373
|
+
createAuthEndpoint as createAuthEndpoint3,
|
|
374
|
+
sessionMiddleware as sessionMiddleware2
|
|
375
|
+
} from "better-auth/api";
|
|
376
|
+
import { z as z3 } from "zod";
|
|
377
|
+
var usage = (_usageOptions) => (polar2) => {
|
|
378
|
+
return {
|
|
379
|
+
meters: createAuthEndpoint3(
|
|
380
|
+
"/usage/meters/list",
|
|
381
|
+
{
|
|
382
|
+
method: "GET",
|
|
383
|
+
use: [sessionMiddleware2],
|
|
384
|
+
query: z3.object({
|
|
385
|
+
page: z3.coerce.number().optional(),
|
|
386
|
+
limit: z3.coerce.number().optional()
|
|
387
|
+
})
|
|
388
|
+
},
|
|
389
|
+
async (ctx) => {
|
|
390
|
+
if (!ctx.context.session.user.id) {
|
|
391
|
+
throw new APIError4("BAD_REQUEST", {
|
|
392
|
+
message: "User not found"
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
try {
|
|
396
|
+
const customerSession = await polar2.customerSessions.create({
|
|
397
|
+
customerExternalId: ctx.context.session.user.id
|
|
398
|
+
});
|
|
399
|
+
const customerMeters = await polar2.customerPortal.customerMeters.list(
|
|
400
|
+
{ customerSession: customerSession.token },
|
|
401
|
+
{
|
|
402
|
+
page: ctx.query?.page,
|
|
403
|
+
limit: ctx.query?.limit
|
|
404
|
+
}
|
|
405
|
+
);
|
|
406
|
+
return ctx.json(customerMeters);
|
|
407
|
+
} catch (e) {
|
|
408
|
+
if (e instanceof Error) {
|
|
409
|
+
ctx.context.logger.error(
|
|
410
|
+
`Polar meters list failed. Error: ${e.message}`
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
throw new APIError4("INTERNAL_SERVER_ERROR", {
|
|
414
|
+
message: "Meters list failed"
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
),
|
|
419
|
+
ingestion: createAuthEndpoint3(
|
|
420
|
+
"/usage/ingest",
|
|
421
|
+
{
|
|
422
|
+
method: "POST",
|
|
423
|
+
body: z3.object({
|
|
424
|
+
event: z3.string(),
|
|
425
|
+
metadata: z3.record(
|
|
426
|
+
z3.string(),
|
|
427
|
+
z3.union([z3.string(), z3.number(), z3.boolean()])
|
|
428
|
+
)
|
|
429
|
+
}),
|
|
430
|
+
use: [sessionMiddleware2]
|
|
431
|
+
},
|
|
432
|
+
async (ctx) => {
|
|
433
|
+
if (!ctx.context.session.user.id) {
|
|
434
|
+
throw new APIError4("BAD_REQUEST", {
|
|
435
|
+
message: "User not found"
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
try {
|
|
439
|
+
const ingestion = await polar2.events.ingest({
|
|
440
|
+
events: [
|
|
441
|
+
{
|
|
442
|
+
name: ctx.body.event,
|
|
443
|
+
metadata: ctx.body.metadata,
|
|
444
|
+
externalCustomerId: ctx.context.session.user.id
|
|
445
|
+
}
|
|
446
|
+
]
|
|
447
|
+
});
|
|
448
|
+
return ctx.json(ingestion);
|
|
449
|
+
} catch (e) {
|
|
450
|
+
if (e instanceof Error) {
|
|
451
|
+
ctx.context.logger.error(
|
|
452
|
+
`Polar ingestion failed. Error: ${e.message}`
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
throw new APIError4("INTERNAL_SERVER_ERROR", {
|
|
456
|
+
message: "Ingestion failed"
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
)
|
|
461
|
+
};
|
|
462
|
+
};
|
|
463
|
+
|
|
464
|
+
// src/plugins/webhooks.ts
|
|
465
|
+
import { validateEvent } from "@polar-sh/sdk/webhooks.js";
|
|
466
|
+
import { APIError as APIError5, createAuthEndpoint as createAuthEndpoint4 } from "better-auth/api";
|
|
467
|
+
var webhooks = (options) => (_polar) => {
|
|
468
|
+
return {
|
|
469
|
+
polarWebhooks: createAuthEndpoint4(
|
|
470
|
+
"/polar/webhooks",
|
|
471
|
+
{
|
|
472
|
+
method: "POST",
|
|
473
|
+
metadata: {
|
|
474
|
+
isAction: false
|
|
475
|
+
},
|
|
476
|
+
cloneRequest: true
|
|
477
|
+
},
|
|
478
|
+
async (ctx) => {
|
|
479
|
+
const {
|
|
480
|
+
secret,
|
|
481
|
+
onPayload,
|
|
482
|
+
onCheckoutCreated,
|
|
483
|
+
onCheckoutUpdated,
|
|
484
|
+
onOrderCreated,
|
|
485
|
+
onOrderPaid,
|
|
486
|
+
onOrderRefunded,
|
|
487
|
+
onRefundCreated,
|
|
488
|
+
onRefundUpdated,
|
|
489
|
+
onSubscriptionCreated,
|
|
490
|
+
onSubscriptionUpdated,
|
|
491
|
+
onSubscriptionActive,
|
|
492
|
+
onSubscriptionCanceled,
|
|
493
|
+
onSubscriptionRevoked,
|
|
494
|
+
onSubscriptionUncanceled,
|
|
495
|
+
onProductCreated,
|
|
496
|
+
onProductUpdated,
|
|
497
|
+
onOrganizationUpdated,
|
|
498
|
+
onBenefitCreated,
|
|
499
|
+
onBenefitUpdated,
|
|
500
|
+
onBenefitGrantCreated,
|
|
501
|
+
onBenefitGrantUpdated,
|
|
502
|
+
onBenefitGrantRevoked,
|
|
503
|
+
onCustomerCreated,
|
|
504
|
+
onCustomerUpdated,
|
|
505
|
+
onCustomerDeleted,
|
|
506
|
+
onCustomerStateChanged
|
|
507
|
+
} = options;
|
|
508
|
+
if (!ctx.request?.body) {
|
|
509
|
+
throw new APIError5("INTERNAL_SERVER_ERROR");
|
|
510
|
+
}
|
|
511
|
+
const buf = await ctx.request.text();
|
|
512
|
+
let event;
|
|
513
|
+
try {
|
|
514
|
+
if (!secret) {
|
|
515
|
+
throw new APIError5("INTERNAL_SERVER_ERROR", {
|
|
516
|
+
message: "Polar webhook secret not found"
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
const headers = {
|
|
520
|
+
"webhook-id": ctx.request.headers.get("webhook-id"),
|
|
521
|
+
"webhook-timestamp": ctx.request.headers.get(
|
|
522
|
+
"webhook-timestamp"
|
|
523
|
+
),
|
|
524
|
+
"webhook-signature": ctx.request.headers.get(
|
|
525
|
+
"webhook-signature"
|
|
526
|
+
)
|
|
527
|
+
};
|
|
528
|
+
event = validateEvent(buf, headers, secret);
|
|
529
|
+
} catch (err) {
|
|
530
|
+
if (err instanceof Error) {
|
|
531
|
+
ctx.context.logger.error(`${err.message}`);
|
|
532
|
+
throw new APIError5("BAD_REQUEST", {
|
|
533
|
+
message: `Webhook Error: ${err.message}`
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
throw new APIError5("BAD_REQUEST", {
|
|
537
|
+
message: `Webhook Error: ${err}`
|
|
538
|
+
});
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
if (onPayload) {
|
|
542
|
+
onPayload(event);
|
|
543
|
+
}
|
|
544
|
+
switch (event.type) {
|
|
545
|
+
case "checkout.created":
|
|
546
|
+
if (onCheckoutCreated) {
|
|
547
|
+
onCheckoutCreated(event);
|
|
548
|
+
}
|
|
549
|
+
break;
|
|
550
|
+
case "checkout.updated":
|
|
551
|
+
if (onCheckoutUpdated) {
|
|
552
|
+
onCheckoutUpdated(event);
|
|
553
|
+
}
|
|
554
|
+
break;
|
|
555
|
+
case "order.created":
|
|
556
|
+
if (onOrderCreated) {
|
|
557
|
+
onOrderCreated(event);
|
|
558
|
+
}
|
|
559
|
+
break;
|
|
560
|
+
case "order.paid":
|
|
561
|
+
if (onOrderPaid) {
|
|
562
|
+
onOrderPaid(event);
|
|
563
|
+
}
|
|
564
|
+
break;
|
|
565
|
+
case "subscription.created":
|
|
566
|
+
if (onSubscriptionCreated) {
|
|
567
|
+
onSubscriptionCreated(event);
|
|
568
|
+
}
|
|
569
|
+
break;
|
|
570
|
+
case "subscription.updated":
|
|
571
|
+
if (onSubscriptionUpdated) {
|
|
572
|
+
onSubscriptionUpdated(event);
|
|
573
|
+
}
|
|
574
|
+
break;
|
|
575
|
+
case "subscription.active":
|
|
576
|
+
if (onSubscriptionActive) {
|
|
577
|
+
onSubscriptionActive(event);
|
|
578
|
+
}
|
|
579
|
+
break;
|
|
580
|
+
case "subscription.canceled":
|
|
581
|
+
if (onSubscriptionCanceled) {
|
|
582
|
+
onSubscriptionCanceled(event);
|
|
583
|
+
}
|
|
584
|
+
break;
|
|
585
|
+
case "subscription.uncanceled":
|
|
586
|
+
if (onSubscriptionUncanceled) {
|
|
587
|
+
onSubscriptionUncanceled(event);
|
|
588
|
+
}
|
|
589
|
+
break;
|
|
590
|
+
case "subscription.revoked":
|
|
591
|
+
if (onSubscriptionRevoked) {
|
|
592
|
+
onSubscriptionRevoked(event);
|
|
593
|
+
}
|
|
594
|
+
break;
|
|
595
|
+
case "product.created":
|
|
596
|
+
if (onProductCreated) {
|
|
597
|
+
onProductCreated(event);
|
|
598
|
+
}
|
|
599
|
+
break;
|
|
600
|
+
case "product.updated":
|
|
601
|
+
if (onProductUpdated) {
|
|
602
|
+
onProductUpdated(event);
|
|
603
|
+
}
|
|
604
|
+
break;
|
|
605
|
+
case "organization.updated":
|
|
606
|
+
if (onOrganizationUpdated) {
|
|
607
|
+
onOrganizationUpdated(event);
|
|
608
|
+
}
|
|
609
|
+
break;
|
|
610
|
+
case "benefit.created":
|
|
611
|
+
if (onBenefitCreated) {
|
|
612
|
+
onBenefitCreated(event);
|
|
613
|
+
}
|
|
614
|
+
break;
|
|
615
|
+
case "benefit.updated":
|
|
616
|
+
if (onBenefitUpdated) {
|
|
617
|
+
onBenefitUpdated(event);
|
|
618
|
+
}
|
|
619
|
+
break;
|
|
620
|
+
case "benefit_grant.created":
|
|
621
|
+
if (onBenefitGrantCreated) {
|
|
622
|
+
onBenefitGrantCreated(event);
|
|
623
|
+
}
|
|
624
|
+
break;
|
|
625
|
+
case "benefit_grant.updated":
|
|
626
|
+
if (onBenefitGrantUpdated) {
|
|
627
|
+
onBenefitGrantUpdated(event);
|
|
628
|
+
}
|
|
629
|
+
break;
|
|
630
|
+
case "benefit_grant.revoked":
|
|
631
|
+
if (onBenefitGrantRevoked) {
|
|
632
|
+
onBenefitGrantRevoked(event);
|
|
633
|
+
}
|
|
634
|
+
break;
|
|
635
|
+
case "order.refunded":
|
|
636
|
+
if (onOrderRefunded) {
|
|
637
|
+
onOrderRefunded(event);
|
|
638
|
+
}
|
|
639
|
+
break;
|
|
640
|
+
case "refund.created":
|
|
641
|
+
if (onRefundCreated) {
|
|
642
|
+
onRefundCreated(event);
|
|
643
|
+
}
|
|
644
|
+
break;
|
|
645
|
+
case "refund.updated":
|
|
646
|
+
if (onRefundUpdated) {
|
|
647
|
+
onRefundUpdated(event);
|
|
648
|
+
}
|
|
649
|
+
break;
|
|
650
|
+
case "customer.created":
|
|
651
|
+
if (onCustomerCreated) {
|
|
652
|
+
onCustomerCreated(event);
|
|
653
|
+
}
|
|
654
|
+
break;
|
|
655
|
+
case "customer.updated":
|
|
656
|
+
if (onCustomerUpdated) {
|
|
657
|
+
onCustomerUpdated(event);
|
|
658
|
+
}
|
|
659
|
+
break;
|
|
660
|
+
case "customer.deleted":
|
|
661
|
+
if (onCustomerDeleted) {
|
|
662
|
+
onCustomerDeleted(event);
|
|
663
|
+
}
|
|
664
|
+
break;
|
|
665
|
+
case "customer.state_changed":
|
|
666
|
+
if (onCustomerStateChanged) {
|
|
667
|
+
onCustomerStateChanged(event);
|
|
668
|
+
}
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
} catch (e) {
|
|
672
|
+
if (e instanceof Error) {
|
|
673
|
+
ctx.context.logger.error(
|
|
674
|
+
`Polar webhook failed. Error: ${e.message}`
|
|
675
|
+
);
|
|
676
|
+
} else {
|
|
677
|
+
ctx.context.logger.error(`Polar webhook failed. Error: ${e}`);
|
|
678
|
+
}
|
|
679
|
+
throw new APIError5("BAD_REQUEST", {
|
|
680
|
+
message: "Webhook error: See server logs for more information."
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
return ctx.json({ received: true });
|
|
684
|
+
}
|
|
685
|
+
)
|
|
686
|
+
};
|
|
687
|
+
};
|
|
688
|
+
|
|
453
689
|
// src/index.ts
|
|
454
690
|
var polar = (options) => {
|
|
691
|
+
const plugins = options.use.map((use) => use(options.client)).reduce((acc, plugin) => {
|
|
692
|
+
Object.assign(acc, plugin);
|
|
693
|
+
return acc;
|
|
694
|
+
}, {});
|
|
455
695
|
return {
|
|
456
696
|
id: "polar",
|
|
457
697
|
endpoints: {
|
|
458
|
-
|
|
459
|
-
polarCheckoutWithSlug: checkoutWithSlug(options),
|
|
460
|
-
polarWebhooks: webhooks(options),
|
|
461
|
-
polarCustomerPortal: customerPortal(options),
|
|
462
|
-
polarCustomerState: customerState(options)
|
|
698
|
+
...plugins
|
|
463
699
|
},
|
|
464
700
|
init() {
|
|
465
701
|
return {
|
|
@@ -480,6 +716,11 @@ var polar = (options) => {
|
|
|
480
716
|
};
|
|
481
717
|
};
|
|
482
718
|
export {
|
|
483
|
-
|
|
719
|
+
checkout,
|
|
720
|
+
polar,
|
|
721
|
+
polarClient,
|
|
722
|
+
portal,
|
|
723
|
+
usage,
|
|
724
|
+
webhooks
|
|
484
725
|
};
|
|
485
726
|
//# sourceMappingURL=index.js.map
|