stripe-no-webhooks 0.0.2 → 0.0.4

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.
@@ -0,0 +1,18 @@
1
+ type PriceInterval = "month" | "year" | "week" | "one_time";
2
+ type Price = {
3
+ id?: string;
4
+ amount: number;
5
+ currency: string;
6
+ interval: PriceInterval;
7
+ };
8
+ type Plan = {
9
+ id?: string;
10
+ name: string;
11
+ description?: string;
12
+ price: Price[];
13
+ };
14
+ type BillingConfig = {
15
+ plans?: Plan[];
16
+ };
17
+
18
+ export type { BillingConfig as B, PriceInterval as P, Price as a, Plan as b };
@@ -0,0 +1,18 @@
1
+ type PriceInterval = "month" | "year" | "week" | "one_time";
2
+ type Price = {
3
+ id?: string;
4
+ amount: number;
5
+ currency: string;
6
+ interval: PriceInterval;
7
+ };
8
+ type Plan = {
9
+ id?: string;
10
+ name: string;
11
+ description?: string;
12
+ price: Price[];
13
+ };
14
+ type BillingConfig = {
15
+ plans?: Plan[];
16
+ };
17
+
18
+ export type { BillingConfig as B, PriceInterval as P, Price as a, Plan as b };
@@ -0,0 +1,79 @@
1
+ import { P as PriceInterval } from './BillingConfig-BYrAQ7Wx.mjs';
2
+
3
+ interface CheckoutOptions {
4
+ /**
5
+ * Plan name to checkout (as defined in your billing config)
6
+ */
7
+ planName?: string;
8
+ /**
9
+ * Plan ID to checkout (as defined in your billing config)
10
+ */
11
+ planId?: string;
12
+ /**
13
+ * Billing interval (month, year, etc.)
14
+ */
15
+ interval?: PriceInterval;
16
+ /**
17
+ * Direct Stripe price ID (bypasses billing config lookup)
18
+ */
19
+ priceId?: string;
20
+ /**
21
+ * Quantity of the item (defaults to 1)
22
+ */
23
+ quantity?: number;
24
+ /**
25
+ * Customer email for prefilling checkout
26
+ */
27
+ customerEmail?: string;
28
+ /**
29
+ * Override success URL for this checkout
30
+ */
31
+ successUrl?: string;
32
+ /**
33
+ * Override cancel URL for this checkout
34
+ */
35
+ cancelUrl?: string;
36
+ /**
37
+ * Additional metadata to attach to the session
38
+ */
39
+ metadata?: Record<string, string>;
40
+ }
41
+ interface CheckoutClientConfig {
42
+ /**
43
+ * API endpoint for checkout (defaults to /api/stripe/checkout)
44
+ */
45
+ checkoutEndpoint?: string;
46
+ }
47
+ /**
48
+ * Creates a checkout client for initiating Stripe checkouts from the frontend.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { createCheckoutClient } from "stripe-no-webhooks/client";
53
+ *
54
+ * const { checkout } = createCheckoutClient();
55
+ *
56
+ * // In your component:
57
+ * <button onClick={() => checkout({ planName: "pro", interval: "month" })}>
58
+ * Subscribe to Pro
59
+ * </button>
60
+ * ```
61
+ */
62
+ declare function createCheckoutClient(config?: CheckoutClientConfig): {
63
+ checkout: (options: CheckoutOptions) => Promise<void>;
64
+ };
65
+ /**
66
+ * Default checkout client instance using /api/stripe/checkout endpoint.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { checkout } from "stripe-no-webhooks/client";
71
+ *
72
+ * <button onClick={() => checkout({ planName: "pro", interval: "month" })}>
73
+ * Subscribe to Pro
74
+ * </button>
75
+ * ```
76
+ */
77
+ declare const checkout: (options: CheckoutOptions) => Promise<void>;
78
+
79
+ export { type CheckoutClientConfig, type CheckoutOptions, checkout, createCheckoutClient };
@@ -0,0 +1,79 @@
1
+ import { P as PriceInterval } from './BillingConfig-BYrAQ7Wx.js';
2
+
3
+ interface CheckoutOptions {
4
+ /**
5
+ * Plan name to checkout (as defined in your billing config)
6
+ */
7
+ planName?: string;
8
+ /**
9
+ * Plan ID to checkout (as defined in your billing config)
10
+ */
11
+ planId?: string;
12
+ /**
13
+ * Billing interval (month, year, etc.)
14
+ */
15
+ interval?: PriceInterval;
16
+ /**
17
+ * Direct Stripe price ID (bypasses billing config lookup)
18
+ */
19
+ priceId?: string;
20
+ /**
21
+ * Quantity of the item (defaults to 1)
22
+ */
23
+ quantity?: number;
24
+ /**
25
+ * Customer email for prefilling checkout
26
+ */
27
+ customerEmail?: string;
28
+ /**
29
+ * Override success URL for this checkout
30
+ */
31
+ successUrl?: string;
32
+ /**
33
+ * Override cancel URL for this checkout
34
+ */
35
+ cancelUrl?: string;
36
+ /**
37
+ * Additional metadata to attach to the session
38
+ */
39
+ metadata?: Record<string, string>;
40
+ }
41
+ interface CheckoutClientConfig {
42
+ /**
43
+ * API endpoint for checkout (defaults to /api/stripe/checkout)
44
+ */
45
+ checkoutEndpoint?: string;
46
+ }
47
+ /**
48
+ * Creates a checkout client for initiating Stripe checkouts from the frontend.
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * import { createCheckoutClient } from "stripe-no-webhooks/client";
53
+ *
54
+ * const { checkout } = createCheckoutClient();
55
+ *
56
+ * // In your component:
57
+ * <button onClick={() => checkout({ planName: "pro", interval: "month" })}>
58
+ * Subscribe to Pro
59
+ * </button>
60
+ * ```
61
+ */
62
+ declare function createCheckoutClient(config?: CheckoutClientConfig): {
63
+ checkout: (options: CheckoutOptions) => Promise<void>;
64
+ };
65
+ /**
66
+ * Default checkout client instance using /api/stripe/checkout endpoint.
67
+ *
68
+ * @example
69
+ * ```ts
70
+ * import { checkout } from "stripe-no-webhooks/client";
71
+ *
72
+ * <button onClick={() => checkout({ planName: "pro", interval: "month" })}>
73
+ * Subscribe to Pro
74
+ * </button>
75
+ * ```
76
+ */
77
+ declare const checkout: (options: CheckoutOptions) => Promise<void>;
78
+
79
+ export { type CheckoutClientConfig, type CheckoutOptions, checkout, createCheckoutClient };
package/dist/client.js ADDED
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/client.ts
21
+ var client_exports = {};
22
+ __export(client_exports, {
23
+ checkout: () => checkout,
24
+ createCheckoutClient: () => createCheckoutClient
25
+ });
26
+ module.exports = __toCommonJS(client_exports);
27
+ function createCheckoutClient(config = {}) {
28
+ const { checkoutEndpoint = "/api/stripe/checkout" } = config;
29
+ async function checkout2(options) {
30
+ const response = await fetch(checkoutEndpoint, {
31
+ method: "POST",
32
+ headers: {
33
+ "Content-Type": "application/json",
34
+ Accept: "application/json"
35
+ },
36
+ body: JSON.stringify(options)
37
+ });
38
+ if (!response.ok) {
39
+ const error = await response.json().catch(() => ({}));
40
+ throw new Error(error.error || `Checkout failed: ${response.status}`);
41
+ }
42
+ const data = await response.json();
43
+ if (!data.url) {
44
+ throw new Error("No checkout URL returned");
45
+ }
46
+ window.location.href = data.url;
47
+ }
48
+ return { checkout: checkout2 };
49
+ }
50
+ var { checkout } = createCheckoutClient();
51
+ // Annotate the CommonJS export names for ESM import in node:
52
+ 0 && (module.exports = {
53
+ checkout,
54
+ createCheckoutClient
55
+ });
@@ -0,0 +1,29 @@
1
+ // src/client.ts
2
+ function createCheckoutClient(config = {}) {
3
+ const { checkoutEndpoint = "/api/stripe/checkout" } = config;
4
+ async function checkout2(options) {
5
+ const response = await fetch(checkoutEndpoint, {
6
+ method: "POST",
7
+ headers: {
8
+ "Content-Type": "application/json",
9
+ Accept: "application/json"
10
+ },
11
+ body: JSON.stringify(options)
12
+ });
13
+ if (!response.ok) {
14
+ const error = await response.json().catch(() => ({}));
15
+ throw new Error(error.error || `Checkout failed: ${response.status}`);
16
+ }
17
+ const data = await response.json();
18
+ if (!data.url) {
19
+ throw new Error("No checkout URL returned");
20
+ }
21
+ window.location.href = data.url;
22
+ }
23
+ return { checkout: checkout2 };
24
+ }
25
+ var { checkout } = createCheckoutClient();
26
+ export {
27
+ checkout,
28
+ createCheckoutClient
29
+ };
package/dist/index.d.mts CHANGED
@@ -1,4 +1,6 @@
1
1
  import Stripe from 'stripe';
2
+ import { B as BillingConfig, P as PriceInterval } from './BillingConfig-BYrAQ7Wx.mjs';
3
+ export { b as Plan, a as Price } from './BillingConfig-BYrAQ7Wx.mjs';
2
4
 
3
5
  interface StripeWebhookCallbacks {
4
6
  /**
@@ -10,28 +12,89 @@ interface StripeWebhookCallbacks {
10
12
  */
11
13
  onSubscriptionCancelled?: (subscription: Stripe.Subscription) => void | Promise<void>;
12
14
  }
13
- interface StripeWebhookConfig {
14
- /**
15
- * PostgreSQL connection string for the Stripe sync database
16
- */
17
- databaseUrl: string;
15
+ interface StripeHandlerConfig {
18
16
  /**
19
17
  * Stripe secret key (sk_test_... or sk_live_...)
18
+ * Falls back to STRIPE_SECRET_KEY environment variable
20
19
  */
21
- stripeSecretKey: string;
20
+ stripeSecretKey?: string;
22
21
  /**
23
22
  * Stripe webhook signing secret (whsec_...)
23
+ * Falls back to STRIPE_WEBHOOK_SECRET environment variable
24
24
  */
25
- stripeWebhookSecret: string;
25
+ stripeWebhookSecret?: string;
26
+ /**
27
+ * PostgreSQL connection string for the Stripe sync database
28
+ * Falls back to DATABASE_URL environment variable
29
+ */
30
+ databaseUrl?: string;
26
31
  /**
27
32
  * Database schema name (defaults to 'stripe')
28
33
  */
29
34
  schema?: string;
35
+ /**
36
+ * Billing configuration containing plans and prices
37
+ */
38
+ billingConfig?: BillingConfig;
39
+ /**
40
+ * Default success URL (can be overridden per request)
41
+ */
42
+ successUrl?: string;
43
+ /**
44
+ * Default cancel URL (can be overridden per request)
45
+ */
46
+ cancelUrl?: string;
47
+ /**
48
+ * Enable automatic tax calculation (defaults to true)
49
+ */
50
+ automaticTax?: boolean;
30
51
  /**
31
52
  * Callbacks for subscription events
32
53
  */
33
54
  callbacks?: StripeWebhookCallbacks;
34
55
  }
35
- declare function createStripeWebhookHandler(config: StripeWebhookConfig): (request: Request) => Promise<Response>;
56
+ interface CheckoutRequestBody {
57
+ /**
58
+ * Plan name to look up in billingConfig (use with interval)
59
+ */
60
+ planName?: string;
61
+ /**
62
+ * Plan ID to look up in billingConfig (use with interval)
63
+ */
64
+ planId?: string;
65
+ /**
66
+ * Price interval for plan lookup
67
+ */
68
+ interval?: PriceInterval;
69
+ /**
70
+ * Direct Stripe price ID (bypasses billingConfig lookup)
71
+ */
72
+ priceId?: string;
73
+ /**
74
+ * Override the success URL for this checkout
75
+ */
76
+ successUrl?: string;
77
+ /**
78
+ * Override the cancel URL for this checkout
79
+ */
80
+ cancelUrl?: string;
81
+ /**
82
+ * Quantity of the item (defaults to 1)
83
+ */
84
+ quantity?: number;
85
+ /**
86
+ * Customer email for prefilling checkout
87
+ */
88
+ customerEmail?: string;
89
+ /**
90
+ * Existing Stripe customer ID
91
+ */
92
+ customerId?: string;
93
+ /**
94
+ * Additional metadata to attach to the session
95
+ */
96
+ metadata?: Record<string, string>;
97
+ }
98
+ declare function createStripeHandler(config?: StripeHandlerConfig): (request: Request) => Promise<Response>;
36
99
 
37
- export { type StripeWebhookCallbacks, type StripeWebhookConfig, createStripeWebhookHandler };
100
+ export { BillingConfig, type CheckoutRequestBody, PriceInterval, type StripeHandlerConfig, type StripeWebhookCallbacks, createStripeHandler };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import Stripe from 'stripe';
2
+ import { B as BillingConfig, P as PriceInterval } from './BillingConfig-BYrAQ7Wx.js';
3
+ export { b as Plan, a as Price } from './BillingConfig-BYrAQ7Wx.js';
2
4
 
3
5
  interface StripeWebhookCallbacks {
4
6
  /**
@@ -10,28 +12,89 @@ interface StripeWebhookCallbacks {
10
12
  */
11
13
  onSubscriptionCancelled?: (subscription: Stripe.Subscription) => void | Promise<void>;
12
14
  }
13
- interface StripeWebhookConfig {
14
- /**
15
- * PostgreSQL connection string for the Stripe sync database
16
- */
17
- databaseUrl: string;
15
+ interface StripeHandlerConfig {
18
16
  /**
19
17
  * Stripe secret key (sk_test_... or sk_live_...)
18
+ * Falls back to STRIPE_SECRET_KEY environment variable
20
19
  */
21
- stripeSecretKey: string;
20
+ stripeSecretKey?: string;
22
21
  /**
23
22
  * Stripe webhook signing secret (whsec_...)
23
+ * Falls back to STRIPE_WEBHOOK_SECRET environment variable
24
24
  */
25
- stripeWebhookSecret: string;
25
+ stripeWebhookSecret?: string;
26
+ /**
27
+ * PostgreSQL connection string for the Stripe sync database
28
+ * Falls back to DATABASE_URL environment variable
29
+ */
30
+ databaseUrl?: string;
26
31
  /**
27
32
  * Database schema name (defaults to 'stripe')
28
33
  */
29
34
  schema?: string;
35
+ /**
36
+ * Billing configuration containing plans and prices
37
+ */
38
+ billingConfig?: BillingConfig;
39
+ /**
40
+ * Default success URL (can be overridden per request)
41
+ */
42
+ successUrl?: string;
43
+ /**
44
+ * Default cancel URL (can be overridden per request)
45
+ */
46
+ cancelUrl?: string;
47
+ /**
48
+ * Enable automatic tax calculation (defaults to true)
49
+ */
50
+ automaticTax?: boolean;
30
51
  /**
31
52
  * Callbacks for subscription events
32
53
  */
33
54
  callbacks?: StripeWebhookCallbacks;
34
55
  }
35
- declare function createStripeWebhookHandler(config: StripeWebhookConfig): (request: Request) => Promise<Response>;
56
+ interface CheckoutRequestBody {
57
+ /**
58
+ * Plan name to look up in billingConfig (use with interval)
59
+ */
60
+ planName?: string;
61
+ /**
62
+ * Plan ID to look up in billingConfig (use with interval)
63
+ */
64
+ planId?: string;
65
+ /**
66
+ * Price interval for plan lookup
67
+ */
68
+ interval?: PriceInterval;
69
+ /**
70
+ * Direct Stripe price ID (bypasses billingConfig lookup)
71
+ */
72
+ priceId?: string;
73
+ /**
74
+ * Override the success URL for this checkout
75
+ */
76
+ successUrl?: string;
77
+ /**
78
+ * Override the cancel URL for this checkout
79
+ */
80
+ cancelUrl?: string;
81
+ /**
82
+ * Quantity of the item (defaults to 1)
83
+ */
84
+ quantity?: number;
85
+ /**
86
+ * Customer email for prefilling checkout
87
+ */
88
+ customerEmail?: string;
89
+ /**
90
+ * Existing Stripe customer ID
91
+ */
92
+ customerId?: string;
93
+ /**
94
+ * Additional metadata to attach to the session
95
+ */
96
+ metadata?: Record<string, string>;
97
+ }
98
+ declare function createStripeHandler(config?: StripeHandlerConfig): (request: Request) => Promise<Response>;
36
99
 
37
- export { type StripeWebhookCallbacks, type StripeWebhookConfig, createStripeWebhookHandler };
100
+ export { BillingConfig, type CheckoutRequestBody, PriceInterval, type StripeHandlerConfig, type StripeWebhookCallbacks, createStripeHandler };
package/dist/index.js CHANGED
@@ -30,31 +30,131 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- createStripeWebhookHandler: () => createStripeWebhookHandler
33
+ createStripeHandler: () => createStripeHandler
34
34
  });
35
35
  module.exports = __toCommonJS(index_exports);
36
36
 
37
37
  // src/handler.ts
38
38
  var import_stripe_sync_engine = require("@supabase/stripe-sync-engine");
39
39
  var import_stripe = __toESM(require("stripe"));
40
- function createStripeWebhookHandler(config) {
40
+ function createStripeHandler(config = {}) {
41
41
  const {
42
- databaseUrl,
43
- stripeSecretKey,
44
- stripeWebhookSecret,
42
+ stripeSecretKey = process.env.STRIPE_SECRET_KEY,
43
+ stripeWebhookSecret = process.env.STRIPE_WEBHOOK_SECRET,
44
+ databaseUrl = process.env.DATABASE_URL,
45
45
  schema = "stripe",
46
+ billingConfig,
47
+ successUrl: defaultSuccessUrl,
48
+ cancelUrl: defaultCancelUrl,
49
+ automaticTax = true,
46
50
  callbacks
47
51
  } = config;
48
- const sync = new import_stripe_sync_engine.StripeSync({
52
+ const stripe = new import_stripe.default(stripeSecretKey);
53
+ const sync = databaseUrl ? new import_stripe_sync_engine.StripeSync({
49
54
  poolConfig: {
50
55
  connectionString: databaseUrl
51
56
  },
52
57
  schema,
53
58
  stripeSecretKey,
54
59
  stripeWebhookSecret
55
- });
56
- const stripe = new import_stripe.default(stripeSecretKey);
57
- return async function handler(request) {
60
+ }) : null;
61
+ function resolvePriceId(body) {
62
+ if (body.priceId) {
63
+ return body.priceId;
64
+ }
65
+ if (!body.interval) {
66
+ throw new Error("interval is required when using planName or planId");
67
+ }
68
+ if (!billingConfig?.plans) {
69
+ throw new Error(
70
+ "billingConfig with plans is required when using planName or planId"
71
+ );
72
+ }
73
+ const plan = body.planName ? billingConfig.plans.find((p) => p.name === body.planName) : body.planId ? billingConfig.plans.find((p) => p.id === body.planId) : null;
74
+ if (!plan) {
75
+ const identifier = body.planName || body.planId;
76
+ throw new Error(`Plan not found: ${identifier}`);
77
+ }
78
+ const price = plan.price.find((p) => p.interval === body.interval);
79
+ if (!price) {
80
+ throw new Error(
81
+ `Price with interval "${body.interval}" not found for plan "${plan.name}"`
82
+ );
83
+ }
84
+ if (!price.id) {
85
+ throw new Error(
86
+ `Price ID not set for plan "${plan.name}" with interval "${body.interval}". Run stripe-sync to sync price IDs.`
87
+ );
88
+ }
89
+ return price.id;
90
+ }
91
+ async function getPriceMode(priceId) {
92
+ const price = await stripe.prices.retrieve(priceId);
93
+ return price.type === "recurring" ? "subscription" : "payment";
94
+ }
95
+ async function handleCheckout(request) {
96
+ try {
97
+ const body = await request.json();
98
+ if (!body.priceId && !body.planName && !body.planId) {
99
+ return new Response(
100
+ JSON.stringify({
101
+ error: "Provide either priceId, planName+interval, or planId+interval"
102
+ }),
103
+ { status: 400, headers: { "Content-Type": "application/json" } }
104
+ );
105
+ }
106
+ const origin = request.headers.get("origin") || "";
107
+ const successUrl = body.successUrl || defaultSuccessUrl || `${origin}/success?session_id={CHECKOUT_SESSION_ID}`;
108
+ const cancelUrl = body.cancelUrl || defaultCancelUrl || `${origin}/`;
109
+ const priceId = resolvePriceId(body);
110
+ const mode = await getPriceMode(priceId);
111
+ const sessionParams = {
112
+ line_items: [
113
+ {
114
+ price: priceId,
115
+ quantity: body.quantity ?? 1
116
+ }
117
+ ],
118
+ mode,
119
+ success_url: successUrl,
120
+ cancel_url: cancelUrl,
121
+ automatic_tax: { enabled: automaticTax }
122
+ };
123
+ if (body.customerEmail) {
124
+ sessionParams.customer_email = body.customerEmail;
125
+ }
126
+ if (body.customerId) {
127
+ sessionParams.customer = body.customerId;
128
+ }
129
+ if (body.metadata) {
130
+ sessionParams.metadata = body.metadata;
131
+ }
132
+ const session = await stripe.checkout.sessions.create(sessionParams);
133
+ if (!session.url) {
134
+ return new Response(
135
+ JSON.stringify({ error: "Failed to create checkout session" }),
136
+ { status: 500, headers: { "Content-Type": "application/json" } }
137
+ );
138
+ }
139
+ const acceptHeader = request.headers.get("accept") || "";
140
+ if (acceptHeader.includes("application/json")) {
141
+ return new Response(JSON.stringify({ url: session.url }), {
142
+ status: 200,
143
+ headers: { "Content-Type": "application/json" }
144
+ });
145
+ }
146
+ return Response.redirect(session.url, 303);
147
+ } catch (err) {
148
+ console.error("Checkout error:", err);
149
+ const message = err instanceof Error ? err.message : "Unknown error";
150
+ const status = err && typeof err === "object" && "statusCode" in err ? err.statusCode : 500;
151
+ return new Response(JSON.stringify({ error: message }), {
152
+ status,
153
+ headers: { "Content-Type": "application/json" }
154
+ });
155
+ }
156
+ }
157
+ async function handleWebhook(request) {
58
158
  try {
59
159
  const body = await request.text();
60
160
  const signature = request.headers.get("stripe-signature");
@@ -75,7 +175,9 @@ function createStripeWebhookHandler(config) {
75
175
  { status: 400 }
76
176
  );
77
177
  }
78
- await sync.processWebhook(body, signature);
178
+ if (sync) {
179
+ await sync.processWebhook(body, signature);
180
+ }
79
181
  if (callbacks) {
80
182
  await handleCallbacks(event, callbacks);
81
183
  }
@@ -88,6 +190,30 @@ function createStripeWebhookHandler(config) {
88
190
  const message = error instanceof Error ? error.message : "Internal server error";
89
191
  return new Response(message, { status: 500 });
90
192
  }
193
+ }
194
+ return async function handler(request) {
195
+ const url = new URL(request.url);
196
+ const pathSegments = url.pathname.split("/").filter(Boolean);
197
+ const action = pathSegments[pathSegments.length - 1];
198
+ if (request.method !== "POST") {
199
+ return new Response(JSON.stringify({ error: "Method not allowed" }), {
200
+ status: 405,
201
+ headers: { "Content-Type": "application/json" }
202
+ });
203
+ }
204
+ switch (action) {
205
+ case "checkout":
206
+ return handleCheckout(request);
207
+ case "webhook":
208
+ return handleWebhook(request);
209
+ default:
210
+ return new Response(
211
+ JSON.stringify({
212
+ error: `Unknown action: ${action}. Supported: checkout, webhook`
213
+ }),
214
+ { status: 404, headers: { "Content-Type": "application/json" } }
215
+ );
216
+ }
91
217
  };
92
218
  }
93
219
  async function handleCallbacks(event, callbacks) {
@@ -114,5 +240,5 @@ async function handleCallbacks(event, callbacks) {
114
240
  }
115
241
  // Annotate the CommonJS export names for ESM import in node:
116
242
  0 && (module.exports = {
117
- createStripeWebhookHandler
243
+ createStripeHandler
118
244
  });