@porulle/adapter-stripe 0.10.4 → 0.10.6

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,CA4H3E"}
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,CA6I3E"}
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",
@@ -18,8 +41,18 @@ export function stripePayment(options) {
18
41
  },
19
42
  automatic_payment_methods: {
20
43
  enabled: true,
44
+ allow_redirects: "never",
21
45
  },
22
- });
46
+ // Porulle's synchronous checkout reserves inventory and captures
47
+ // after order creation. With a token, confirm up to the
48
+ // requires_capture boundary; never send raw card data here.
49
+ capture_method: "manual",
50
+ ...(params.paymentMethodToken
51
+ ? { payment_method: params.paymentMethodToken, confirm: true }
52
+ : {}),
53
+ }, params.idempotencyKey
54
+ ? { idempotencyKey: params.idempotencyKey }
55
+ : undefined);
23
56
  return Ok({
24
57
  id: intent.id,
25
58
  status: intent.status,
@@ -31,7 +64,7 @@ export function stripePayment(options) {
31
64
  catch (error) {
32
65
  return Err({
33
66
  code: "PAYMENT_INTENT_CREATE_FAILED",
34
- message: error instanceof Error ? error.message : "Stripe payment intent creation failed.",
67
+ message: providerErrorMessage(error, "Stripe payment intent creation failed."),
35
68
  });
36
69
  }
37
70
  },
@@ -47,7 +80,7 @@ export function stripePayment(options) {
47
80
  catch (error) {
48
81
  return Err({
49
82
  code: "PAYMENT_CAPTURE_FAILED",
50
- message: error instanceof Error ? error.message : "Stripe capture failed.",
83
+ message: providerErrorMessage(error, "Stripe capture failed."),
51
84
  });
52
85
  }
53
86
  },
@@ -71,7 +104,7 @@ export function stripePayment(options) {
71
104
  catch (error) {
72
105
  return Err({
73
106
  code: "PAYMENT_REFUND_FAILED",
74
- message: error instanceof Error ? error.message : "Stripe refund failed.",
107
+ message: providerErrorMessage(error, "Stripe refund failed."),
75
108
  });
76
109
  }
77
110
  },
@@ -83,7 +116,7 @@ export function stripePayment(options) {
83
116
  catch (error) {
84
117
  return Err({
85
118
  code: "PAYMENT_CANCEL_FAILED",
86
- message: error instanceof Error ? error.message : "Stripe cancellation failed.",
119
+ message: providerErrorMessage(error, "Stripe cancellation failed."),
87
120
  });
88
121
  }
89
122
  },
@@ -113,7 +146,7 @@ export function stripePayment(options) {
113
146
  catch (error) {
114
147
  return Err({
115
148
  code: "WEBHOOK_VERIFICATION_FAILED",
116
- message: error instanceof Error ? error.message : "Stripe webhook verification failed.",
149
+ message: providerErrorMessage(error, "Stripe webhook verification failed."),
117
150
  });
118
151
  }
119
152
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@porulle/adapter-stripe",
3
- "version": "0.10.4",
3
+ "version": "0.10.6",
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.4"
15
+ "@porulle/core": "0.10.6"
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 {
@@ -26,18 +49,31 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
26
49
 
27
50
  async createPaymentIntent(params): Promise<Result<PaymentIntent>> {
28
51
  try {
29
- const intent = await stripe.paymentIntents.create({
30
- amount: params.amount,
31
- currency: params.currency.toLowerCase(),
32
- metadata: {
33
- orderId: params.orderId,
34
- customerId: params.customerId ?? "",
35
- ...params.metadata,
52
+ const intent = await stripe.paymentIntents.create(
53
+ {
54
+ amount: params.amount,
55
+ currency: params.currency.toLowerCase(),
56
+ metadata: {
57
+ orderId: params.orderId,
58
+ customerId: params.customerId ?? "",
59
+ ...params.metadata,
60
+ },
61
+ automatic_payment_methods: {
62
+ enabled: true,
63
+ allow_redirects: "never",
64
+ },
65
+ // Porulle's synchronous checkout reserves inventory and captures
66
+ // after order creation. With a token, confirm up to the
67
+ // requires_capture boundary; never send raw card data here.
68
+ capture_method: "manual",
69
+ ...(params.paymentMethodToken
70
+ ? { payment_method: params.paymentMethodToken, confirm: true }
71
+ : {}),
36
72
  },
37
- automatic_payment_methods: {
38
- enabled: true,
39
- },
40
- });
73
+ params.idempotencyKey
74
+ ? { idempotencyKey: params.idempotencyKey }
75
+ : undefined,
76
+ );
41
77
 
42
78
  return Ok({
43
79
  id: intent.id,
@@ -49,7 +85,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
49
85
  } catch (error) {
50
86
  return Err({
51
87
  code: "PAYMENT_INTENT_CREATE_FAILED",
52
- message: error instanceof Error ? error.message : "Stripe payment intent creation failed.",
88
+ message: providerErrorMessage(error, "Stripe payment intent creation failed."),
53
89
  });
54
90
  }
55
91
  },
@@ -65,7 +101,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
65
101
  } catch (error) {
66
102
  return Err({
67
103
  code: "PAYMENT_CAPTURE_FAILED",
68
- message: error instanceof Error ? error.message : "Stripe capture failed.",
104
+ message: providerErrorMessage(error, "Stripe capture failed."),
69
105
  });
70
106
  }
71
107
  },
@@ -90,7 +126,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
90
126
  } catch (error) {
91
127
  return Err({
92
128
  code: "PAYMENT_REFUND_FAILED",
93
- message: error instanceof Error ? error.message : "Stripe refund failed.",
129
+ message: providerErrorMessage(error, "Stripe refund failed."),
94
130
  });
95
131
  }
96
132
  },
@@ -102,7 +138,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
102
138
  } catch (error) {
103
139
  return Err({
104
140
  code: "PAYMENT_CANCEL_FAILED",
105
- message: error instanceof Error ? error.message : "Stripe cancellation failed.",
141
+ message: providerErrorMessage(error, "Stripe cancellation failed."),
106
142
  });
107
143
  }
108
144
  },
@@ -135,7 +171,7 @@ export function stripePayment(options: StripeAdapterOptions): PaymentAdapter {
135
171
  } catch (error) {
136
172
  return Err({
137
173
  code: "WEBHOOK_VERIFICATION_FAILED",
138
- message: error instanceof Error ? error.message : "Stripe webhook verification failed.",
174
+ message: providerErrorMessage(error, "Stripe webhook verification failed."),
139
175
  });
140
176
  }
141
177
  },