@porulle/adapter-stripe 0.10.5 → 0.10.8

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAGL,KAAK,cAAc,EAMpB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC;CACtC;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAyI3E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAGL,KAAK,cAAc,EAMpB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC,gBAAgB,CAAC;CACtC;AAqBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAoJ3E"}
package/dist/index.js CHANGED
@@ -1,8 +1,31 @@
1
1
  import Stripe from "stripe";
2
2
  import { Err, Ok, } from "@porulle/core";
3
+ function providerErrorMessage(error, fallback) {
4
+ if (error && typeof error === "object") {
5
+ const candidate = error;
6
+ for (const nested of [candidate.error, candidate.cause, candidate.reason]) {
7
+ if (nested && nested !== error) {
8
+ const message = providerErrorMessage(nested, "");
9
+ if (message)
10
+ return message;
11
+ }
12
+ }
13
+ if (typeof candidate.message === "string" && candidate.message && candidate.message !== "[object ErrorEvent]") {
14
+ return candidate.message;
15
+ }
16
+ }
17
+ if (error instanceof Error && error.message && error.message !== "[object ErrorEvent]") {
18
+ return error.message;
19
+ }
20
+ return fallback;
21
+ }
3
22
  export function stripePayment(options) {
4
23
  const stripe = new Stripe(options.secretKey, {
5
24
  apiVersion: options.apiVersion ?? "2025-08-27.basil",
25
+ // Stripe's fetch transport works in Cloudflare Workers and remains valid in
26
+ // Node/Bun. The default Node HTTP client can surface opaque ErrorEvents in
27
+ // workerd before a request ever reaches Stripe.
28
+ httpClient: Stripe.createFetchHttpClient(globalThis.fetch.bind(globalThis)),
6
29
  });
7
30
  return {
8
31
  providerId: "stripe",
@@ -41,7 +64,7 @@ export function stripePayment(options) {
41
64
  catch (error) {
42
65
  return Err({
43
66
  code: "PAYMENT_INTENT_CREATE_FAILED",
44
- message: error instanceof Error ? error.message : "Stripe payment intent creation failed.",
67
+ message: providerErrorMessage(error, "Stripe payment intent creation failed."),
45
68
  });
46
69
  }
47
70
  },
@@ -57,7 +80,7 @@ export function stripePayment(options) {
57
80
  catch (error) {
58
81
  return Err({
59
82
  code: "PAYMENT_CAPTURE_FAILED",
60
- message: error instanceof Error ? error.message : "Stripe capture failed.",
83
+ message: providerErrorMessage(error, "Stripe capture failed."),
61
84
  });
62
85
  }
63
86
  },
@@ -81,7 +104,7 @@ export function stripePayment(options) {
81
104
  catch (error) {
82
105
  return Err({
83
106
  code: "PAYMENT_REFUND_FAILED",
84
- message: error instanceof Error ? error.message : "Stripe refund failed.",
107
+ message: providerErrorMessage(error, "Stripe refund failed."),
85
108
  });
86
109
  }
87
110
  },
@@ -93,7 +116,7 @@ export function stripePayment(options) {
93
116
  catch (error) {
94
117
  return Err({
95
118
  code: "PAYMENT_CANCEL_FAILED",
96
- message: error instanceof Error ? error.message : "Stripe cancellation failed.",
119
+ message: providerErrorMessage(error, "Stripe cancellation failed."),
97
120
  });
98
121
  }
99
122
  },
@@ -113,7 +136,10 @@ export function stripePayment(options) {
113
136
  });
114
137
  }
115
138
  const body = await request.text();
116
- const event = stripe.webhooks.constructEvent(body, signature, options.webhookSecret);
139
+ // Workers expose Web Crypto through an asynchronous provider. Stripe's
140
+ // synchronous verifier throws under workerd even for a valid signature.
141
+ // The async verifier works across Workers, Node, and Bun.
142
+ const event = await stripe.webhooks.constructEventAsync(body, signature, options.webhookSecret);
117
143
  return Ok({
118
144
  id: event.id,
119
145
  type: event.type,
@@ -123,7 +149,7 @@ export function stripePayment(options) {
123
149
  catch (error) {
124
150
  return Err({
125
151
  code: "WEBHOOK_VERIFICATION_FAILED",
126
- message: error instanceof Error ? error.message : "Stripe webhook verification failed.",
152
+ message: providerErrorMessage(error, "Stripe webhook verification failed."),
127
153
  });
128
154
  }
129
155
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/adapter-stripe",
3
- "version": "0.10.5",
3
+ "version": "0.10.8",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "exports": {
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "stripe": "^18.5.0",
15
- "@porulle/core": "0.10.5"
15
+ "@porulle/core": "0.10.8"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^24.5.2",
package/src/index.ts CHANGED
@@ -16,9 +16,32 @@ export interface StripeAdapterOptions {
16
16
  apiVersion?: Stripe.LatestApiVersion;
17
17
  }
18
18
 
19
+ function providerErrorMessage(error: unknown, fallback: string): string {
20
+ if (error && typeof error === "object") {
21
+ const candidate = error as { error?: unknown; cause?: unknown; reason?: unknown; message?: unknown };
22
+ for (const nested of [candidate.error, candidate.cause, candidate.reason]) {
23
+ if (nested && nested !== error) {
24
+ const message = providerErrorMessage(nested, "");
25
+ if (message) return message;
26
+ }
27
+ }
28
+ if (typeof candidate.message === "string" && candidate.message && candidate.message !== "[object ErrorEvent]") {
29
+ return candidate.message;
30
+ }
31
+ }
32
+ if (error instanceof Error && error.message && error.message !== "[object ErrorEvent]") {
33
+ return error.message;
34
+ }
35
+ return fallback;
36
+ }
37
+
19
38
  export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
20
39
  const stripe = new Stripe(options.secretKey, {
21
40
  apiVersion: options.apiVersion ?? "2025-08-27.basil",
41
+ // Stripe's fetch transport works in Cloudflare Workers and remains valid in
42
+ // Node/Bun. The default Node HTTP client can surface opaque ErrorEvents in
43
+ // workerd before a request ever reaches Stripe.
44
+ httpClient: Stripe.createFetchHttpClient(globalThis.fetch.bind(globalThis)),
22
45
  });
23
46
 
24
47
  return {
@@ -62,7 +85,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
62
85
  } catch (error) {
63
86
  return Err({
64
87
  code: "PAYMENT_INTENT_CREATE_FAILED",
65
- message: error instanceof Error ? error.message : "Stripe payment intent creation failed.",
88
+ message: providerErrorMessage(error, "Stripe payment intent creation failed."),
66
89
  });
67
90
  }
68
91
  },
@@ -78,7 +101,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
78
101
  } catch (error) {
79
102
  return Err({
80
103
  code: "PAYMENT_CAPTURE_FAILED",
81
- message: error instanceof Error ? error.message : "Stripe capture failed.",
104
+ message: providerErrorMessage(error, "Stripe capture failed."),
82
105
  });
83
106
  }
84
107
  },
@@ -103,7 +126,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
103
126
  } catch (error) {
104
127
  return Err({
105
128
  code: "PAYMENT_REFUND_FAILED",
106
- message: error instanceof Error ? error.message : "Stripe refund failed.",
129
+ message: providerErrorMessage(error, "Stripe refund failed."),
107
130
  });
108
131
  }
109
132
  },
@@ -115,7 +138,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
115
138
  } catch (error) {
116
139
  return Err({
117
140
  code: "PAYMENT_CANCEL_FAILED",
118
- message: error instanceof Error ? error.message : "Stripe cancellation failed.",
141
+ message: providerErrorMessage(error, "Stripe cancellation failed."),
119
142
  });
120
143
  }
121
144
  },
@@ -138,7 +161,14 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
138
161
  }
139
162
 
140
163
  const body = await request.text();
141
- const event = stripe.webhooks.constructEvent(body, signature, options.webhookSecret);
164
+ // Workers expose Web Crypto through an asynchronous provider. Stripe's
165
+ // synchronous verifier throws under workerd even for a valid signature.
166
+ // The async verifier works across Workers, Node, and Bun.
167
+ const event = await stripe.webhooks.constructEventAsync(
168
+ body,
169
+ signature,
170
+ options.webhookSecret,
171
+ );
142
172
 
143
173
  return Ok({
144
174
  id: event.id,
@@ -148,7 +178,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
148
178
  } catch (error) {
149
179
  return Err({
150
180
  code: "WEBHOOK_VERIFICATION_FAILED",
151
- message: error instanceof Error ? error.message : "Stripe webhook verification failed.",
181
+ message: providerErrorMessage(error, "Stripe webhook verification failed."),
152
182
  });
153
183
  }
154
184
  },