@zendfi/sdk 0.1.1 → 0.2.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/index.js CHANGED
@@ -37,6 +37,7 @@ __export(index_exports, {
37
37
  ValidationError: () => ValidationError,
38
38
  ZendFiClient: () => ZendFiClient,
39
39
  ZendFiError: () => ZendFiError,
40
+ processWebhook: () => processWebhook,
40
41
  verifyExpressWebhook: () => verifyExpressWebhook,
41
42
  verifyNextWebhook: () => verifyNextWebhook,
42
43
  verifyWebhookSignature: () => verifyWebhookSignature,
@@ -322,14 +323,15 @@ var ZendFiClient = class {
322
323
  };
323
324
  }
324
325
  /**
325
- * List all payment links
326
+ * List all payment links for the authenticated merchant
326
327
  */
327
328
  async listPaymentLinks() {
328
- return [];
329
+ const response = await this.request("GET", "/api/v1/payment-links");
330
+ return response.map((link) => ({
331
+ ...link,
332
+ url: link.hosted_page_url
333
+ }));
329
334
  }
330
- // ===================================================================
331
- // INSTALLMENT PLANS - Pay over time
332
- // ===================================================================
333
335
  /**
334
336
  * Create an installment plan
335
337
  * Split a purchase into multiple scheduled payments
@@ -380,9 +382,6 @@ var ZendFiClient = class {
380
382
  `/api/v1/installment-plans/${planId}/cancel`
381
383
  );
382
384
  }
383
- // ===================================================================
384
- // ESCROW - Secure fund holding
385
- // ===================================================================
386
385
  /**
387
386
  * Create an escrow transaction
388
387
  * Hold funds until conditions are met
@@ -432,9 +431,6 @@ var ZendFiClient = class {
432
431
  async disputeEscrow(escrowId, request) {
433
432
  return this.request("POST", `/api/v1/escrows/${escrowId}/dispute`, request);
434
433
  }
435
- // ===================================================================
436
- // INVOICES - Professional billing
437
- // ===================================================================
438
434
  /**
439
435
  * Create an invoice
440
436
  */
@@ -486,15 +482,34 @@ var ZendFiClient = class {
486
482
  if (!request.payload || !request.signature || !request.secret) {
487
483
  return false;
488
484
  }
489
- const parsedPayload = JSON.parse(request.payload);
490
- if (!parsedPayload.event || !parsedPayload.merchant_id || !parsedPayload.timestamp) {
485
+ let payloadString;
486
+ let parsedPayload = null;
487
+ if (typeof request.payload === "string") {
488
+ payloadString = request.payload;
489
+ try {
490
+ parsedPayload = JSON.parse(payloadString);
491
+ } catch (e) {
492
+ return false;
493
+ }
494
+ } else if (typeof request.payload === "object") {
495
+ parsedPayload = request.payload;
496
+ try {
497
+ payloadString = JSON.stringify(request.payload);
498
+ } catch (e) {
499
+ return false;
500
+ }
501
+ } else {
502
+ return false;
503
+ }
504
+ if (!parsedPayload || !parsedPayload.event || !parsedPayload.merchant_id || !parsedPayload.timestamp) {
491
505
  return false;
492
506
  }
493
- const computedSignature = this.computeHmacSignature(request.payload, request.secret);
507
+ const computedSignature = this.computeHmacSignature(payloadString, request.secret);
494
508
  return this.timingSafeEqual(request.signature, computedSignature);
495
- } catch (error) {
509
+ } catch (err) {
510
+ const error = err;
496
511
  if (this.config.environment === "development") {
497
- console.error("Webhook verification error:", error);
512
+ console.error("Webhook verification error:", error?.message || String(error));
498
513
  }
499
514
  return false;
500
515
  }
@@ -664,6 +679,147 @@ function verifyWebhookSignature(payload, signature, secret) {
664
679
  secret
665
680
  });
666
681
  }
682
+
683
+ // src/webhook-handler.ts
684
+ var import_crypto2 = require("crypto");
685
+ var processedWebhooks = /* @__PURE__ */ new Set();
686
+ var defaultIsProcessed = async (webhookId) => {
687
+ return processedWebhooks.has(webhookId);
688
+ };
689
+ var defaultOnProcessed = async (webhookId) => {
690
+ processedWebhooks.add(webhookId);
691
+ if (processedWebhooks.size > 1e4) {
692
+ const iterator = processedWebhooks.values();
693
+ for (let i = 0; i < 1e3; i++) {
694
+ const { value } = iterator.next();
695
+ if (value) processedWebhooks.delete(value);
696
+ }
697
+ }
698
+ };
699
+ function generateWebhookId(payload) {
700
+ return `${payload.merchant_id}:${payload.event}:${payload.timestamp}`;
701
+ }
702
+ async function processPayload(payload, handlers, config) {
703
+ try {
704
+ const webhookId = generateWebhookId(payload);
705
+ const isProcessed = config.isProcessed || config.checkDuplicate || defaultIsProcessed;
706
+ const onProcessed = config.onProcessed || config.markProcessed || defaultOnProcessed;
707
+ const dedupEnabled = !!(config.enableDeduplication || config.isProcessed || config.checkDuplicate);
708
+ if (dedupEnabled && await isProcessed(webhookId)) {
709
+ return {
710
+ success: false,
711
+ processed: false,
712
+ event: payload.event,
713
+ error: "Duplicate webhook",
714
+ statusCode: 409
715
+ };
716
+ }
717
+ const handler = handlers[payload.event];
718
+ if (!handler) {
719
+ return {
720
+ success: true,
721
+ processed: false,
722
+ event: payload.event,
723
+ statusCode: 200
724
+ };
725
+ }
726
+ await handler(payload.data, payload);
727
+ await onProcessed(webhookId);
728
+ return {
729
+ success: true,
730
+ processed: true,
731
+ event: payload.event
732
+ };
733
+ } catch (error) {
734
+ const err = error;
735
+ if (config?.onError) {
736
+ await config.onError(err, error?.event);
737
+ }
738
+ return {
739
+ success: false,
740
+ processed: false,
741
+ error: err.message,
742
+ event: error?.event,
743
+ statusCode: 500
744
+ };
745
+ }
746
+ }
747
+ async function processWebhook(a, b, c) {
748
+ if (a && typeof a === "object" && a.event && b && c) {
749
+ return processPayload(a, b, c);
750
+ }
751
+ const opts = a;
752
+ if (!opts || !opts.signature && !opts.body && !opts.handlers) {
753
+ return {
754
+ success: false,
755
+ processed: false,
756
+ error: "Invalid arguments to processWebhook",
757
+ statusCode: 400
758
+ };
759
+ }
760
+ const signature = opts.signature;
761
+ const body = opts.body;
762
+ const handlers = opts.handlers || {};
763
+ const cfg = opts.config || {};
764
+ const secret = cfg.webhookSecret || cfg.secret;
765
+ if (!secret) {
766
+ return {
767
+ success: false,
768
+ processed: false,
769
+ error: "Webhook secret not provided",
770
+ statusCode: 400
771
+ };
772
+ }
773
+ if (!signature || !body) {
774
+ return {
775
+ success: false,
776
+ processed: false,
777
+ error: "Missing signature or body",
778
+ statusCode: 400
779
+ };
780
+ }
781
+ try {
782
+ const sig = typeof signature === "string" && signature.startsWith("sha256=") ? signature.slice("sha256=".length) : String(signature);
783
+ const hmac = (0, import_crypto2.createHmac)("sha256", secret).update(body, "utf8").digest("hex");
784
+ let ok = false;
785
+ try {
786
+ const sigBuf = Buffer.from(sig, "hex");
787
+ const hmacBuf = Buffer.from(hmac, "hex");
788
+ if (sigBuf.length === hmacBuf.length) {
789
+ ok = (0, import_crypto2.timingSafeEqual)(sigBuf, hmacBuf);
790
+ }
791
+ } catch (e) {
792
+ ok = (0, import_crypto2.timingSafeEqual)(Buffer.from(String(sig), "utf8"), Buffer.from(hmac, "utf8"));
793
+ }
794
+ if (!ok) {
795
+ return {
796
+ success: false,
797
+ processed: false,
798
+ error: "Invalid signature",
799
+ statusCode: 401
800
+ };
801
+ }
802
+ const payload = JSON.parse(body);
803
+ const fullConfig = {
804
+ secret,
805
+ isProcessed: cfg.isProcessed,
806
+ onProcessed: cfg.onProcessed,
807
+ onError: cfg.onError,
808
+ // Forward compatibility for alternate names and flags
809
+ enableDeduplication: cfg.enableDeduplication,
810
+ checkDuplicate: cfg.checkDuplicate,
811
+ markProcessed: cfg.markProcessed
812
+ };
813
+ return await processPayload(payload, handlers, fullConfig);
814
+ } catch (err) {
815
+ return {
816
+ success: false,
817
+ processed: false,
818
+ error: err.message,
819
+ statusCode: 500
820
+ };
821
+ }
822
+ }
667
823
  // Annotate the CommonJS export names for ESM import in node:
668
824
  0 && (module.exports = {
669
825
  AuthenticationError,
@@ -673,6 +829,7 @@ function verifyWebhookSignature(payload, signature, secret) {
673
829
  ValidationError,
674
830
  ZendFiClient,
675
831
  ZendFiError,
832
+ processWebhook,
676
833
  verifyExpressWebhook,
677
834
  verifyNextWebhook,
678
835
  verifyWebhookSignature,
package/dist/index.mjs CHANGED
@@ -1,9 +1,7 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
1
+ import {
2
+ __require,
3
+ processWebhook
4
+ } from "./chunk-YFOBPGQE.mjs";
7
5
 
8
6
  // src/client.ts
9
7
  import fetch from "cross-fetch";
@@ -283,14 +281,15 @@ var ZendFiClient = class {
283
281
  };
284
282
  }
285
283
  /**
286
- * List all payment links
284
+ * List all payment links for the authenticated merchant
287
285
  */
288
286
  async listPaymentLinks() {
289
- return [];
287
+ const response = await this.request("GET", "/api/v1/payment-links");
288
+ return response.map((link) => ({
289
+ ...link,
290
+ url: link.hosted_page_url
291
+ }));
290
292
  }
291
- // ===================================================================
292
- // INSTALLMENT PLANS - Pay over time
293
- // ===================================================================
294
293
  /**
295
294
  * Create an installment plan
296
295
  * Split a purchase into multiple scheduled payments
@@ -341,9 +340,6 @@ var ZendFiClient = class {
341
340
  `/api/v1/installment-plans/${planId}/cancel`
342
341
  );
343
342
  }
344
- // ===================================================================
345
- // ESCROW - Secure fund holding
346
- // ===================================================================
347
343
  /**
348
344
  * Create an escrow transaction
349
345
  * Hold funds until conditions are met
@@ -393,9 +389,6 @@ var ZendFiClient = class {
393
389
  async disputeEscrow(escrowId, request) {
394
390
  return this.request("POST", `/api/v1/escrows/${escrowId}/dispute`, request);
395
391
  }
396
- // ===================================================================
397
- // INVOICES - Professional billing
398
- // ===================================================================
399
392
  /**
400
393
  * Create an invoice
401
394
  */
@@ -447,15 +440,34 @@ var ZendFiClient = class {
447
440
  if (!request.payload || !request.signature || !request.secret) {
448
441
  return false;
449
442
  }
450
- const parsedPayload = JSON.parse(request.payload);
451
- if (!parsedPayload.event || !parsedPayload.merchant_id || !parsedPayload.timestamp) {
443
+ let payloadString;
444
+ let parsedPayload = null;
445
+ if (typeof request.payload === "string") {
446
+ payloadString = request.payload;
447
+ try {
448
+ parsedPayload = JSON.parse(payloadString);
449
+ } catch (e) {
450
+ return false;
451
+ }
452
+ } else if (typeof request.payload === "object") {
453
+ parsedPayload = request.payload;
454
+ try {
455
+ payloadString = JSON.stringify(request.payload);
456
+ } catch (e) {
457
+ return false;
458
+ }
459
+ } else {
452
460
  return false;
453
461
  }
454
- const computedSignature = this.computeHmacSignature(request.payload, request.secret);
462
+ if (!parsedPayload || !parsedPayload.event || !parsedPayload.merchant_id || !parsedPayload.timestamp) {
463
+ return false;
464
+ }
465
+ const computedSignature = this.computeHmacSignature(payloadString, request.secret);
455
466
  return this.timingSafeEqual(request.signature, computedSignature);
456
- } catch (error) {
467
+ } catch (err) {
468
+ const error = err;
457
469
  if (this.config.environment === "development") {
458
- console.error("Webhook verification error:", error);
470
+ console.error("Webhook verification error:", error?.message || String(error));
459
471
  }
460
472
  return false;
461
473
  }
@@ -633,6 +645,7 @@ export {
633
645
  ValidationError,
634
646
  ZendFiClient,
635
647
  ZendFiError,
648
+ processWebhook,
636
649
  verifyExpressWebhook,
637
650
  verifyNextWebhook,
638
651
  verifyWebhookSignature,
@@ -0,0 +1,37 @@
1
+ import { W as WebhookHandlerConfig, a as WebhookHandlers } from './webhook-handler-BIze3Qop.mjs';
2
+
3
+ /**
4
+ * Next.js Webhook Handler for App Router
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * // app/api/webhooks/zendfi/route.ts
9
+ * import { createNextWebhookHandler } from '@zendfi/sdk/nextjs';
10
+ *
11
+ * export const POST = createNextWebhookHandler({
12
+ * secret: process.env.ZENDFI_WEBHOOK_SECRET!,
13
+ * handlers: {
14
+ * 'payment.confirmed': async (payment) => {
15
+ * await db.orders.update({
16
+ * where: { id: payment.metadata.orderId },
17
+ * data: { status: 'paid' },
18
+ * });
19
+ * },
20
+ * 'payment.failed': async (payment) => {
21
+ * await sendFailureEmail(payment);
22
+ * },
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+
28
+ type NextRequest = any;
29
+ interface NextWebhookHandlerConfig extends WebhookHandlerConfig {
30
+ handlers: WebhookHandlers;
31
+ }
32
+ /**
33
+ * Create a Next.js App Router webhook handler
34
+ */
35
+ declare function createNextWebhookHandler(config: NextWebhookHandlerConfig): (request: NextRequest) => Promise<Response>;
36
+
37
+ export { type NextWebhookHandlerConfig, createNextWebhookHandler };
@@ -0,0 +1,37 @@
1
+ import { W as WebhookHandlerConfig, a as WebhookHandlers } from './webhook-handler-BIze3Qop.js';
2
+
3
+ /**
4
+ * Next.js Webhook Handler for App Router
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * // app/api/webhooks/zendfi/route.ts
9
+ * import { createNextWebhookHandler } from '@zendfi/sdk/nextjs';
10
+ *
11
+ * export const POST = createNextWebhookHandler({
12
+ * secret: process.env.ZENDFI_WEBHOOK_SECRET!,
13
+ * handlers: {
14
+ * 'payment.confirmed': async (payment) => {
15
+ * await db.orders.update({
16
+ * where: { id: payment.metadata.orderId },
17
+ * data: { status: 'paid' },
18
+ * });
19
+ * },
20
+ * 'payment.failed': async (payment) => {
21
+ * await sendFailureEmail(payment);
22
+ * },
23
+ * },
24
+ * });
25
+ * ```
26
+ */
27
+
28
+ type NextRequest = any;
29
+ interface NextWebhookHandlerConfig extends WebhookHandlerConfig {
30
+ handlers: WebhookHandlers;
31
+ }
32
+ /**
33
+ * Create a Next.js App Router webhook handler
34
+ */
35
+ declare function createNextWebhookHandler(config: NextWebhookHandlerConfig): (request: NextRequest) => Promise<Response>;
36
+
37
+ export { type NextWebhookHandlerConfig, createNextWebhookHandler };
package/dist/nextjs.js ADDED
@@ -0,0 +1,227 @@
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/nextjs.ts
21
+ var nextjs_exports = {};
22
+ __export(nextjs_exports, {
23
+ createNextWebhookHandler: () => createNextWebhookHandler
24
+ });
25
+ module.exports = __toCommonJS(nextjs_exports);
26
+ var import_crypto2 = require("crypto");
27
+
28
+ // src/webhook-handler.ts
29
+ var import_crypto = require("crypto");
30
+ var processedWebhooks = /* @__PURE__ */ new Set();
31
+ var defaultIsProcessed = async (webhookId) => {
32
+ return processedWebhooks.has(webhookId);
33
+ };
34
+ var defaultOnProcessed = async (webhookId) => {
35
+ processedWebhooks.add(webhookId);
36
+ if (processedWebhooks.size > 1e4) {
37
+ const iterator = processedWebhooks.values();
38
+ for (let i = 0; i < 1e3; i++) {
39
+ const { value } = iterator.next();
40
+ if (value) processedWebhooks.delete(value);
41
+ }
42
+ }
43
+ };
44
+ function generateWebhookId(payload) {
45
+ return `${payload.merchant_id}:${payload.event}:${payload.timestamp}`;
46
+ }
47
+ async function processPayload(payload, handlers, config) {
48
+ try {
49
+ const webhookId = generateWebhookId(payload);
50
+ const isProcessed = config.isProcessed || config.checkDuplicate || defaultIsProcessed;
51
+ const onProcessed = config.onProcessed || config.markProcessed || defaultOnProcessed;
52
+ const dedupEnabled = !!(config.enableDeduplication || config.isProcessed || config.checkDuplicate);
53
+ if (dedupEnabled && await isProcessed(webhookId)) {
54
+ return {
55
+ success: false,
56
+ processed: false,
57
+ event: payload.event,
58
+ error: "Duplicate webhook",
59
+ statusCode: 409
60
+ };
61
+ }
62
+ const handler = handlers[payload.event];
63
+ if (!handler) {
64
+ return {
65
+ success: true,
66
+ processed: false,
67
+ event: payload.event,
68
+ statusCode: 200
69
+ };
70
+ }
71
+ await handler(payload.data, payload);
72
+ await onProcessed(webhookId);
73
+ return {
74
+ success: true,
75
+ processed: true,
76
+ event: payload.event
77
+ };
78
+ } catch (error) {
79
+ const err = error;
80
+ if (config?.onError) {
81
+ await config.onError(err, error?.event);
82
+ }
83
+ return {
84
+ success: false,
85
+ processed: false,
86
+ error: err.message,
87
+ event: error?.event,
88
+ statusCode: 500
89
+ };
90
+ }
91
+ }
92
+ async function processWebhook(a, b, c) {
93
+ if (a && typeof a === "object" && a.event && b && c) {
94
+ return processPayload(a, b, c);
95
+ }
96
+ const opts = a;
97
+ if (!opts || !opts.signature && !opts.body && !opts.handlers) {
98
+ return {
99
+ success: false,
100
+ processed: false,
101
+ error: "Invalid arguments to processWebhook",
102
+ statusCode: 400
103
+ };
104
+ }
105
+ const signature = opts.signature;
106
+ const body = opts.body;
107
+ const handlers = opts.handlers || {};
108
+ const cfg = opts.config || {};
109
+ const secret = cfg.webhookSecret || cfg.secret;
110
+ if (!secret) {
111
+ return {
112
+ success: false,
113
+ processed: false,
114
+ error: "Webhook secret not provided",
115
+ statusCode: 400
116
+ };
117
+ }
118
+ if (!signature || !body) {
119
+ return {
120
+ success: false,
121
+ processed: false,
122
+ error: "Missing signature or body",
123
+ statusCode: 400
124
+ };
125
+ }
126
+ try {
127
+ const sig = typeof signature === "string" && signature.startsWith("sha256=") ? signature.slice("sha256=".length) : String(signature);
128
+ const hmac = (0, import_crypto.createHmac)("sha256", secret).update(body, "utf8").digest("hex");
129
+ let ok = false;
130
+ try {
131
+ const sigBuf = Buffer.from(sig, "hex");
132
+ const hmacBuf = Buffer.from(hmac, "hex");
133
+ if (sigBuf.length === hmacBuf.length) {
134
+ ok = (0, import_crypto.timingSafeEqual)(sigBuf, hmacBuf);
135
+ }
136
+ } catch (e) {
137
+ ok = (0, import_crypto.timingSafeEqual)(Buffer.from(String(sig), "utf8"), Buffer.from(hmac, "utf8"));
138
+ }
139
+ if (!ok) {
140
+ return {
141
+ success: false,
142
+ processed: false,
143
+ error: "Invalid signature",
144
+ statusCode: 401
145
+ };
146
+ }
147
+ const payload = JSON.parse(body);
148
+ const fullConfig = {
149
+ secret,
150
+ isProcessed: cfg.isProcessed,
151
+ onProcessed: cfg.onProcessed,
152
+ onError: cfg.onError,
153
+ // Forward compatibility for alternate names and flags
154
+ enableDeduplication: cfg.enableDeduplication,
155
+ checkDuplicate: cfg.checkDuplicate,
156
+ markProcessed: cfg.markProcessed
157
+ };
158
+ return await processPayload(payload, handlers, fullConfig);
159
+ } catch (err) {
160
+ return {
161
+ success: false,
162
+ processed: false,
163
+ error: err.message,
164
+ statusCode: 500
165
+ };
166
+ }
167
+ }
168
+
169
+ // src/nextjs.ts
170
+ function createNextWebhookHandler(config) {
171
+ return async (request) => {
172
+ try {
173
+ const signature = request.headers.get("x-zendfi-signature");
174
+ if (!signature) {
175
+ return new Response(
176
+ JSON.stringify({ error: "Missing signature" }),
177
+ { status: 401, headers: { "Content-Type": "application/json" } }
178
+ );
179
+ }
180
+ const body = await request.text();
181
+ const computedSignature = (0, import_crypto2.createHmac)("sha256", config.secret).update(body, "utf8").digest("hex");
182
+ const sigBuffer = Buffer.from(signature, "utf8");
183
+ const compBuffer = Buffer.from(computedSignature, "utf8");
184
+ if (sigBuffer.length !== compBuffer.length || !(0, import_crypto2.timingSafeEqual)(sigBuffer, compBuffer)) {
185
+ return new Response(
186
+ JSON.stringify({ error: "Invalid signature" }),
187
+ { status: 401, headers: { "Content-Type": "application/json" } }
188
+ );
189
+ }
190
+ let payload;
191
+ try {
192
+ payload = JSON.parse(body);
193
+ } catch {
194
+ return new Response(
195
+ JSON.stringify({ error: "Invalid JSON" }),
196
+ { status: 400, headers: { "Content-Type": "application/json" } }
197
+ );
198
+ }
199
+ const result = await processWebhook(payload, config.handlers, config);
200
+ if (!result.success) {
201
+ return new Response(
202
+ JSON.stringify({ error: result.error || "Webhook processing failed" }),
203
+ { status: 500, headers: { "Content-Type": "application/json" } }
204
+ );
205
+ }
206
+ return new Response(
207
+ JSON.stringify({
208
+ received: true,
209
+ processed: result.processed,
210
+ event: result.event
211
+ }),
212
+ { status: 200, headers: { "Content-Type": "application/json" } }
213
+ );
214
+ } catch (error) {
215
+ const err = error;
216
+ console.error("Webhook handler error:", err);
217
+ return new Response(
218
+ JSON.stringify({ error: "Internal server error" }),
219
+ { status: 500, headers: { "Content-Type": "application/json" } }
220
+ );
221
+ }
222
+ };
223
+ }
224
+ // Annotate the CommonJS export names for ESM import in node:
225
+ 0 && (module.exports = {
226
+ createNextWebhookHandler
227
+ });