@digilogiclabs/saas-factory-payments 0.1.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/LICENSE +22 -0
- package/README.md +679 -0
- package/dist/index.d.mts +365 -0
- package/dist/index.d.ts +365 -0
- package/dist/index.js +869 -0
- package/dist/index.mjs +806 -0
- package/dist/native/index.d.mts +266 -0
- package/dist/native/index.d.ts +266 -0
- package/dist/native/index.js +1833 -0
- package/dist/native/index.mjs +1815 -0
- package/dist/server/index.d.mts +122 -0
- package/dist/server/index.d.ts +122 -0
- package/dist/server/index.js +484 -0
- package/dist/server/index.mjs +443 -0
- package/dist/web/index.d.mts +281 -0
- package/dist/web/index.d.ts +281 -0
- package/dist/web/index.js +1651 -0
- package/dist/web/index.mjs +1604 -0
- package/package.json +153 -0
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
// src/server/api/stripe-server.ts
|
|
2
|
+
import Stripe from "stripe";
|
|
3
|
+
|
|
4
|
+
// src/shared/constants.ts
|
|
5
|
+
var STRIPE_API_VERSION = "2023-10-16";
|
|
6
|
+
var WEBHOOK_EVENTS = {
|
|
7
|
+
CUSTOMER_SUBSCRIPTION_CREATED: "customer.subscription.created",
|
|
8
|
+
CUSTOMER_SUBSCRIPTION_UPDATED: "customer.subscription.updated",
|
|
9
|
+
CUSTOMER_SUBSCRIPTION_DELETED: "customer.subscription.deleted",
|
|
10
|
+
INVOICE_PAYMENT_SUCCEEDED: "invoice.payment_succeeded",
|
|
11
|
+
INVOICE_PAYMENT_FAILED: "invoice.payment_failed",
|
|
12
|
+
CHECKOUT_SESSION_COMPLETED: "checkout.session.completed",
|
|
13
|
+
PAYMENT_INTENT_SUCCEEDED: "payment_intent.succeeded",
|
|
14
|
+
PAYMENT_INTENT_PAYMENT_FAILED: "payment_intent.payment_failed"
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/server/api/stripe-server.ts
|
|
18
|
+
var StripeServerAPI = class {
|
|
19
|
+
constructor(secretKey, options) {
|
|
20
|
+
this.stripe = new Stripe(secretKey, {
|
|
21
|
+
apiVersion: options?.apiVersion || STRIPE_API_VERSION,
|
|
22
|
+
typescript: true
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Customer methods
|
|
26
|
+
async createCustomer(params) {
|
|
27
|
+
return this.stripe.customers.create({
|
|
28
|
+
email: params.email,
|
|
29
|
+
name: params.name,
|
|
30
|
+
phone: params.phone,
|
|
31
|
+
metadata: params.metadata
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
async getCustomer(customerId) {
|
|
35
|
+
return this.stripe.customers.retrieve(customerId);
|
|
36
|
+
}
|
|
37
|
+
async updateCustomer(customerId, params) {
|
|
38
|
+
return this.stripe.customers.update(customerId, params);
|
|
39
|
+
}
|
|
40
|
+
async deleteCustomer(customerId) {
|
|
41
|
+
return this.stripe.customers.del(customerId);
|
|
42
|
+
}
|
|
43
|
+
// Subscription methods
|
|
44
|
+
async createSubscription(params) {
|
|
45
|
+
return this.stripe.subscriptions.create({
|
|
46
|
+
customer: params.customerId,
|
|
47
|
+
items: [
|
|
48
|
+
{
|
|
49
|
+
price: params.priceId,
|
|
50
|
+
quantity: params.quantity || 1
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
trial_period_days: params.trialPeriodDays,
|
|
54
|
+
metadata: params.metadata,
|
|
55
|
+
payment_behavior: params.paymentBehavior || "default_incomplete",
|
|
56
|
+
payment_settings: {
|
|
57
|
+
save_default_payment_method: "on_subscription"
|
|
58
|
+
},
|
|
59
|
+
expand: ["latest_invoice.payment_intent"]
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async getSubscription(subscriptionId) {
|
|
63
|
+
return this.stripe.subscriptions.retrieve(subscriptionId, {
|
|
64
|
+
expand: ["default_payment_method"]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
async updateSubscription(subscriptionId, params) {
|
|
68
|
+
const updateData = {};
|
|
69
|
+
if (params.priceId) {
|
|
70
|
+
const subscription = await this.getSubscription(subscriptionId);
|
|
71
|
+
const currentItem = subscription.items.data[0];
|
|
72
|
+
updateData.items = [
|
|
73
|
+
{
|
|
74
|
+
id: currentItem.id,
|
|
75
|
+
price: params.priceId,
|
|
76
|
+
quantity: params.quantity || currentItem.quantity
|
|
77
|
+
}
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
if (params.metadata) {
|
|
81
|
+
updateData.metadata = params.metadata;
|
|
82
|
+
}
|
|
83
|
+
if (typeof params.cancelAtPeriodEnd === "boolean") {
|
|
84
|
+
updateData.cancel_at_period_end = params.cancelAtPeriodEnd;
|
|
85
|
+
}
|
|
86
|
+
return this.stripe.subscriptions.update(subscriptionId, updateData);
|
|
87
|
+
}
|
|
88
|
+
async cancelSubscription(subscriptionId, immediately = false) {
|
|
89
|
+
if (immediately) {
|
|
90
|
+
return this.stripe.subscriptions.cancel(subscriptionId);
|
|
91
|
+
} else {
|
|
92
|
+
return this.stripe.subscriptions.update(subscriptionId, {
|
|
93
|
+
cancel_at_period_end: true
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async reactivateSubscription(subscriptionId) {
|
|
98
|
+
return this.stripe.subscriptions.update(subscriptionId, {
|
|
99
|
+
cancel_at_period_end: false
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async getCustomerSubscriptions(customerId) {
|
|
103
|
+
return this.stripe.subscriptions.list({
|
|
104
|
+
customer: customerId,
|
|
105
|
+
expand: ["data.default_payment_method"]
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// Checkout methods
|
|
109
|
+
async createCheckoutSession(params) {
|
|
110
|
+
const sessionParams = {
|
|
111
|
+
payment_method_types: ["card"],
|
|
112
|
+
line_items: [
|
|
113
|
+
{
|
|
114
|
+
price: params.priceId,
|
|
115
|
+
quantity: 1
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
mode: params.mode || "subscription",
|
|
119
|
+
success_url: params.successUrl,
|
|
120
|
+
cancel_url: params.cancelUrl,
|
|
121
|
+
allow_promotion_codes: params.allowPromotionCodes,
|
|
122
|
+
billing_address_collection: params.billingAddressCollection,
|
|
123
|
+
metadata: params.metadata
|
|
124
|
+
};
|
|
125
|
+
if (params.customerId) {
|
|
126
|
+
sessionParams.customer = params.customerId;
|
|
127
|
+
} else if (params.customerEmail) {
|
|
128
|
+
sessionParams.customer_email = params.customerEmail;
|
|
129
|
+
}
|
|
130
|
+
if (params.mode === "subscription" && params.trialPeriodDays) {
|
|
131
|
+
sessionParams.subscription_data = {
|
|
132
|
+
trial_period_days: params.trialPeriodDays
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
return this.stripe.checkout.sessions.create(sessionParams);
|
|
136
|
+
}
|
|
137
|
+
// Payment Intent methods
|
|
138
|
+
async createPaymentIntent(params) {
|
|
139
|
+
return this.stripe.paymentIntents.create({
|
|
140
|
+
amount: params.amount,
|
|
141
|
+
currency: params.currency,
|
|
142
|
+
customer: params.customerId,
|
|
143
|
+
payment_method_types: params.paymentMethodTypes || ["card"],
|
|
144
|
+
metadata: params.metadata,
|
|
145
|
+
description: params.description
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
async confirmPaymentIntent(paymentIntentId, params) {
|
|
149
|
+
return this.stripe.paymentIntents.confirm(paymentIntentId, {
|
|
150
|
+
payment_method: params?.paymentMethod
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Setup Intent methods (for subscriptions without immediate payment)
|
|
154
|
+
async createSetupIntent(params) {
|
|
155
|
+
return this.stripe.setupIntents.create({
|
|
156
|
+
customer: params.customerId,
|
|
157
|
+
payment_method_types: params.paymentMethodTypes || ["card"],
|
|
158
|
+
metadata: params.metadata,
|
|
159
|
+
usage: "off_session"
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Customer Portal methods
|
|
163
|
+
async createPortalSession(params) {
|
|
164
|
+
return this.stripe.billingPortal.sessions.create({
|
|
165
|
+
customer: params.customerId,
|
|
166
|
+
return_url: params.returnUrl
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
// Payment Method methods
|
|
170
|
+
async getCustomerPaymentMethods(customerId, type = "card") {
|
|
171
|
+
return this.stripe.paymentMethods.list({
|
|
172
|
+
customer: customerId,
|
|
173
|
+
type
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
async attachPaymentMethod(paymentMethodId, customerId) {
|
|
177
|
+
return this.stripe.paymentMethods.attach(paymentMethodId, {
|
|
178
|
+
customer: customerId
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async detachPaymentMethod(paymentMethodId) {
|
|
182
|
+
return this.stripe.paymentMethods.detach(paymentMethodId);
|
|
183
|
+
}
|
|
184
|
+
async setDefaultPaymentMethod(customerId, paymentMethodId) {
|
|
185
|
+
return this.stripe.customers.update(customerId, {
|
|
186
|
+
invoice_settings: {
|
|
187
|
+
default_payment_method: paymentMethodId
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
// Invoice methods
|
|
192
|
+
async getCustomerInvoices(customerId, limit = 10) {
|
|
193
|
+
return this.stripe.invoices.list({
|
|
194
|
+
customer: customerId,
|
|
195
|
+
limit
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async getInvoice(invoiceId) {
|
|
199
|
+
return this.stripe.invoices.retrieve(invoiceId);
|
|
200
|
+
}
|
|
201
|
+
// Webhook methods
|
|
202
|
+
constructWebhookEvent(payload, signature, webhookSecret) {
|
|
203
|
+
return this.stripe.webhooks.constructEvent(
|
|
204
|
+
payload,
|
|
205
|
+
signature,
|
|
206
|
+
webhookSecret
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
// Price and Product methods
|
|
210
|
+
async getPrice(priceId) {
|
|
211
|
+
return this.stripe.prices.retrieve(priceId, {
|
|
212
|
+
expand: ["product"]
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
async getPrices(params) {
|
|
216
|
+
return this.stripe.prices.list({
|
|
217
|
+
active: params?.active,
|
|
218
|
+
limit: params?.limit || 10,
|
|
219
|
+
product: params?.product,
|
|
220
|
+
expand: ["data.product"]
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
async getProduct(productId) {
|
|
224
|
+
return this.stripe.products.retrieve(productId);
|
|
225
|
+
}
|
|
226
|
+
// Ephemeral Key methods (for mobile)
|
|
227
|
+
async createEphemeralKey(customerId, apiVersion) {
|
|
228
|
+
return this.stripe.ephemeralKeys.create(
|
|
229
|
+
{ customer: customerId },
|
|
230
|
+
{ apiVersion }
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// src/server/webhooks/stripe.ts
|
|
236
|
+
var StripeWebhookHandler = class {
|
|
237
|
+
constructor(secretKey, handlers = {}) {
|
|
238
|
+
this.stripeAPI = new StripeServerAPI(secretKey);
|
|
239
|
+
this.handlers = handlers;
|
|
240
|
+
}
|
|
241
|
+
async handleWebhook(payload, signature, webhookSecret) {
|
|
242
|
+
try {
|
|
243
|
+
const event = this.stripeAPI.constructWebhookEvent(
|
|
244
|
+
payload,
|
|
245
|
+
signature,
|
|
246
|
+
webhookSecret
|
|
247
|
+
);
|
|
248
|
+
console.log(`Received webhook event: ${event.type}`);
|
|
249
|
+
await this.processEvent(event);
|
|
250
|
+
return { success: true };
|
|
251
|
+
} catch (error) {
|
|
252
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown webhook error";
|
|
253
|
+
console.error("Webhook error:", errorMessage);
|
|
254
|
+
return { success: false, error: errorMessage };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
async processEvent(event) {
|
|
258
|
+
switch (event.type) {
|
|
259
|
+
case WEBHOOK_EVENTS.CUSTOMER_SUBSCRIPTION_CREATED:
|
|
260
|
+
await this.handleSubscriptionCreated(
|
|
261
|
+
event.data.object
|
|
262
|
+
);
|
|
263
|
+
break;
|
|
264
|
+
case WEBHOOK_EVENTS.CUSTOMER_SUBSCRIPTION_UPDATED:
|
|
265
|
+
await this.handleSubscriptionUpdated(
|
|
266
|
+
event.data.object
|
|
267
|
+
);
|
|
268
|
+
break;
|
|
269
|
+
case WEBHOOK_EVENTS.CUSTOMER_SUBSCRIPTION_DELETED:
|
|
270
|
+
await this.handleSubscriptionDeleted(
|
|
271
|
+
event.data.object
|
|
272
|
+
);
|
|
273
|
+
break;
|
|
274
|
+
case WEBHOOK_EVENTS.INVOICE_PAYMENT_SUCCEEDED:
|
|
275
|
+
await this.handleInvoicePaymentSucceeded(
|
|
276
|
+
event.data.object
|
|
277
|
+
);
|
|
278
|
+
break;
|
|
279
|
+
case WEBHOOK_EVENTS.INVOICE_PAYMENT_FAILED:
|
|
280
|
+
await this.handleInvoicePaymentFailed(
|
|
281
|
+
event.data.object
|
|
282
|
+
);
|
|
283
|
+
break;
|
|
284
|
+
case WEBHOOK_EVENTS.CHECKOUT_SESSION_COMPLETED:
|
|
285
|
+
await this.handleCheckoutSessionCompleted(
|
|
286
|
+
event.data.object
|
|
287
|
+
);
|
|
288
|
+
break;
|
|
289
|
+
case WEBHOOK_EVENTS.PAYMENT_INTENT_SUCCEEDED:
|
|
290
|
+
await this.handlePaymentIntentSucceeded(
|
|
291
|
+
event.data.object
|
|
292
|
+
);
|
|
293
|
+
break;
|
|
294
|
+
case WEBHOOK_EVENTS.PAYMENT_INTENT_PAYMENT_FAILED:
|
|
295
|
+
await this.handlePaymentIntentFailed(
|
|
296
|
+
event.data.object
|
|
297
|
+
);
|
|
298
|
+
break;
|
|
299
|
+
default:
|
|
300
|
+
console.log(`Unhandled event type: ${event.type}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async handleSubscriptionCreated(subscription) {
|
|
304
|
+
console.log(`Subscription created: ${subscription.id}`);
|
|
305
|
+
if (this.handlers.onCustomerSubscriptionCreated) {
|
|
306
|
+
await this.handlers.onCustomerSubscriptionCreated(subscription);
|
|
307
|
+
}
|
|
308
|
+
console.log(
|
|
309
|
+
`Customer ${subscription.customer} subscribed to ${subscription.items.data[0]?.price.id}`
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
async handleSubscriptionUpdated(subscription) {
|
|
313
|
+
console.log(`Subscription updated: ${subscription.id}`);
|
|
314
|
+
if (this.handlers.onCustomerSubscriptionUpdated) {
|
|
315
|
+
await this.handlers.onCustomerSubscriptionUpdated(subscription);
|
|
316
|
+
}
|
|
317
|
+
console.log(
|
|
318
|
+
`Subscription ${subscription.id} status: ${subscription.status}`
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
async handleSubscriptionDeleted(subscription) {
|
|
322
|
+
console.log(`Subscription deleted: ${subscription.id}`);
|
|
323
|
+
if (this.handlers.onCustomerSubscriptionDeleted) {
|
|
324
|
+
await this.handlers.onCustomerSubscriptionDeleted(subscription);
|
|
325
|
+
}
|
|
326
|
+
console.log(
|
|
327
|
+
`Customer ${subscription.customer} cancelled subscription ${subscription.id}`
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
async handleInvoicePaymentSucceeded(invoice) {
|
|
331
|
+
console.log(`Invoice payment succeeded: ${invoice.id}`);
|
|
332
|
+
if (this.handlers.onInvoicePaymentSucceeded) {
|
|
333
|
+
await this.handlers.onInvoicePaymentSucceeded(invoice);
|
|
334
|
+
}
|
|
335
|
+
if (invoice.subscription) {
|
|
336
|
+
console.log(`Payment succeeded for subscription ${invoice.subscription}`);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
async handleInvoicePaymentFailed(invoice) {
|
|
340
|
+
console.log(`Invoice payment failed: ${invoice.id}`);
|
|
341
|
+
if (this.handlers.onInvoicePaymentFailed) {
|
|
342
|
+
await this.handlers.onInvoicePaymentFailed(invoice);
|
|
343
|
+
}
|
|
344
|
+
if (invoice.subscription) {
|
|
345
|
+
console.log(`Payment failed for subscription ${invoice.subscription}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
async handleCheckoutSessionCompleted(session) {
|
|
349
|
+
console.log(`Checkout session completed: ${session.id}`);
|
|
350
|
+
if (this.handlers.onCheckoutSessionCompleted) {
|
|
351
|
+
await this.handlers.onCheckoutSessionCompleted(session);
|
|
352
|
+
}
|
|
353
|
+
if (session.mode === "subscription") {
|
|
354
|
+
console.log(
|
|
355
|
+
`Subscription checkout completed for customer ${session.customer}`
|
|
356
|
+
);
|
|
357
|
+
} else {
|
|
358
|
+
console.log(
|
|
359
|
+
`Payment checkout completed for customer ${session.customer}`
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async handlePaymentIntentSucceeded(paymentIntent) {
|
|
364
|
+
console.log(`Payment intent succeeded: ${paymentIntent.id}`);
|
|
365
|
+
if (this.handlers.onPaymentIntentSucceeded) {
|
|
366
|
+
await this.handlers.onPaymentIntentSucceeded(paymentIntent);
|
|
367
|
+
}
|
|
368
|
+
console.log(
|
|
369
|
+
`Payment of ${paymentIntent.amount} ${paymentIntent.currency} succeeded`
|
|
370
|
+
);
|
|
371
|
+
}
|
|
372
|
+
async handlePaymentIntentFailed(paymentIntent) {
|
|
373
|
+
console.log(`Payment intent failed: ${paymentIntent.id}`);
|
|
374
|
+
if (this.handlers.onPaymentIntentPaymentFailed) {
|
|
375
|
+
await this.handlers.onPaymentIntentPaymentFailed(paymentIntent);
|
|
376
|
+
}
|
|
377
|
+
console.log(
|
|
378
|
+
`Payment of ${paymentIntent.amount} ${paymentIntent.currency} failed`
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
var createStripeWebhookHandler = (secretKey, handlers = {}) => {
|
|
383
|
+
return new StripeWebhookHandler(secretKey, handlers);
|
|
384
|
+
};
|
|
385
|
+
var createStripeWebhookMiddleware = (secretKey, webhookSecret, handlers = {}) => {
|
|
386
|
+
const webhookHandler = new StripeWebhookHandler(secretKey, handlers);
|
|
387
|
+
return async (req, res, next) => {
|
|
388
|
+
try {
|
|
389
|
+
const signature = req.headers["stripe-signature"];
|
|
390
|
+
if (!signature) {
|
|
391
|
+
return res.status(400).json({ error: "Missing stripe-signature header" });
|
|
392
|
+
}
|
|
393
|
+
const result = await webhookHandler.handleWebhook(
|
|
394
|
+
req.body,
|
|
395
|
+
signature,
|
|
396
|
+
webhookSecret
|
|
397
|
+
);
|
|
398
|
+
if (result.success) {
|
|
399
|
+
res.status(200).json({ received: true });
|
|
400
|
+
} else {
|
|
401
|
+
res.status(400).json({ error: result.error });
|
|
402
|
+
}
|
|
403
|
+
} catch (error) {
|
|
404
|
+
console.error("Webhook middleware error:", error);
|
|
405
|
+
res.status(500).json({ error: "Internal server error" });
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
};
|
|
409
|
+
var createNextJSWebhookHandler = (secretKey, webhookSecret, handlers = {}) => {
|
|
410
|
+
const webhookHandler = new StripeWebhookHandler(secretKey, handlers);
|
|
411
|
+
return async (req, res) => {
|
|
412
|
+
if (req.method !== "POST") {
|
|
413
|
+
res.setHeader("Allow", "POST");
|
|
414
|
+
return res.status(405).json({ error: "Method not allowed" });
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
const signature = req.headers["stripe-signature"];
|
|
418
|
+
if (!signature) {
|
|
419
|
+
return res.status(400).json({ error: "Missing stripe-signature header" });
|
|
420
|
+
}
|
|
421
|
+
const result = await webhookHandler.handleWebhook(
|
|
422
|
+
req.body,
|
|
423
|
+
signature,
|
|
424
|
+
webhookSecret
|
|
425
|
+
);
|
|
426
|
+
if (result.success) {
|
|
427
|
+
res.status(200).json({ received: true });
|
|
428
|
+
} else {
|
|
429
|
+
res.status(400).json({ error: result.error });
|
|
430
|
+
}
|
|
431
|
+
} catch (error) {
|
|
432
|
+
console.error("Webhook handler error:", error);
|
|
433
|
+
res.status(500).json({ error: "Internal server error" });
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
};
|
|
437
|
+
export {
|
|
438
|
+
StripeServerAPI,
|
|
439
|
+
StripeWebhookHandler,
|
|
440
|
+
createNextJSWebhookHandler,
|
|
441
|
+
createStripeWebhookHandler,
|
|
442
|
+
createStripeWebhookMiddleware
|
|
443
|
+
};
|