@happyvertical/payments 0.74.11 → 0.76.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/README.md CHANGED
@@ -31,11 +31,63 @@ import { StripeAdapter } from '@happyvertical/payments/stripe';
31
31
  - `BtcAdapter`: BTCPay Server invoice, polling/webhook status, tiered
32
32
  confirmation policy, and unsigned PSBT payout creation.
33
33
  - `StripeAdapter`: Stripe Checkout URL settlement, webhook verification,
34
- refunds, and Stripe Connect transfers.
34
+ refunds, Stripe Connect transfers, saved payment methods / card-on-file
35
+ (`createSetupSession` / `getSetupResult`), and the manual-capture card
36
+ lifecycle (`authorizePayment` / `capturePayment` / `voidPayment`).
35
37
 
36
38
  The package does not depend on SMRT or a database. Consumers own quote
37
39
  persistence, webhook routing, and operational policy.
38
40
 
41
+ ### Save a card (setup) → charge later
42
+
43
+ ```ts
44
+ const setup = await stripe.createSetupSession({
45
+ customerEmail: advertiser.email, // or providerCustomerId for an existing customer
46
+ successUrl,
47
+ cancelUrl,
48
+ });
49
+ redirect(setup.url); // buyer saves their card on Stripe's hosted page
50
+
51
+ // on return, read the reusable references to persist:
52
+ const saved = await stripe.getSetupResult({ sessionId: setup.sessionId });
53
+ if (saved.status === 'complete') {
54
+ // both refs are guaranteed present when complete; persist them (never `raw`,
55
+ // which may contain PII). Charge later via authorizePayment (see below /
56
+ // the manual-capture adapter).
57
+ persist({ cus: saved.providerCustomerId, pm: saved.providerPaymentMethodId,
58
+ brand: saved.brand, last4: saved.last4 });
59
+ }
60
+ // status: 'pending' (still processing), 'failed' (declined — stop polling),
61
+ // 'expired' (session lapsed). A setup-mode Checkout webhook is only a
62
+ // "go call getSetupResult" trigger, not the save outcome itself.
63
+ ```
64
+
65
+ ### Manual capture (authorize → capture / void)
66
+
67
+ Charge a saved card later — e.g. hold at approval, capture on fulfillment:
68
+
69
+ ```ts
70
+ const auth = await stripe.authorizePayment({
71
+ amount: 5000, // minor units
72
+ currency: 'CAD',
73
+ providerPaymentMethodId: saved.providerPaymentMethodId, // pm_...
74
+ providerCustomerId: saved.providerCustomerId, // cus_... — REQUIRED for a saved card
75
+ quoteId: campaign.id, // stamp your id so capture/void webhooks are correlatable
76
+ // offSession defaults to true (buyer absent). An off-session step-up throws
77
+ // `authentication_required`; re-prompt on-session (offSession: false) to recover.
78
+ });
79
+ if (auth.status !== 'requires_capture') {
80
+ // 'succeeded' means already captured (don't capture again); else declined.
81
+ }
82
+ await stripe.capturePayment({ providerPaymentId: auth.providerPaymentId, idempotencyKey });
83
+ // or, to release the hold:
84
+ await stripe.voidPayment({ providerPaymentId: auth.providerPaymentId, idempotencyKey });
85
+ ```
86
+
87
+ Common footguns: omitting `providerCustomerId` for a customer-attached (saved)
88
+ card 400s at charge time; omitting `quoteId` leaves the intent's
89
+ capture/void/fail webhooks un-correlatable (`processing`, no `quoteId`).
90
+
39
91
  Public payment amounts follow Stripe's convention: `amount` is an integer in
40
92
  the smallest currency unit, paired with a `currency` code. For example,
41
93
  `{ amount: 1234, currency: 'USD' }` means USD 12.34. Crypto settlement uses the
@@ -1,5 +1,5 @@
1
1
  import { FetchLike } from '../shared.js';
2
- import { CreatePaymentOptionInput, PaymentBackend, PaymentBackendCapabilities, PaymentEvent, PaymentOption, PaymentStatus, PaymentStatusContext, PaymentStatusResult, PaymentWebhookEvent, PayoutResult, RefundPaymentInput, RefundResult, SendPayoutInput, WatchPaymentInput } from '../types.js';
2
+ import { AuthorizationResult, AuthorizePaymentInput, CapturePaymentInput, CaptureResult, CreatePaymentOptionInput, CreateSetupSessionInput, GetSetupResultInput, PaymentBackend, PaymentBackendCapabilities, PaymentEvent, PaymentOption, PaymentStatus, PaymentStatusContext, PaymentStatusResult, PaymentWebhookEvent, PayoutResult, RefundPaymentInput, RefundResult, SavedPaymentMethod, SendPayoutInput, SetupSession, VoidPaymentInput, VoidResult, WatchPaymentInput } from '../types.js';
3
3
  export declare const STRIPE_BACKEND_ID = "stripe";
4
4
  export interface StripeAdapterOptions {
5
5
  secretKey: string;
@@ -45,6 +45,11 @@ export declare class StripeAdapter implements PaymentBackend {
45
45
  getStatus(quoteId: string, payTo: string, context?: PaymentStatusContext): Promise<PaymentStatusResult>;
46
46
  sendPayout(input: SendPayoutInput): Promise<PayoutResult>;
47
47
  refundPayment(input: RefundPaymentInput): Promise<RefundResult>;
48
+ authorizePayment(input: AuthorizePaymentInput): Promise<AuthorizationResult>;
49
+ capturePayment(input: CapturePaymentInput): Promise<CaptureResult>;
50
+ voidPayment(input: VoidPaymentInput): Promise<VoidResult>;
51
+ createSetupSession(input: CreateSetupSessionInput): Promise<SetupSession>;
52
+ getSetupResult(input: GetSetupResultInput): Promise<SavedPaymentMethod>;
48
53
  parseWebhookEvent(payload: string, signature?: string): StripeWebhookEvent;
49
54
  private stripeRequest;
50
55
  private assertSupportedCurrency;
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../src/adapters/stripe.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,KAAK,SAAS,EAYf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,0BAA0B,EAC1B,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,kBAAkB,EAClB,YAAY,EACZ,eAAe,EACf,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,iBAAiB,WAAW,CAAC;AAM1C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,kBAAmB,SAAQ,mBAAmB;IAC7D,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,GAAG,EAAE,OAAO,CAAC;CACd;AAED,qBAAa,aAAc,YAAW,cAAc;IAgBtC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAfpC,QAAQ,CAAC,YAAY,EAAE,0BAA0B,CAAC;IAElD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAc;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAS;IACjD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAS;IAClD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoC;IACnE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;gBAE5B,OAAO,EAAE,oBAAoB;IA4FpD,mBAAmB,CACvB,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,aAAa,CAAC;IA2FzB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,CAAC,YAAY,CAAC;IAW7D,SAAS,CACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC;IA2FzB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC;IA+CzD,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC;IAwDrE,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,kBAAkB;YA6D5D,aAAa;IA2B3B,OAAO,CAAC,uBAAuB;YAQjB,iCAAiC;CAsBhD;AAsED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,EACd,gBAAgB,SAAM,GACrB,IAAI,CA2FN"}
1
+ {"version":3,"file":"stripe.d.ts","sourceRoot":"","sources":["../../src/adapters/stripe.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { createHmac, timingSafeEqual } from "node:crypto";
2
2
  import { P as PaymentConfigurationError, b as PaymentProviderError, d as PaymentVerificationError } from "../chunks/errors-BgFC46qQ.js";
3
- import { g as getFetch, a as normalizeMaxStoredPaymentOptions, b as normalizeUrlString, n as normalizeNonEmptyString, o as normalizePositivePaymentAmount, h as normalizeDate, t as formEncode, r as rememberPaymentOption, p as pollPaymentStatus, i as normalizeMinorUnitAmount, j as readJsonResponse, s as applyExpiryToPendingStatus } from "../chunks/shared-DGHSqDQT.js";
3
+ import { g as getFetch, a as normalizeMaxStoredPaymentOptions, b as normalizeUrlString, n as normalizeNonEmptyString, o as normalizePositivePaymentAmount, h as normalizeDate, t as formEncode, r as rememberPaymentOption, p as pollPaymentStatus, i as normalizeMinorUnitAmount, e as normalizePositiveMinorUnitAmount, j as readJsonResponse, s as applyExpiryToPendingStatus } from "../chunks/shared-DGHSqDQT.js";
4
4
  const STRIPE_BACKEND_ID = "stripe";
5
5
  const STRIPE_CHECKOUT_MIN_EXPIRY_MS = 30 * 60 * 1e3;
6
6
  const STRIPE_CHECKOUT_MAX_EXPIRY_MS = 24 * 60 * 60 * 1e3;
@@ -86,6 +86,8 @@ class StripeAdapter {
86
86
  supportsRefunds: true,
87
87
  supportsPayouts: true,
88
88
  supportsWebhooks: true,
89
+ supportsManualCapture: true,
90
+ supportsSavedPaymentMethods: true,
89
91
  metadata: {
90
92
  provider: "stripe"
91
93
  }
@@ -341,6 +343,239 @@ class StripeAdapter {
341
343
  raw: refund
342
344
  };
343
345
  }
346
+ async authorizePayment(input) {
347
+ const currency = normalizeStripeCurrency(input.currency);
348
+ this.assertSupportedCurrency(currency);
349
+ const amount = normalizePositivePaymentAmount(
350
+ input.amount,
351
+ currency,
352
+ "Stripe authorize amount"
353
+ );
354
+ const paymentMethod = normalizeNonEmptyString(
355
+ input.providerPaymentMethodId,
356
+ "Stripe authorize providerPaymentMethodId"
357
+ );
358
+ const providerCustomerId = input.providerCustomerId === void 0 ? void 0 : normalizeNonEmptyString(
359
+ input.providerCustomerId,
360
+ "Stripe authorize providerCustomerId"
361
+ );
362
+ const quoteId = input.quoteId === void 0 ? void 0 : normalizeNonEmptyString(input.quoteId, "Stripe authorize quoteId");
363
+ const intent = await this.stripeRequest(
364
+ "/payment_intents",
365
+ {
366
+ method: "POST",
367
+ idempotencyKey: input.idempotencyKey,
368
+ body: formEncode({
369
+ amount,
370
+ currency,
371
+ confirm: true,
372
+ "payment_method_types[]": "card",
373
+ description: input.description,
374
+ ...Object.fromEntries([
375
+ ["payment_method", paymentMethod],
376
+ ["capture_method", "manual"],
377
+ // Off-session (merchant-initiated) by default — the primary use is
378
+ // charging a saved card while the buyer is absent. Without this,
379
+ // Stripe treats it as on-session and may raise an SCA challenge the
380
+ // absent buyer can't complete, so the hold is never placed.
381
+ ["off_session", input.offSession ?? true]
382
+ ]),
383
+ ...providerCustomerId === void 0 ? {} : { customer: providerCustomerId },
384
+ ...flattenStripeMetadata(input.metadata),
385
+ ...quoteId === void 0 ? {} : { "metadata[quoteId]": quoteId }
386
+ })
387
+ }
388
+ );
389
+ const providerPaymentId = normalizeOptionalProviderString(
390
+ readProviderString(intent, "id")
391
+ );
392
+ if (!providerPaymentId) {
393
+ throw new PaymentProviderError(
394
+ "Stripe PaymentIntent response did not include an id."
395
+ );
396
+ }
397
+ const status = mapStripeAuthorizationStatus(readString(intent, "status"));
398
+ const actionRequired = status === "requires_action";
399
+ return {
400
+ backendId: this.capabilities.id,
401
+ status,
402
+ providerPaymentId,
403
+ amount: readSafeInteger(intent, "amount") ?? amount,
404
+ currency: (readString(intent, "currency") ?? currency).toUpperCase(),
405
+ clientSecret: actionRequired ? normalizeOptionalProviderString(
406
+ readProviderString(intent, "client_secret")
407
+ ) : void 0,
408
+ nextAction: actionRequired ? intent.next_action ?? void 0 : void 0,
409
+ raw: intent
410
+ };
411
+ }
412
+ async capturePayment(input) {
413
+ const providerPaymentId = normalizeNonEmptyString(
414
+ input.providerPaymentId,
415
+ "Stripe capture providerPaymentId"
416
+ );
417
+ const amount = input.amount === void 0 ? void 0 : normalizePositiveMinorUnitAmount(
418
+ input.amount,
419
+ "Stripe capture amount"
420
+ );
421
+ const intent = await this.stripeRequest(
422
+ `/payment_intents/${encodeURIComponent(providerPaymentId)}/capture`,
423
+ {
424
+ method: "POST",
425
+ idempotencyKey: input.idempotencyKey,
426
+ body: formEncode({
427
+ ...Object.fromEntries([["amount_to_capture", amount]]),
428
+ ...flattenStripeMetadata(input.metadata)
429
+ })
430
+ }
431
+ );
432
+ return {
433
+ backendId: this.capabilities.id,
434
+ status: mapStripeCaptureStatus(readString(intent, "status")),
435
+ providerPaymentId: normalizeOptionalProviderString(readProviderString(intent, "id")) ?? providerPaymentId,
436
+ amount: readSafeInteger(intent, "amount_received") ?? readSafeInteger(intent, "amount") ?? amount,
437
+ currency: readStripeResultCurrency(intent),
438
+ raw: intent
439
+ };
440
+ }
441
+ async voidPayment(input) {
442
+ const providerPaymentId = normalizeNonEmptyString(
443
+ input.providerPaymentId,
444
+ "Stripe void providerPaymentId"
445
+ );
446
+ const reason = input.reason === void 0 ? void 0 : normalizeNonEmptyString(input.reason, "Stripe void reason");
447
+ const intent = await this.stripeRequest(
448
+ `/payment_intents/${encodeURIComponent(providerPaymentId)}/cancel`,
449
+ {
450
+ method: "POST",
451
+ idempotencyKey: input.idempotencyKey,
452
+ body: formEncode(Object.fromEntries([["cancellation_reason", reason]]))
453
+ }
454
+ );
455
+ return {
456
+ backendId: this.capabilities.id,
457
+ status: mapStripeVoidStatus(readString(intent, "status")),
458
+ providerPaymentId: normalizeOptionalProviderString(readProviderString(intent, "id")) ?? providerPaymentId,
459
+ amount: readSafeInteger(intent, "amount"),
460
+ currency: readStripeResultCurrency(intent),
461
+ raw: intent
462
+ };
463
+ }
464
+ async createSetupSession(input) {
465
+ const rawSuccessUrl = input.successUrl ?? this.options.successUrl;
466
+ const rawCancelUrl = input.cancelUrl ?? this.options.cancelUrl;
467
+ if (rawSuccessUrl === void 0 || rawCancelUrl === void 0) {
468
+ throw new PaymentConfigurationError(
469
+ "StripeAdapter createSetupSession requires successUrl and cancelUrl."
470
+ );
471
+ }
472
+ const successUrl = normalizeUrlString(rawSuccessUrl, "Stripe successUrl");
473
+ const cancelUrl = normalizeUrlString(rawCancelUrl, "Stripe cancelUrl");
474
+ const currency = normalizeStripeCurrency(
475
+ input.currency ?? this.defaultCurrency
476
+ );
477
+ this.assertSupportedCurrency(currency);
478
+ const providerCustomerId = input.providerCustomerId === void 0 ? void 0 : normalizeNonEmptyString(
479
+ input.providerCustomerId,
480
+ "Stripe setup customer"
481
+ );
482
+ const customerParams = [];
483
+ if (providerCustomerId !== void 0) {
484
+ customerParams.push(["customer", providerCustomerId]);
485
+ } else {
486
+ customerParams.push(["customer_creation", "always"]);
487
+ if (input.customerEmail !== void 0) {
488
+ customerParams.push([
489
+ "customer_email",
490
+ normalizeNonEmptyString(
491
+ input.customerEmail,
492
+ "Stripe setup customerEmail"
493
+ )
494
+ ]);
495
+ }
496
+ }
497
+ const params = {
498
+ mode: "setup",
499
+ currency,
500
+ // Restrict to cards: SavedPaymentMethod exposes card display fields
501
+ // (brand/last4/expiry), so allowing SEPA/Bacs/etc. would yield saved
502
+ // methods with no usable display detail.
503
+ "payment_method_types[]": "card",
504
+ ...Object.fromEntries([
505
+ ["success_url", successUrl],
506
+ ["cancel_url", cancelUrl],
507
+ ...customerParams
508
+ ]),
509
+ ...flattenStripeMetadata(input.metadata)
510
+ };
511
+ const session = await this.stripeRequest(
512
+ "/checkout/sessions",
513
+ {
514
+ method: "POST",
515
+ idempotencyKey: input.idempotencyKey,
516
+ body: formEncode(params)
517
+ }
518
+ );
519
+ const sessionId = normalizeOptionalProviderString(
520
+ readProviderString(session, "id")
521
+ );
522
+ const url = normalizeOptionalProviderString(
523
+ readProviderString(session, "url")
524
+ );
525
+ if (!sessionId || !url) {
526
+ throw new PaymentProviderError(
527
+ "Stripe setup Checkout Session response did not include id and url."
528
+ );
529
+ }
530
+ return {
531
+ backendId: this.capabilities.id,
532
+ sessionId,
533
+ url,
534
+ providerCustomerId: providerCustomerId ?? normalizeOptionalProviderString(
535
+ readProviderString(session, "customer")
536
+ ),
537
+ raw: session
538
+ };
539
+ }
540
+ async getSetupResult(input) {
541
+ const sessionId = normalizeNonEmptyString(
542
+ input.sessionId,
543
+ "Stripe setup sessionId"
544
+ );
545
+ const query = new URLSearchParams();
546
+ query.append("expand[]", "setup_intent.payment_method");
547
+ const session = await this.stripeRequest(
548
+ `/checkout/sessions/${encodeURIComponent(sessionId)}?${query.toString()}`
549
+ );
550
+ const setupIntent = readObject(session, "setup_intent");
551
+ const paymentMethod = readObject(setupIntent, "payment_method");
552
+ const card = readObject(paymentMethod, "card");
553
+ const providerCustomerId = normalizeOptionalProviderString(
554
+ readProviderString(session, "customer") ?? readProviderString(readObject(session, "customer"), "id")
555
+ );
556
+ const providerPaymentMethodId = normalizeOptionalProviderString(
557
+ readProviderString(paymentMethod, "id")
558
+ );
559
+ let status = mapStripeSetupStatus(
560
+ readString(session, "status"),
561
+ readString(setupIntent, "status")
562
+ );
563
+ if (status === "complete" && (!providerCustomerId || !providerPaymentMethodId)) {
564
+ status = "pending";
565
+ }
566
+ return {
567
+ backendId: this.capabilities.id,
568
+ status,
569
+ providerCustomerId,
570
+ providerPaymentMethodId,
571
+ type: readString(paymentMethod, "type"),
572
+ brand: readString(card, "brand"),
573
+ last4: readString(card, "last4"),
574
+ expMonth: readSafeInteger(card, "exp_month"),
575
+ expYear: readSafeInteger(card, "exp_year"),
576
+ raw: session
577
+ };
578
+ }
344
579
  parseWebhookEvent(payload, signature) {
345
580
  if (!this.webhookSecret) {
346
581
  throw new PaymentConfigurationError(
@@ -379,7 +614,12 @@ class StripeAdapter {
379
614
  type,
380
615
  status: mapStripeWebhookStatus(type, data),
381
616
  quoteId: normalizeOptionalWebhookString(
382
- readString(data, "client_reference_id") ?? readString(
617
+ // `client_reference_id` is a Checkout Session-only field; honor it only
618
+ // for session events so a non-session object (a PaymentIntent / Charge /
619
+ // Transfer, possibly from a malicious Connect account) can't spoof
620
+ // correlation to another quote's id. Non-session events correlate only
621
+ // via our own `metadata.quoteId`.
622
+ (type.startsWith("checkout.session.") ? readString(data, "client_reference_id") : void 0) ?? readString(
383
623
  data?.metadata ?? {},
384
624
  "quoteId"
385
625
  )
@@ -625,12 +865,27 @@ function mapStripeWebhookStatus(type, object) {
625
865
  if (type === "checkout.session.expired") {
626
866
  return "expired";
627
867
  }
628
- if (type?.includes("failed")) {
629
- return "failed";
868
+ if (type === "payment_intent.succeeded" || type === "payment_intent.canceled" || type === "payment_intent.payment_failed") {
869
+ const metadata = object?.metadata ?? {};
870
+ const owned = normalizeOptionalWebhookString(readString(metadata, "quoteId")) !== void 0;
871
+ if (owned) {
872
+ if (type === "payment_intent.succeeded") {
873
+ return "confirmed";
874
+ }
875
+ if (type === "payment_intent.canceled" && readString(object, "cancellation_reason") === "automatic") {
876
+ return "expired";
877
+ }
878
+ return "failed";
879
+ }
880
+ return "processing";
630
881
  }
631
- if (type?.includes("refunded")) {
882
+ const isPaymentInEvent = type?.startsWith("checkout.session.") === true || type?.startsWith("payment_intent.") === true || type?.startsWith("charge.") === true;
883
+ if (isPaymentInEvent && type?.includes("refunded")) {
632
884
  return "refunded";
633
885
  }
886
+ if (isPaymentInEvent && type?.includes("failed")) {
887
+ return "failed";
888
+ }
634
889
  return "processing";
635
890
  }
636
891
  function mapStripeRefundStatus(status) {
@@ -646,6 +901,58 @@ function mapStripeRefundStatus(status) {
646
901
  return "submitted";
647
902
  }
648
903
  }
904
+ function mapStripeAuthorizationStatus(status) {
905
+ switch (status) {
906
+ case "requires_capture":
907
+ return "requires_capture";
908
+ case "succeeded":
909
+ return "succeeded";
910
+ case "requires_action":
911
+ return "requires_action";
912
+ case "processing":
913
+ return "processing";
914
+ default:
915
+ return "failed";
916
+ }
917
+ }
918
+ function mapStripeCaptureStatus(status) {
919
+ switch (status) {
920
+ case "succeeded":
921
+ return "succeeded";
922
+ // Capturing an authorized intent shouldn't re-enter authentication; treat
923
+ // any in-flight/action state as still processing rather than a failure.
924
+ case "processing":
925
+ case "requires_action":
926
+ return "processing";
927
+ default:
928
+ return "failed";
929
+ }
930
+ }
931
+ function mapStripeVoidStatus(status) {
932
+ return status === "canceled" ? "canceled" : "failed";
933
+ }
934
+ function readStripeResultCurrency(value) {
935
+ const currency = readString(value, "currency");
936
+ return currency === void 0 ? void 0 : currency.toUpperCase();
937
+ }
938
+ function mapStripeSetupStatus(sessionStatus, setupIntentStatus) {
939
+ if (sessionStatus === "expired") {
940
+ return "expired";
941
+ }
942
+ if (sessionStatus === "complete") {
943
+ if (setupIntentStatus === "succeeded") {
944
+ return "complete";
945
+ }
946
+ if (setupIntentStatus === "canceled" || setupIntentStatus === "requires_payment_method") {
947
+ return "failed";
948
+ }
949
+ }
950
+ return "pending";
951
+ }
952
+ function readObject(value, key) {
953
+ const item = value?.[key];
954
+ return item && typeof item === "object" && !Array.isArray(item) ? item : void 0;
955
+ }
649
956
  function extractStripeSessionId(payTo) {
650
957
  if (/^cs_(test_|live_)?[A-Za-z0-9_]+$/.test(payTo)) {
651
958
  return payTo;
@@ -1 +1 @@
1
- {"version":3,"file":"stripe.js","sources":["../../src/adapters/stripe.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'node:crypto';\nimport {\n PaymentConfigurationError,\n PaymentProviderError,\n PaymentVerificationError,\n} from '../errors.js';\nimport {\n applyExpiryToPendingStatus,\n type FetchLike,\n formEncode,\n getFetch,\n normalizeDate,\n normalizeMaxStoredPaymentOptions,\n normalizeMinorUnitAmount,\n normalizeNonEmptyString,\n normalizePositivePaymentAmount,\n normalizeUrlString,\n pollPaymentStatus,\n readJsonResponse,\n rememberPaymentOption,\n} from '../shared.js';\nimport type {\n CreatePaymentOptionInput,\n PaymentBackend,\n PaymentBackendCapabilities,\n PaymentEvent,\n PaymentOption,\n PaymentStatus,\n PaymentStatusContext,\n PaymentStatusResult,\n PaymentWebhookEvent,\n PayoutResult,\n RefundPaymentInput,\n RefundResult,\n SendPayoutInput,\n WatchPaymentInput,\n} from '../types.js';\n\nexport const STRIPE_BACKEND_ID = 'stripe';\nconst STRIPE_CHECKOUT_MIN_EXPIRY_MS = 30 * 60 * 1_000;\nconst STRIPE_CHECKOUT_MAX_EXPIRY_MS = 24 * 60 * 60 * 1_000;\nconst DEFAULT_STRIPE_API_VERSION = '2024-06-20';\nconst DEFAULT_MAX_STORED_WEBHOOK_EVENT_IDS = 50_000;\n\nexport interface StripeAdapterOptions {\n secretKey: string;\n fetch?: FetchLike;\n apiBaseUrl?: string;\n apiVersion?: string;\n defaultCurrency?: string;\n supportedCurrencies?: string[];\n successUrl?: string;\n cancelUrl?: string;\n checkoutMode?: string;\n webhookSecret?: string;\n pollIntervalMs?: number;\n maxStoredPaymentOptions?: number;\n maxStoredWebhookEventIds?: number;\n}\n\nexport interface StripeWebhookEvent extends PaymentWebhookEvent {\n id: string;\n type: string;\n status: PaymentStatus;\n quoteId?: string;\n providerPaymentId?: string;\n raw: unknown;\n}\n\nexport class StripeAdapter implements PaymentBackend {\n readonly capabilities: PaymentBackendCapabilities;\n\n private readonly fetch: FetchLike;\n private readonly secretKey: string;\n private readonly apiBaseUrl: string;\n private readonly apiVersion: string;\n private readonly defaultCurrency: string;\n private readonly supportedCurrencies: Set<string>;\n private readonly checkoutMode: string;\n private readonly webhookSecret: string | undefined;\n private readonly maxStoredPaymentOptions: number;\n private readonly maxStoredWebhookEventIds: number;\n private readonly optionsByQuote = new Map<string, PaymentOption>();\n private readonly seenWebhookEventIds = new Set<string>();\n\n constructor(private readonly options: StripeAdapterOptions) {\n if (typeof options.secretKey !== 'string' || !options.secretKey.trim()) {\n throw new PaymentConfigurationError('StripeAdapter requires secretKey.');\n }\n\n if (options.webhookSecret !== undefined) {\n if (typeof options.webhookSecret !== 'string') {\n throw new PaymentConfigurationError(\n 'StripeAdapter webhookSecret must be a string when configured.',\n );\n }\n\n if (!options.webhookSecret.trim()) {\n throw new PaymentConfigurationError(\n 'StripeAdapter webhookSecret must not be empty when configured.',\n );\n }\n }\n\n if (options.apiBaseUrl !== undefined) {\n if (typeof options.apiBaseUrl !== 'string') {\n throw new PaymentConfigurationError(\n 'StripeAdapter apiBaseUrl must be a string when configured.',\n );\n }\n\n if (!options.apiBaseUrl.trim()) {\n throw new PaymentConfigurationError(\n 'StripeAdapter apiBaseUrl must not be empty when configured.',\n );\n }\n }\n\n this.fetch = getFetch(options.fetch);\n this.maxStoredPaymentOptions = normalizeMaxStoredPaymentOptions(\n options.maxStoredPaymentOptions,\n 'StripeAdapter maxStoredPaymentOptions',\n );\n this.maxStoredWebhookEventIds = normalizeMaxStoredPaymentOptions(\n options.maxStoredWebhookEventIds ?? DEFAULT_MAX_STORED_WEBHOOK_EVENT_IDS,\n 'StripeAdapter maxStoredWebhookEventIds',\n );\n this.secretKey = options.secretKey.trim();\n this.apiBaseUrl = normalizeUrlString(\n options.apiBaseUrl ?? 'https://api.stripe.com/v1',\n 'StripeAdapter apiBaseUrl',\n ).replace(/\\/$/, '');\n this.apiVersion = normalizeNonEmptyString(\n options.apiVersion ?? DEFAULT_STRIPE_API_VERSION,\n 'StripeAdapter apiVersion',\n );\n this.defaultCurrency = normalizeStripeCurrency(\n options.defaultCurrency ?? 'usd',\n );\n this.supportedCurrencies = normalizeSupportedStripeCurrencies(\n options.supportedCurrencies,\n this.defaultCurrency,\n );\n this.checkoutMode = options.checkoutMode ?? 'payment';\n\n if (this.checkoutMode !== 'payment') {\n throw new PaymentConfigurationError(\n 'StripeAdapter only supports payment Checkout mode.',\n );\n }\n\n this.webhookSecret = options.webhookSecret?.trim();\n this.capabilities = {\n id: STRIPE_BACKEND_ID,\n displayName: 'Stripe Checkout',\n settlementCurrency: this.defaultCurrency.toUpperCase(),\n supportedSettlementCurrencies: [...this.supportedCurrencies].map(\n (currency) => currency.toUpperCase(),\n ),\n chain: 'stripe',\n settlementShape: 'url',\n x402Capable: false,\n confirmationLatency: {\n expectedSeconds: 5,\n maxExpectedSeconds: 600,\n description:\n 'Card payments usually confirm in seconds; bank debits can remain processing while Stripe settles them.',\n },\n supportsRefunds: true,\n supportsPayouts: true,\n supportsWebhooks: true,\n metadata: {\n provider: 'stripe',\n },\n };\n }\n\n async createPaymentOption(\n input: CreatePaymentOptionInput,\n ): Promise<PaymentOption> {\n const quoteId = normalizeNonEmptyString(input.quoteId, 'Stripe quoteId');\n const rawSuccessUrl = input.successUrl ?? this.options.successUrl;\n const rawCancelUrl = input.cancelUrl ?? this.options.cancelUrl;\n\n if (rawSuccessUrl === undefined || rawCancelUrl === undefined) {\n throw new PaymentConfigurationError(\n 'StripeAdapter createPaymentOption requires successUrl and cancelUrl.',\n );\n }\n\n const successUrl = normalizeUrlString(rawSuccessUrl, 'Stripe successUrl');\n const cancelUrl = normalizeUrlString(rawCancelUrl, 'Stripe cancelUrl');\n const currency = normalizeStripeCurrency(input.currency);\n this.assertSupportedCurrency(currency);\n const amount = normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe Checkout amount',\n );\n const expiresAt = normalizeDate(input.expiresAt);\n const stripeExpiresAt = normalizeStripeCheckoutExpiresAt(expiresAt);\n const params: Record<string, unknown> = {\n mode: this.checkoutMode,\n ...Object.fromEntries([\n ['success_url', successUrl],\n ['cancel_url', cancelUrl],\n ['client_reference_id', quoteId],\n ['customer_email', input.buyerEmail],\n ['expires_at', Math.floor(stripeExpiresAt.getTime() / 1_000)],\n ]),\n 'line_items[0][quantity]': 1,\n 'line_items[0][price_data][currency]': currency,\n 'line_items[0][price_data][unit_amount]': amount,\n 'line_items[0][price_data][product_data][name]':\n input.description ?? `Quote ${quoteId}`,\n ...flattenStripeMetadata(input.metadata),\n 'metadata[quoteId]': quoteId,\n };\n\n const session = await this.stripeRequest<Record<string, unknown>>(\n '/checkout/sessions',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode(params),\n },\n );\n const sessionId = normalizeOptionalProviderString(\n readProviderString(session, 'id'),\n );\n const checkoutUrl = normalizeOptionalProviderString(\n readProviderString(session, 'url'),\n );\n\n if (!sessionId || !checkoutUrl) {\n throw new PaymentProviderError(\n 'Stripe Checkout Session response did not include id and url.',\n );\n }\n\n const option: PaymentOption = {\n backendId: this.capabilities.id,\n quoteId,\n payTo: checkoutUrl,\n settlementShape: 'url',\n settlementCurrency: currency.toUpperCase(),\n settlementAmount: amount,\n amount,\n currency: currency.toUpperCase(),\n expiresAt: stripeExpiresAt,\n providerPaymentId: sessionId,\n paymentUri: checkoutUrl,\n metadata: {\n sessionId,\n paymentIntent: normalizeOptionalProviderString(\n readProviderString(session, 'payment_intent'),\n ),\n },\n };\n\n rememberPaymentOption(\n this.optionsByQuote,\n quoteId,\n option,\n this.maxStoredPaymentOptions,\n );\n\n return option;\n }\n\n watchPayment(input: WatchPaymentInput): AsyncIterable<PaymentEvent> {\n return pollPaymentStatus(\n {\n ...input,\n pollIntervalMs:\n input.pollIntervalMs ?? this.options.pollIntervalMs ?? 5_000,\n },\n () => this.getStatus(input.quoteId, input.payTo, input.statusContext),\n );\n }\n\n async getStatus(\n quoteId: string,\n payTo: string,\n context: PaymentStatusContext = {},\n ): Promise<PaymentStatusResult> {\n const normalizedQuoteId = normalizeNonEmptyString(\n quoteId,\n 'Stripe quoteId',\n );\n const normalizedPayTo = normalizeNonEmptyString(payTo, 'Stripe payTo');\n const contextProviderPaymentId =\n context.providerPaymentId === undefined\n ? undefined\n : normalizeNonEmptyString(\n context.providerPaymentId,\n 'Stripe providerPaymentId',\n );\n const sessionId =\n this.optionsByQuote.get(normalizedQuoteId)?.providerPaymentId ??\n contextProviderPaymentId ??\n extractStripeSessionId(normalizedPayTo);\n\n if (!sessionId) {\n throw new PaymentConfigurationError(\n 'Stripe getStatus requires a Checkout Session id or URL.',\n );\n }\n\n const session = await this.stripeRequest<Record<string, unknown>>(\n `/checkout/sessions/${encodeURIComponent(sessionId)}`,\n );\n const sessionQuoteId = readStripeSessionQuoteId(session);\n\n if (sessionQuoteId !== undefined && sessionQuoteId !== normalizedQuoteId) {\n throw new PaymentVerificationError(\n `Stripe Checkout Session quoteId ${sessionQuoteId} did not match ${normalizedQuoteId}.`,\n );\n }\n\n const paymentStatus = readString(session, 'payment_status');\n const status = mapStripeStatus(\n readString(session, 'status'),\n paymentStatus,\n );\n\n const option = this.optionsByQuote.get(normalizedQuoteId);\n const contextAmount =\n context.amount === undefined\n ? undefined\n : normalizeMinorUnitAmount(context.amount, 'Stripe status');\n const contextCurrency =\n context.currency === undefined\n ? undefined\n : normalizeStripeCurrency(context.currency).toUpperCase();\n const sessionCurrency =\n readString(session, 'currency') === undefined\n ? undefined\n : normalizeStripeCurrency(\n readString(session, 'currency') ?? '',\n ).toUpperCase();\n const sessionAmount = readSafeInteger(session, 'amount_total');\n const expiresAt =\n option?.expiresAt ??\n (context.expiresAt === undefined\n ? undefined\n : normalizeDate(context.expiresAt));\n const effectiveStatus = applyExpiryToPendingStatus(status, expiresAt);\n\n return {\n backendId: this.capabilities.id,\n quoteId: normalizedQuoteId,\n payTo: normalizedPayTo,\n status: effectiveStatus,\n settlementCurrency:\n sessionCurrency ??\n option?.settlementCurrency ??\n contextCurrency ??\n this.defaultCurrency.toUpperCase(),\n settlementAmount:\n sessionAmount ?? option?.settlementAmount ?? contextAmount,\n receivedAmount:\n paymentStatus === 'paid' || paymentStatus === 'no_payment_required'\n ? (sessionAmount ?? option?.settlementAmount ?? contextAmount)\n : undefined,\n amount: option?.amount ?? contextAmount,\n currency: option?.currency ?? contextCurrency,\n providerPaymentId: sessionId,\n transactionId: normalizeOptionalProviderString(\n readProviderString(session, 'payment_intent'),\n ),\n updatedAt: new Date(),\n raw: session,\n };\n }\n\n async sendPayout(input: SendPayoutInput): Promise<PayoutResult> {\n const currency = normalizeStripeCurrency(\n input.currency ?? this.defaultCurrency,\n );\n this.assertSupportedCurrency(currency);\n const destination = normalizeNonEmptyString(\n input.destination,\n 'Stripe payout destination',\n );\n const quoteId =\n input.quoteId === undefined\n ? undefined\n : normalizeNonEmptyString(input.quoteId, 'Stripe payout quoteId');\n const amount = normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe payout amount',\n );\n const transfer = await this.stripeRequest<Record<string, unknown>>(\n '/transfers',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode({\n amount,\n currency,\n destination,\n description: input.memo,\n ...flattenStripeMetadata(input.metadata),\n ...(quoteId === undefined ? {} : { 'metadata[quoteId]': quoteId }),\n }),\n },\n );\n\n return {\n backendId: this.capabilities.id,\n status: 'submitted',\n payoutId: normalizeOptionalProviderString(\n readProviderString(transfer, 'id'),\n ),\n destination,\n amount,\n currency: currency.toUpperCase(),\n raw: transfer,\n };\n }\n\n async refundPayment(input: RefundPaymentInput): Promise<RefundResult> {\n const rawPaymentReference = input.paymentId ?? input.transactionId;\n\n if (!rawPaymentReference) {\n throw new PaymentConfigurationError(\n 'Stripe refunds require paymentId or transactionId.',\n );\n }\n\n const paymentReference = normalizeNonEmptyString(\n rawPaymentReference,\n 'Stripe refund payment reference',\n );\n const currency = normalizeStripeCurrency(\n input.currency ?? this.defaultCurrency,\n );\n this.assertSupportedCurrency(currency);\n const amount =\n input.amount === undefined\n ? undefined\n : normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe refund amount',\n );\n const refundReferenceParam =\n await this.resolveStripeRefundReferenceParam(paymentReference);\n const refundParams: Record<string, unknown> = {\n ...refundReferenceParam,\n amount: amount === undefined ? undefined : amount,\n reason: input.reason,\n ...flattenStripeMetadata(input.metadata),\n };\n\n const refund = await this.stripeRequest<Record<string, unknown>>(\n '/refunds',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode(refundParams),\n },\n );\n\n return {\n backendId: this.capabilities.id,\n status: mapStripeRefundStatus(readString(refund, 'status')),\n refundId: normalizeOptionalProviderString(\n readProviderString(refund, 'id'),\n ),\n transactionId: paymentReference,\n amount,\n currency: currency.toUpperCase(),\n raw: refund,\n };\n }\n\n parseWebhookEvent(payload: string, signature?: string): StripeWebhookEvent {\n if (!this.webhookSecret) {\n throw new PaymentConfigurationError(\n 'StripeAdapter parseWebhookEvent requires webhookSecret.',\n );\n }\n\n if (!signature) {\n throw new PaymentProviderError('Missing Stripe webhook signature.');\n }\n\n verifyStripeWebhookSignature(payload, signature, this.webhookSecret);\n\n const event = parseStripeWebhookPayload(payload);\n const id = readRequiredWebhookString(\n event,\n 'id',\n 'Stripe webhook event id',\n );\n const type = readRequiredWebhookString(\n event,\n 'type',\n 'Stripe webhook event type',\n );\n\n const duplicate = this.seenWebhookEventIds.has(id);\n\n if (!duplicate) {\n this.seenWebhookEventIds.add(id);\n while (this.seenWebhookEventIds.size > this.maxStoredWebhookEventIds) {\n const oldest = this.seenWebhookEventIds.values().next().value;\n\n if (oldest === undefined) {\n break;\n }\n\n this.seenWebhookEventIds.delete(oldest);\n }\n }\n\n const data = (\n event.data as { object?: Record<string, unknown> } | undefined\n )?.object;\n\n return {\n id,\n type,\n status: mapStripeWebhookStatus(type, data),\n quoteId: normalizeOptionalWebhookString(\n readString(data, 'client_reference_id') ??\n readString(\n (data?.metadata as Record<string, unknown>) ?? {},\n 'quoteId',\n ),\n ),\n providerPaymentId: normalizeOptionalWebhookString(readString(data, 'id')),\n duplicate,\n raw: event,\n };\n }\n\n private async stripeRequest<T>(\n path: string,\n init: RequestInit & { idempotencyKey?: string } = {},\n ): Promise<T> {\n const headers = new Headers(init.headers);\n headers.set('Authorization', `Bearer ${this.secretKey}`);\n headers.set('Content-Type', 'application/x-www-form-urlencoded');\n headers.set('Accept', 'application/json');\n headers.set('Stripe-Version', this.apiVersion);\n\n if (init.idempotencyKey !== undefined) {\n headers.set(\n 'Idempotency-Key',\n normalizeNonEmptyString(init.idempotencyKey, 'Stripe idempotencyKey'),\n );\n }\n\n const { idempotencyKey: _idempotencyKey, ...requestInit } = init;\n const response = await this.fetch(`${this.apiBaseUrl}${path}`, {\n ...requestInit,\n method: init.method ?? 'GET',\n headers,\n });\n\n return readJsonResponse<T>(response, `Stripe ${path}`);\n }\n\n private assertSupportedCurrency(currency: string): void {\n if (!this.supportedCurrencies.has(currency)) {\n throw new PaymentConfigurationError(\n `StripeAdapter currency ${currency.toUpperCase()} is not configured as supported.`,\n );\n }\n }\n\n private async resolveStripeRefundReferenceParam(\n paymentReference: string,\n ): Promise<Record<string, string>> {\n if (paymentReference.startsWith('cs_')) {\n const session = await this.stripeRequest<Record<string, unknown>>(\n `/checkout/sessions/${encodeURIComponent(paymentReference)}`,\n );\n const paymentIntent = normalizeOptionalProviderString(\n readProviderString(session, 'payment_intent'),\n );\n\n if (!paymentIntent) {\n throw new PaymentProviderError(\n 'Stripe Checkout Session did not include payment_intent for refund.',\n );\n }\n\n return Object.fromEntries([['payment_intent', paymentIntent]]);\n }\n\n return stripeRefundReferenceParam(paymentReference);\n }\n}\n\nfunction stripeRefundReferenceParam(\n paymentReference: string,\n): Record<string, string> {\n if (paymentReference.startsWith('pi_')) {\n return Object.fromEntries([['payment_intent', paymentReference]]);\n }\n\n if (paymentReference.startsWith('ch_')) {\n return { charge: paymentReference };\n }\n\n throw new PaymentConfigurationError(\n 'Stripe refunds require a Checkout Session (cs_), payment_intent (pi_), or charge (ch_) reference.',\n );\n}\n\nfunction normalizeStripeCurrency(value: string): string {\n if (typeof value !== 'string') {\n throw new PaymentConfigurationError(\n `StripeAdapter currency must be a three-letter ISO currency code, received ${String(value)}.`,\n );\n }\n\n const normalized = value.trim().toLowerCase();\n\n if (!/^[a-z]{3}$/.test(normalized)) {\n throw new PaymentConfigurationError(\n `StripeAdapter currency must be a three-letter ISO currency code, received ${String(value)}.`,\n );\n }\n\n return normalized;\n}\n\nfunction normalizeSupportedStripeCurrencies(\n configuredCurrencies: string[] | undefined,\n defaultCurrency: string,\n): Set<string> {\n const normalized = new Set(\n (configuredCurrencies ?? ['usd', 'eur', 'gbp', 'cad']).map(\n normalizeStripeCurrency,\n ),\n );\n normalized.add(defaultCurrency);\n\n return normalized;\n}\n\nfunction normalizeStripeCheckoutExpiresAt(\n expiresAt: Date,\n now = Date.now(),\n): Date {\n if (expiresAt.getTime() <= now) {\n throw new PaymentProviderError('Stripe Checkout expiry is in the past.');\n }\n\n const min = now + STRIPE_CHECKOUT_MIN_EXPIRY_MS;\n const max = now + STRIPE_CHECKOUT_MAX_EXPIRY_MS;\n\n if (expiresAt.getTime() < min || expiresAt.getTime() > max) {\n throw new PaymentConfigurationError(\n 'Stripe Checkout expiry must be at least 30 minutes and no more than 24 hours from now.',\n );\n }\n\n return expiresAt;\n}\n\nexport function verifyStripeWebhookSignature(\n payload: string,\n signatureHeader: string,\n secret: string,\n toleranceSeconds = 300,\n): void {\n if (typeof payload !== 'string') {\n throw new PaymentProviderError('Stripe webhook payload must be a string.');\n }\n\n const normalizedSignatureHeader = normalizeNonEmptyString(\n signatureHeader,\n 'Stripe signature header',\n );\n const normalizedSecret = normalizeNonEmptyString(\n secret,\n 'Stripe webhook secret',\n );\n\n if (!Number.isFinite(toleranceSeconds) || toleranceSeconds < 0) {\n throw new PaymentConfigurationError(\n `Stripe webhook toleranceSeconds must be a non-negative finite number, received ${String(toleranceSeconds)}.`,\n );\n }\n\n const timestampCandidates: string[] = [];\n const signatures: string[] = [];\n\n for (const part of normalizedSignatureHeader.split(',')) {\n const [rawKey, ...rawValue] = part.split('=');\n const key = rawKey?.trim();\n const value = rawValue.join('=').trim();\n\n if (!key || !value) {\n continue;\n }\n\n if (key === 't') {\n timestampCandidates.push(value);\n }\n\n if (key === 'v1') {\n signatures.push(value);\n }\n }\n\n if (timestampCandidates.length !== 1 || signatures.length === 0) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const timestamp = timestampCandidates[0] ?? '';\n\n if (!/^\\d+$/.test(timestamp)) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const timestampSeconds = Number(timestamp);\n\n if (!Number.isSafeInteger(timestampSeconds)) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const nowSeconds = Date.now() / 1_000;\n const ageSeconds = nowSeconds - timestampSeconds;\n\n if (ageSeconds < -5) {\n throw new PaymentProviderError(\n 'Stripe webhook signature timestamp is in the future.',\n );\n }\n\n if (ageSeconds > toleranceSeconds) {\n throw new PaymentProviderError('Stripe webhook signature is too old.');\n }\n\n const expected = createHmac('sha256', normalizedSecret)\n .update(`${timestamp}.${payload}`)\n .digest('hex');\n const expectedBuffer = Buffer.from(expected, 'hex');\n\n for (const signature of signatures) {\n if (!/^[0-9a-f]+$/i.test(signature)) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const actualBuffer = Buffer.from(signature, 'hex');\n\n if (\n expectedBuffer.length === actualBuffer.length &&\n timingSafeEqual(expectedBuffer, actualBuffer)\n ) {\n return;\n }\n }\n\n throw new PaymentProviderError('Invalid Stripe webhook signature.');\n}\n\nfunction parseStripeWebhookPayload(payload: string): Record<string, unknown> {\n try {\n const event = JSON.parse(payload);\n\n if (!event || typeof event !== 'object' || Array.isArray(event)) {\n throw new PaymentProviderError('Invalid Stripe webhook JSON payload.');\n }\n\n return event as Record<string, unknown>;\n } catch (error) {\n if (error instanceof PaymentProviderError) {\n throw error;\n }\n\n throw new PaymentProviderError('Invalid Stripe webhook JSON payload.', {\n cause: error,\n });\n }\n}\n\nfunction normalizeOptionalWebhookString(\n value: string | undefined,\n): string | undefined {\n const normalized = value?.trim();\n\n return normalized ? normalized : undefined;\n}\n\nfunction normalizeOptionalProviderString(\n value: string | undefined,\n): string | undefined {\n const normalized = value?.trim();\n\n return normalized ? normalized : undefined;\n}\n\nfunction readProviderString(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const item = value[key];\n\n return typeof item === 'string' ? item : undefined;\n}\n\nfunction readRequiredWebhookString(\n value: Record<string, unknown>,\n key: string,\n context: string,\n): string {\n const item = value[key];\n\n if (typeof item !== 'string') {\n throw new PaymentProviderError(`${context} must be a string.`);\n }\n\n return normalizeNonEmptyString(item, context);\n}\n\nfunction readStripeSessionQuoteId(\n session: Record<string, unknown>,\n): string | undefined {\n return normalizeOptionalWebhookString(\n readString(session, 'client_reference_id') ??\n readString(\n (session.metadata as Record<string, unknown>) ?? {},\n 'quoteId',\n ),\n );\n}\n\nfunction mapStripeStatus(\n checkoutStatus: string | undefined,\n paymentStatus: string | undefined,\n): PaymentStatus {\n if (paymentStatus === 'paid' || paymentStatus === 'no_payment_required') {\n return 'confirmed';\n }\n\n if (checkoutStatus === 'expired') {\n return 'expired';\n }\n\n if (paymentStatus === 'unpaid' || checkoutStatus === 'open') {\n return 'pending';\n }\n\n if (checkoutStatus === 'complete') {\n return 'processing';\n }\n\n return 'pending';\n}\n\nfunction mapStripeWebhookStatus(\n type: string | undefined,\n object: Record<string, unknown> | undefined,\n): PaymentStatus {\n if (type === 'checkout.session.completed') {\n return mapStripeStatus(\n readString(object, 'status'),\n readString(object, 'payment_status'),\n );\n }\n\n if (type === 'checkout.session.async_payment_succeeded') {\n return 'confirmed';\n }\n\n if (type === 'checkout.session.async_payment_failed') {\n return 'failed';\n }\n\n if (type === 'checkout.session.expired') {\n return 'expired';\n }\n\n if (type?.includes('failed')) {\n return 'failed';\n }\n\n if (type?.includes('refunded')) {\n return 'refunded';\n }\n\n return 'processing';\n}\n\nfunction mapStripeRefundStatus(\n status: string | undefined,\n): RefundResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'succeeded';\n case 'failed':\n case 'canceled':\n return 'failed';\n case 'requires_action':\n return 'requires_action';\n default:\n return 'submitted';\n }\n}\n\nfunction extractStripeSessionId(payTo: string): string | undefined {\n if (/^cs_(test_|live_)?[A-Za-z0-9_]+$/.test(payTo)) {\n return payTo;\n }\n\n try {\n const url = new URL(payTo);\n const match = url.pathname.match(/\\/pay\\/([^/?#]+)/);\n\n const sessionId = match?.[1];\n\n return sessionId && /^cs_(test_|live_)?[A-Za-z0-9_]+$/.test(sessionId)\n ? sessionId\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction flattenStripeMetadata(\n metadata:\n | Record<string, string | number | boolean | null | undefined>\n | undefined,\n): Record<string, string | number | boolean> {\n const result: Record<string, string | number | boolean> = {};\n\n for (const [key, value] of Object.entries(metadata ?? {})) {\n if (value !== undefined && value !== null) {\n result[`metadata[${key}]`] = value;\n }\n }\n\n return result;\n}\n\nfunction readString(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const item = value[key];\n\n if (typeof item === 'string') {\n return item;\n }\n\n if (typeof item === 'number') {\n return String(item);\n }\n\n return undefined;\n}\n\nfunction readSafeInteger(\n value: Record<string, unknown> | undefined,\n key: string,\n): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const item = value[key];\n\n return typeof item === 'number' && Number.isSafeInteger(item) && item >= 0\n ? item\n : undefined;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stripe.js","sources":["../../src/adapters/stripe.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'node:crypto';\nimport {\n PaymentConfigurationError,\n PaymentProviderError,\n PaymentVerificationError,\n} from '../errors.js';\nimport {\n applyExpiryToPendingStatus,\n type FetchLike,\n formEncode,\n getFetch,\n normalizeDate,\n normalizeMaxStoredPaymentOptions,\n normalizeMinorUnitAmount,\n normalizeNonEmptyString,\n normalizePositiveMinorUnitAmount,\n normalizePositivePaymentAmount,\n normalizeUrlString,\n pollPaymentStatus,\n readJsonResponse,\n rememberPaymentOption,\n} from '../shared.js';\nimport type {\n AuthorizationResult,\n AuthorizePaymentInput,\n CapturePaymentInput,\n CaptureResult,\n CreatePaymentOptionInput,\n CreateSetupSessionInput,\n GetSetupResultInput,\n PaymentBackend,\n PaymentBackendCapabilities,\n PaymentEvent,\n PaymentOption,\n PaymentStatus,\n PaymentStatusContext,\n PaymentStatusResult,\n PaymentWebhookEvent,\n PayoutResult,\n RefundPaymentInput,\n RefundResult,\n SavedPaymentMethod,\n SendPayoutInput,\n SetupSession,\n VoidPaymentInput,\n VoidResult,\n WatchPaymentInput,\n} from '../types.js';\n\nexport const STRIPE_BACKEND_ID = 'stripe';\nconst STRIPE_CHECKOUT_MIN_EXPIRY_MS = 30 * 60 * 1_000;\nconst STRIPE_CHECKOUT_MAX_EXPIRY_MS = 24 * 60 * 60 * 1_000;\nconst DEFAULT_STRIPE_API_VERSION = '2024-06-20';\nconst DEFAULT_MAX_STORED_WEBHOOK_EVENT_IDS = 50_000;\n\nexport interface StripeAdapterOptions {\n secretKey: string;\n fetch?: FetchLike;\n apiBaseUrl?: string;\n apiVersion?: string;\n defaultCurrency?: string;\n supportedCurrencies?: string[];\n successUrl?: string;\n cancelUrl?: string;\n checkoutMode?: string;\n webhookSecret?: string;\n pollIntervalMs?: number;\n maxStoredPaymentOptions?: number;\n maxStoredWebhookEventIds?: number;\n}\n\nexport interface StripeWebhookEvent extends PaymentWebhookEvent {\n id: string;\n type: string;\n status: PaymentStatus;\n quoteId?: string;\n providerPaymentId?: string;\n raw: unknown;\n}\n\nexport class StripeAdapter implements PaymentBackend {\n readonly capabilities: PaymentBackendCapabilities;\n\n private readonly fetch: FetchLike;\n private readonly secretKey: string;\n private readonly apiBaseUrl: string;\n private readonly apiVersion: string;\n private readonly defaultCurrency: string;\n private readonly supportedCurrencies: Set<string>;\n private readonly checkoutMode: string;\n private readonly webhookSecret: string | undefined;\n private readonly maxStoredPaymentOptions: number;\n private readonly maxStoredWebhookEventIds: number;\n private readonly optionsByQuote = new Map<string, PaymentOption>();\n private readonly seenWebhookEventIds = new Set<string>();\n\n constructor(private readonly options: StripeAdapterOptions) {\n if (typeof options.secretKey !== 'string' || !options.secretKey.trim()) {\n throw new PaymentConfigurationError('StripeAdapter requires secretKey.');\n }\n\n if (options.webhookSecret !== undefined) {\n if (typeof options.webhookSecret !== 'string') {\n throw new PaymentConfigurationError(\n 'StripeAdapter webhookSecret must be a string when configured.',\n );\n }\n\n if (!options.webhookSecret.trim()) {\n throw new PaymentConfigurationError(\n 'StripeAdapter webhookSecret must not be empty when configured.',\n );\n }\n }\n\n if (options.apiBaseUrl !== undefined) {\n if (typeof options.apiBaseUrl !== 'string') {\n throw new PaymentConfigurationError(\n 'StripeAdapter apiBaseUrl must be a string when configured.',\n );\n }\n\n if (!options.apiBaseUrl.trim()) {\n throw new PaymentConfigurationError(\n 'StripeAdapter apiBaseUrl must not be empty when configured.',\n );\n }\n }\n\n this.fetch = getFetch(options.fetch);\n this.maxStoredPaymentOptions = normalizeMaxStoredPaymentOptions(\n options.maxStoredPaymentOptions,\n 'StripeAdapter maxStoredPaymentOptions',\n );\n this.maxStoredWebhookEventIds = normalizeMaxStoredPaymentOptions(\n options.maxStoredWebhookEventIds ?? DEFAULT_MAX_STORED_WEBHOOK_EVENT_IDS,\n 'StripeAdapter maxStoredWebhookEventIds',\n );\n this.secretKey = options.secretKey.trim();\n this.apiBaseUrl = normalizeUrlString(\n options.apiBaseUrl ?? 'https://api.stripe.com/v1',\n 'StripeAdapter apiBaseUrl',\n ).replace(/\\/$/, '');\n this.apiVersion = normalizeNonEmptyString(\n options.apiVersion ?? DEFAULT_STRIPE_API_VERSION,\n 'StripeAdapter apiVersion',\n );\n this.defaultCurrency = normalizeStripeCurrency(\n options.defaultCurrency ?? 'usd',\n );\n this.supportedCurrencies = normalizeSupportedStripeCurrencies(\n options.supportedCurrencies,\n this.defaultCurrency,\n );\n this.checkoutMode = options.checkoutMode ?? 'payment';\n\n if (this.checkoutMode !== 'payment') {\n throw new PaymentConfigurationError(\n 'StripeAdapter only supports payment Checkout mode.',\n );\n }\n\n this.webhookSecret = options.webhookSecret?.trim();\n this.capabilities = {\n id: STRIPE_BACKEND_ID,\n displayName: 'Stripe Checkout',\n settlementCurrency: this.defaultCurrency.toUpperCase(),\n supportedSettlementCurrencies: [...this.supportedCurrencies].map(\n (currency) => currency.toUpperCase(),\n ),\n chain: 'stripe',\n settlementShape: 'url',\n x402Capable: false,\n confirmationLatency: {\n expectedSeconds: 5,\n maxExpectedSeconds: 600,\n description:\n 'Card payments usually confirm in seconds; bank debits can remain processing while Stripe settles them.',\n },\n supportsRefunds: true,\n supportsPayouts: true,\n supportsWebhooks: true,\n supportsManualCapture: true,\n supportsSavedPaymentMethods: true,\n metadata: {\n provider: 'stripe',\n },\n };\n }\n\n async createPaymentOption(\n input: CreatePaymentOptionInput,\n ): Promise<PaymentOption> {\n const quoteId = normalizeNonEmptyString(input.quoteId, 'Stripe quoteId');\n const rawSuccessUrl = input.successUrl ?? this.options.successUrl;\n const rawCancelUrl = input.cancelUrl ?? this.options.cancelUrl;\n\n if (rawSuccessUrl === undefined || rawCancelUrl === undefined) {\n throw new PaymentConfigurationError(\n 'StripeAdapter createPaymentOption requires successUrl and cancelUrl.',\n );\n }\n\n const successUrl = normalizeUrlString(rawSuccessUrl, 'Stripe successUrl');\n const cancelUrl = normalizeUrlString(rawCancelUrl, 'Stripe cancelUrl');\n const currency = normalizeStripeCurrency(input.currency);\n this.assertSupportedCurrency(currency);\n const amount = normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe Checkout amount',\n );\n const expiresAt = normalizeDate(input.expiresAt);\n const stripeExpiresAt = normalizeStripeCheckoutExpiresAt(expiresAt);\n const params: Record<string, unknown> = {\n mode: this.checkoutMode,\n ...Object.fromEntries([\n ['success_url', successUrl],\n ['cancel_url', cancelUrl],\n ['client_reference_id', quoteId],\n ['customer_email', input.buyerEmail],\n ['expires_at', Math.floor(stripeExpiresAt.getTime() / 1_000)],\n ]),\n 'line_items[0][quantity]': 1,\n 'line_items[0][price_data][currency]': currency,\n 'line_items[0][price_data][unit_amount]': amount,\n 'line_items[0][price_data][product_data][name]':\n input.description ?? `Quote ${quoteId}`,\n ...flattenStripeMetadata(input.metadata),\n 'metadata[quoteId]': quoteId,\n };\n\n const session = await this.stripeRequest<Record<string, unknown>>(\n '/checkout/sessions',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode(params),\n },\n );\n const sessionId = normalizeOptionalProviderString(\n readProviderString(session, 'id'),\n );\n const checkoutUrl = normalizeOptionalProviderString(\n readProviderString(session, 'url'),\n );\n\n if (!sessionId || !checkoutUrl) {\n throw new PaymentProviderError(\n 'Stripe Checkout Session response did not include id and url.',\n );\n }\n\n const option: PaymentOption = {\n backendId: this.capabilities.id,\n quoteId,\n payTo: checkoutUrl,\n settlementShape: 'url',\n settlementCurrency: currency.toUpperCase(),\n settlementAmount: amount,\n amount,\n currency: currency.toUpperCase(),\n expiresAt: stripeExpiresAt,\n providerPaymentId: sessionId,\n paymentUri: checkoutUrl,\n metadata: {\n sessionId,\n paymentIntent: normalizeOptionalProviderString(\n readProviderString(session, 'payment_intent'),\n ),\n },\n };\n\n rememberPaymentOption(\n this.optionsByQuote,\n quoteId,\n option,\n this.maxStoredPaymentOptions,\n );\n\n return option;\n }\n\n watchPayment(input: WatchPaymentInput): AsyncIterable<PaymentEvent> {\n return pollPaymentStatus(\n {\n ...input,\n pollIntervalMs:\n input.pollIntervalMs ?? this.options.pollIntervalMs ?? 5_000,\n },\n () => this.getStatus(input.quoteId, input.payTo, input.statusContext),\n );\n }\n\n async getStatus(\n quoteId: string,\n payTo: string,\n context: PaymentStatusContext = {},\n ): Promise<PaymentStatusResult> {\n const normalizedQuoteId = normalizeNonEmptyString(\n quoteId,\n 'Stripe quoteId',\n );\n const normalizedPayTo = normalizeNonEmptyString(payTo, 'Stripe payTo');\n const contextProviderPaymentId =\n context.providerPaymentId === undefined\n ? undefined\n : normalizeNonEmptyString(\n context.providerPaymentId,\n 'Stripe providerPaymentId',\n );\n const sessionId =\n this.optionsByQuote.get(normalizedQuoteId)?.providerPaymentId ??\n contextProviderPaymentId ??\n extractStripeSessionId(normalizedPayTo);\n\n if (!sessionId) {\n throw new PaymentConfigurationError(\n 'Stripe getStatus requires a Checkout Session id or URL.',\n );\n }\n\n const session = await this.stripeRequest<Record<string, unknown>>(\n `/checkout/sessions/${encodeURIComponent(sessionId)}`,\n );\n const sessionQuoteId = readStripeSessionQuoteId(session);\n\n if (sessionQuoteId !== undefined && sessionQuoteId !== normalizedQuoteId) {\n throw new PaymentVerificationError(\n `Stripe Checkout Session quoteId ${sessionQuoteId} did not match ${normalizedQuoteId}.`,\n );\n }\n\n const paymentStatus = readString(session, 'payment_status');\n const status = mapStripeStatus(\n readString(session, 'status'),\n paymentStatus,\n );\n\n const option = this.optionsByQuote.get(normalizedQuoteId);\n const contextAmount =\n context.amount === undefined\n ? undefined\n : normalizeMinorUnitAmount(context.amount, 'Stripe status');\n const contextCurrency =\n context.currency === undefined\n ? undefined\n : normalizeStripeCurrency(context.currency).toUpperCase();\n const sessionCurrency =\n readString(session, 'currency') === undefined\n ? undefined\n : normalizeStripeCurrency(\n readString(session, 'currency') ?? '',\n ).toUpperCase();\n const sessionAmount = readSafeInteger(session, 'amount_total');\n const expiresAt =\n option?.expiresAt ??\n (context.expiresAt === undefined\n ? undefined\n : normalizeDate(context.expiresAt));\n const effectiveStatus = applyExpiryToPendingStatus(status, expiresAt);\n\n return {\n backendId: this.capabilities.id,\n quoteId: normalizedQuoteId,\n payTo: normalizedPayTo,\n status: effectiveStatus,\n settlementCurrency:\n sessionCurrency ??\n option?.settlementCurrency ??\n contextCurrency ??\n this.defaultCurrency.toUpperCase(),\n settlementAmount:\n sessionAmount ?? option?.settlementAmount ?? contextAmount,\n receivedAmount:\n paymentStatus === 'paid' || paymentStatus === 'no_payment_required'\n ? (sessionAmount ?? option?.settlementAmount ?? contextAmount)\n : undefined,\n amount: option?.amount ?? contextAmount,\n currency: option?.currency ?? contextCurrency,\n providerPaymentId: sessionId,\n transactionId: normalizeOptionalProviderString(\n readProviderString(session, 'payment_intent'),\n ),\n updatedAt: new Date(),\n raw: session,\n };\n }\n\n async sendPayout(input: SendPayoutInput): Promise<PayoutResult> {\n const currency = normalizeStripeCurrency(\n input.currency ?? this.defaultCurrency,\n );\n this.assertSupportedCurrency(currency);\n const destination = normalizeNonEmptyString(\n input.destination,\n 'Stripe payout destination',\n );\n const quoteId =\n input.quoteId === undefined\n ? undefined\n : normalizeNonEmptyString(input.quoteId, 'Stripe payout quoteId');\n const amount = normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe payout amount',\n );\n const transfer = await this.stripeRequest<Record<string, unknown>>(\n '/transfers',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode({\n amount,\n currency,\n destination,\n description: input.memo,\n ...flattenStripeMetadata(input.metadata),\n ...(quoteId === undefined ? {} : { 'metadata[quoteId]': quoteId }),\n }),\n },\n );\n\n return {\n backendId: this.capabilities.id,\n status: 'submitted',\n payoutId: normalizeOptionalProviderString(\n readProviderString(transfer, 'id'),\n ),\n destination,\n amount,\n currency: currency.toUpperCase(),\n raw: transfer,\n };\n }\n\n async refundPayment(input: RefundPaymentInput): Promise<RefundResult> {\n const rawPaymentReference = input.paymentId ?? input.transactionId;\n\n if (!rawPaymentReference) {\n throw new PaymentConfigurationError(\n 'Stripe refunds require paymentId or transactionId.',\n );\n }\n\n const paymentReference = normalizeNonEmptyString(\n rawPaymentReference,\n 'Stripe refund payment reference',\n );\n const currency = normalizeStripeCurrency(\n input.currency ?? this.defaultCurrency,\n );\n this.assertSupportedCurrency(currency);\n const amount =\n input.amount === undefined\n ? undefined\n : normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe refund amount',\n );\n const refundReferenceParam =\n await this.resolveStripeRefundReferenceParam(paymentReference);\n const refundParams: Record<string, unknown> = {\n ...refundReferenceParam,\n amount: amount === undefined ? undefined : amount,\n reason: input.reason,\n ...flattenStripeMetadata(input.metadata),\n };\n\n const refund = await this.stripeRequest<Record<string, unknown>>(\n '/refunds',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode(refundParams),\n },\n );\n\n return {\n backendId: this.capabilities.id,\n status: mapStripeRefundStatus(readString(refund, 'status')),\n refundId: normalizeOptionalProviderString(\n readProviderString(refund, 'id'),\n ),\n transactionId: paymentReference,\n amount,\n currency: currency.toUpperCase(),\n raw: refund,\n };\n }\n\n async authorizePayment(\n input: AuthorizePaymentInput,\n ): Promise<AuthorizationResult> {\n const currency = normalizeStripeCurrency(input.currency);\n this.assertSupportedCurrency(currency);\n const amount = normalizePositivePaymentAmount(\n input.amount,\n currency,\n 'Stripe authorize amount',\n );\n const paymentMethod = normalizeNonEmptyString(\n input.providerPaymentMethodId,\n 'Stripe authorize providerPaymentMethodId',\n );\n const providerCustomerId =\n input.providerCustomerId === undefined\n ? undefined\n : normalizeNonEmptyString(\n input.providerCustomerId,\n 'Stripe authorize providerCustomerId',\n );\n const quoteId =\n input.quoteId === undefined\n ? undefined\n : normalizeNonEmptyString(input.quoteId, 'Stripe authorize quoteId');\n\n const intent = await this.stripeRequest<Record<string, unknown>>(\n '/payment_intents',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode({\n amount,\n currency,\n confirm: true,\n 'payment_method_types[]': 'card',\n description: input.description,\n ...Object.fromEntries([\n ['payment_method', paymentMethod],\n ['capture_method', 'manual'],\n // Off-session (merchant-initiated) by default — the primary use is\n // charging a saved card while the buyer is absent. Without this,\n // Stripe treats it as on-session and may raise an SCA challenge the\n // absent buyer can't complete, so the hold is never placed.\n ['off_session', input.offSession ?? true],\n ]),\n ...(providerCustomerId === undefined\n ? {}\n : { customer: providerCustomerId }),\n ...flattenStripeMetadata(input.metadata),\n ...(quoteId === undefined ? {} : { 'metadata[quoteId]': quoteId }),\n }),\n },\n );\n\n const providerPaymentId = normalizeOptionalProviderString(\n readProviderString(intent, 'id'),\n );\n\n if (!providerPaymentId) {\n throw new PaymentProviderError(\n 'Stripe PaymentIntent response did not include an id.',\n );\n }\n\n const status = mapStripeAuthorizationStatus(readString(intent, 'status'));\n // Only surface the SCA fields when authentication is actually required — the\n // documented contract — even though Stripe returns client_secret regardless.\n // (Authorization progress is observed via `parseWebhookEvent`, which surfaces\n // the ready-to-capture transition as `processing` — there is no distinct\n // `requires_capture` webhook status; `getStatus` handles Checkout sessions,\n // not PaymentIntents.)\n const actionRequired = status === 'requires_action';\n\n return {\n backendId: this.capabilities.id,\n status,\n providerPaymentId,\n amount: readSafeInteger(intent, 'amount') ?? amount,\n currency: (readString(intent, 'currency') ?? currency).toUpperCase(),\n clientSecret: actionRequired\n ? normalizeOptionalProviderString(\n readProviderString(intent, 'client_secret'),\n )\n : undefined,\n nextAction: actionRequired\n ? (intent.next_action ?? undefined)\n : undefined,\n raw: intent,\n };\n }\n\n async capturePayment(input: CapturePaymentInput): Promise<CaptureResult> {\n const providerPaymentId = normalizeNonEmptyString(\n input.providerPaymentId,\n 'Stripe capture providerPaymentId',\n );\n const amount =\n input.amount === undefined\n ? undefined\n : normalizePositiveMinorUnitAmount(\n input.amount,\n 'Stripe capture amount',\n );\n\n const intent = await this.stripeRequest<Record<string, unknown>>(\n `/payment_intents/${encodeURIComponent(providerPaymentId)}/capture`,\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode({\n ...Object.fromEntries([['amount_to_capture', amount]]),\n ...flattenStripeMetadata(input.metadata),\n }),\n },\n );\n\n return {\n backendId: this.capabilities.id,\n status: mapStripeCaptureStatus(readString(intent, 'status')),\n providerPaymentId:\n normalizeOptionalProviderString(readProviderString(intent, 'id')) ??\n providerPaymentId,\n amount:\n readSafeInteger(intent, 'amount_received') ??\n readSafeInteger(intent, 'amount') ??\n amount,\n currency: readStripeResultCurrency(intent),\n raw: intent,\n };\n }\n\n async voidPayment(input: VoidPaymentInput): Promise<VoidResult> {\n const providerPaymentId = normalizeNonEmptyString(\n input.providerPaymentId,\n 'Stripe void providerPaymentId',\n );\n const reason =\n input.reason === undefined\n ? undefined\n : normalizeNonEmptyString(input.reason, 'Stripe void reason');\n\n const intent = await this.stripeRequest<Record<string, unknown>>(\n `/payment_intents/${encodeURIComponent(providerPaymentId)}/cancel`,\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode(Object.fromEntries([['cancellation_reason', reason]])),\n },\n );\n\n return {\n backendId: this.capabilities.id,\n status: mapStripeVoidStatus(readString(intent, 'status')),\n providerPaymentId:\n normalizeOptionalProviderString(readProviderString(intent, 'id')) ??\n providerPaymentId,\n amount: readSafeInteger(intent, 'amount'),\n currency: readStripeResultCurrency(intent),\n raw: intent,\n };\n }\n\n async createSetupSession(\n input: CreateSetupSessionInput,\n ): Promise<SetupSession> {\n const rawSuccessUrl = input.successUrl ?? this.options.successUrl;\n const rawCancelUrl = input.cancelUrl ?? this.options.cancelUrl;\n\n if (rawSuccessUrl === undefined || rawCancelUrl === undefined) {\n throw new PaymentConfigurationError(\n 'StripeAdapter createSetupSession requires successUrl and cancelUrl.',\n );\n }\n\n const successUrl = normalizeUrlString(rawSuccessUrl, 'Stripe successUrl');\n const cancelUrl = normalizeUrlString(rawCancelUrl, 'Stripe cancelUrl');\n // Currency for the setup-mode session (defaults to the backend currency).\n // Redundant now that payment_method_types is always set, but harmless and\n // kept so the session is well-formed if that restriction is ever relaxed.\n const currency = normalizeStripeCurrency(\n input.currency ?? this.defaultCurrency,\n );\n this.assertSupportedCurrency(currency);\n const providerCustomerId =\n input.providerCustomerId === undefined\n ? undefined\n : normalizeNonEmptyString(\n input.providerCustomerId,\n 'Stripe setup customer',\n );\n\n // Either attach to an existing customer, or force Stripe to create one so\n // the saved method comes back with a reusable `cus_` reference. Setup-mode\n // sessions do NOT create a customer on their own — `customer_creation` must\n // be `always`. All snake_case keys go through Object.fromEntries.\n const customerParams: [string, unknown][] = [];\n if (providerCustomerId !== undefined) {\n customerParams.push(['customer', providerCustomerId]);\n } else {\n customerParams.push(['customer_creation', 'always']);\n if (input.customerEmail !== undefined) {\n customerParams.push([\n 'customer_email',\n normalizeNonEmptyString(\n input.customerEmail,\n 'Stripe setup customerEmail',\n ),\n ]);\n }\n }\n\n const params: Record<string, unknown> = {\n mode: 'setup',\n currency,\n // Restrict to cards: SavedPaymentMethod exposes card display fields\n // (brand/last4/expiry), so allowing SEPA/Bacs/etc. would yield saved\n // methods with no usable display detail.\n 'payment_method_types[]': 'card',\n ...Object.fromEntries([\n ['success_url', successUrl],\n ['cancel_url', cancelUrl],\n ...customerParams,\n ]),\n ...flattenStripeMetadata(input.metadata),\n };\n\n const session = await this.stripeRequest<Record<string, unknown>>(\n '/checkout/sessions',\n {\n method: 'POST',\n idempotencyKey: input.idempotencyKey,\n body: formEncode(params),\n },\n );\n\n const sessionId = normalizeOptionalProviderString(\n readProviderString(session, 'id'),\n );\n const url = normalizeOptionalProviderString(\n readProviderString(session, 'url'),\n );\n\n if (!sessionId || !url) {\n throw new PaymentProviderError(\n 'Stripe setup Checkout Session response did not include id and url.',\n );\n }\n\n return {\n backendId: this.capabilities.id,\n sessionId,\n url,\n providerCustomerId:\n providerCustomerId ??\n normalizeOptionalProviderString(\n readProviderString(session, 'customer'),\n ),\n raw: session,\n };\n }\n\n async getSetupResult(\n input: GetSetupResultInput,\n ): Promise<SavedPaymentMethod> {\n const sessionId = normalizeNonEmptyString(\n input.sessionId,\n 'Stripe setup sessionId',\n );\n\n const query = new URLSearchParams();\n query.append('expand[]', 'setup_intent.payment_method');\n\n const session = await this.stripeRequest<Record<string, unknown>>(\n `/checkout/sessions/${encodeURIComponent(sessionId)}?${query.toString()}`,\n );\n\n const setupIntent = readObject(session, 'setup_intent');\n const paymentMethod = readObject(setupIntent, 'payment_method');\n const card = readObject(paymentMethod, 'card');\n\n // `customer` is a bare `cus_` string on the request path (only\n // setup_intent.payment_method is expanded), but read tolerantly of an\n // expanded object so a future `expand[]=customer` can't wrongly downgrade a\n // completed setup to a permanent `pending`.\n const providerCustomerId = normalizeOptionalProviderString(\n readProviderString(session, 'customer') ??\n readProviderString(readObject(session, 'customer'), 'id'),\n );\n const providerPaymentMethodId = normalizeOptionalProviderString(\n readProviderString(paymentMethod, 'id'),\n );\n\n let status = mapStripeSetupStatus(\n readString(session, 'status'),\n readString(setupIntent, 'status'),\n );\n // Never report `complete` without the reusable references a caller needs to\n // charge the method later — a `pm_` with no `cus_` can't be charged\n // off-session, so treat that as not-yet-ready rather than a false success.\n if (\n status === 'complete' &&\n (!providerCustomerId || !providerPaymentMethodId)\n ) {\n status = 'pending';\n }\n\n return {\n backendId: this.capabilities.id,\n status,\n providerCustomerId,\n providerPaymentMethodId,\n type: readString(paymentMethod, 'type'),\n brand: readString(card, 'brand'),\n last4: readString(card, 'last4'),\n expMonth: readSafeInteger(card, 'exp_month'),\n expYear: readSafeInteger(card, 'exp_year'),\n raw: session,\n };\n }\n\n parseWebhookEvent(payload: string, signature?: string): StripeWebhookEvent {\n if (!this.webhookSecret) {\n throw new PaymentConfigurationError(\n 'StripeAdapter parseWebhookEvent requires webhookSecret.',\n );\n }\n\n if (!signature) {\n throw new PaymentProviderError('Missing Stripe webhook signature.');\n }\n\n verifyStripeWebhookSignature(payload, signature, this.webhookSecret);\n\n const event = parseStripeWebhookPayload(payload);\n const id = readRequiredWebhookString(\n event,\n 'id',\n 'Stripe webhook event id',\n );\n const type = readRequiredWebhookString(\n event,\n 'type',\n 'Stripe webhook event type',\n );\n\n const duplicate = this.seenWebhookEventIds.has(id);\n\n if (!duplicate) {\n this.seenWebhookEventIds.add(id);\n while (this.seenWebhookEventIds.size > this.maxStoredWebhookEventIds) {\n const oldest = this.seenWebhookEventIds.values().next().value;\n\n if (oldest === undefined) {\n break;\n }\n\n this.seenWebhookEventIds.delete(oldest);\n }\n }\n\n const data = (\n event.data as { object?: Record<string, unknown> } | undefined\n )?.object;\n\n return {\n id,\n type,\n status: mapStripeWebhookStatus(type, data),\n quoteId: normalizeOptionalWebhookString(\n // `client_reference_id` is a Checkout Session-only field; honor it only\n // for session events so a non-session object (a PaymentIntent / Charge /\n // Transfer, possibly from a malicious Connect account) can't spoof\n // correlation to another quote's id. Non-session events correlate only\n // via our own `metadata.quoteId`.\n (type.startsWith('checkout.session.')\n ? readString(data, 'client_reference_id')\n : undefined) ??\n readString(\n (data?.metadata as Record<string, unknown>) ?? {},\n 'quoteId',\n ),\n ),\n providerPaymentId: normalizeOptionalWebhookString(readString(data, 'id')),\n duplicate,\n raw: event,\n };\n }\n\n private async stripeRequest<T>(\n path: string,\n init: RequestInit & { idempotencyKey?: string } = {},\n ): Promise<T> {\n const headers = new Headers(init.headers);\n headers.set('Authorization', `Bearer ${this.secretKey}`);\n headers.set('Content-Type', 'application/x-www-form-urlencoded');\n headers.set('Accept', 'application/json');\n headers.set('Stripe-Version', this.apiVersion);\n\n if (init.idempotencyKey !== undefined) {\n headers.set(\n 'Idempotency-Key',\n normalizeNonEmptyString(init.idempotencyKey, 'Stripe idempotencyKey'),\n );\n }\n\n const { idempotencyKey: _idempotencyKey, ...requestInit } = init;\n const response = await this.fetch(`${this.apiBaseUrl}${path}`, {\n ...requestInit,\n method: init.method ?? 'GET',\n headers,\n });\n\n return readJsonResponse<T>(response, `Stripe ${path}`);\n }\n\n private assertSupportedCurrency(currency: string): void {\n if (!this.supportedCurrencies.has(currency)) {\n throw new PaymentConfigurationError(\n `StripeAdapter currency ${currency.toUpperCase()} is not configured as supported.`,\n );\n }\n }\n\n private async resolveStripeRefundReferenceParam(\n paymentReference: string,\n ): Promise<Record<string, string>> {\n if (paymentReference.startsWith('cs_')) {\n const session = await this.stripeRequest<Record<string, unknown>>(\n `/checkout/sessions/${encodeURIComponent(paymentReference)}`,\n );\n const paymentIntent = normalizeOptionalProviderString(\n readProviderString(session, 'payment_intent'),\n );\n\n if (!paymentIntent) {\n throw new PaymentProviderError(\n 'Stripe Checkout Session did not include payment_intent for refund.',\n );\n }\n\n return Object.fromEntries([['payment_intent', paymentIntent]]);\n }\n\n return stripeRefundReferenceParam(paymentReference);\n }\n}\n\nfunction stripeRefundReferenceParam(\n paymentReference: string,\n): Record<string, string> {\n if (paymentReference.startsWith('pi_')) {\n return Object.fromEntries([['payment_intent', paymentReference]]);\n }\n\n if (paymentReference.startsWith('ch_')) {\n return { charge: paymentReference };\n }\n\n throw new PaymentConfigurationError(\n 'Stripe refunds require a Checkout Session (cs_), payment_intent (pi_), or charge (ch_) reference.',\n );\n}\n\nfunction normalizeStripeCurrency(value: string): string {\n if (typeof value !== 'string') {\n throw new PaymentConfigurationError(\n `StripeAdapter currency must be a three-letter ISO currency code, received ${String(value)}.`,\n );\n }\n\n const normalized = value.trim().toLowerCase();\n\n if (!/^[a-z]{3}$/.test(normalized)) {\n throw new PaymentConfigurationError(\n `StripeAdapter currency must be a three-letter ISO currency code, received ${String(value)}.`,\n );\n }\n\n return normalized;\n}\n\nfunction normalizeSupportedStripeCurrencies(\n configuredCurrencies: string[] | undefined,\n defaultCurrency: string,\n): Set<string> {\n const normalized = new Set(\n (configuredCurrencies ?? ['usd', 'eur', 'gbp', 'cad']).map(\n normalizeStripeCurrency,\n ),\n );\n normalized.add(defaultCurrency);\n\n return normalized;\n}\n\nfunction normalizeStripeCheckoutExpiresAt(\n expiresAt: Date,\n now = Date.now(),\n): Date {\n if (expiresAt.getTime() <= now) {\n throw new PaymentProviderError('Stripe Checkout expiry is in the past.');\n }\n\n const min = now + STRIPE_CHECKOUT_MIN_EXPIRY_MS;\n const max = now + STRIPE_CHECKOUT_MAX_EXPIRY_MS;\n\n if (expiresAt.getTime() < min || expiresAt.getTime() > max) {\n throw new PaymentConfigurationError(\n 'Stripe Checkout expiry must be at least 30 minutes and no more than 24 hours from now.',\n );\n }\n\n return expiresAt;\n}\n\nexport function verifyStripeWebhookSignature(\n payload: string,\n signatureHeader: string,\n secret: string,\n toleranceSeconds = 300,\n): void {\n if (typeof payload !== 'string') {\n throw new PaymentProviderError('Stripe webhook payload must be a string.');\n }\n\n const normalizedSignatureHeader = normalizeNonEmptyString(\n signatureHeader,\n 'Stripe signature header',\n );\n const normalizedSecret = normalizeNonEmptyString(\n secret,\n 'Stripe webhook secret',\n );\n\n if (!Number.isFinite(toleranceSeconds) || toleranceSeconds < 0) {\n throw new PaymentConfigurationError(\n `Stripe webhook toleranceSeconds must be a non-negative finite number, received ${String(toleranceSeconds)}.`,\n );\n }\n\n const timestampCandidates: string[] = [];\n const signatures: string[] = [];\n\n for (const part of normalizedSignatureHeader.split(',')) {\n const [rawKey, ...rawValue] = part.split('=');\n const key = rawKey?.trim();\n const value = rawValue.join('=').trim();\n\n if (!key || !value) {\n continue;\n }\n\n if (key === 't') {\n timestampCandidates.push(value);\n }\n\n if (key === 'v1') {\n signatures.push(value);\n }\n }\n\n if (timestampCandidates.length !== 1 || signatures.length === 0) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const timestamp = timestampCandidates[0] ?? '';\n\n if (!/^\\d+$/.test(timestamp)) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const timestampSeconds = Number(timestamp);\n\n if (!Number.isSafeInteger(timestampSeconds)) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const nowSeconds = Date.now() / 1_000;\n const ageSeconds = nowSeconds - timestampSeconds;\n\n if (ageSeconds < -5) {\n throw new PaymentProviderError(\n 'Stripe webhook signature timestamp is in the future.',\n );\n }\n\n if (ageSeconds > toleranceSeconds) {\n throw new PaymentProviderError('Stripe webhook signature is too old.');\n }\n\n const expected = createHmac('sha256', normalizedSecret)\n .update(`${timestamp}.${payload}`)\n .digest('hex');\n const expectedBuffer = Buffer.from(expected, 'hex');\n\n for (const signature of signatures) {\n if (!/^[0-9a-f]+$/i.test(signature)) {\n throw new PaymentProviderError('Invalid Stripe signature header.');\n }\n\n const actualBuffer = Buffer.from(signature, 'hex');\n\n if (\n expectedBuffer.length === actualBuffer.length &&\n timingSafeEqual(expectedBuffer, actualBuffer)\n ) {\n return;\n }\n }\n\n throw new PaymentProviderError('Invalid Stripe webhook signature.');\n}\n\nfunction parseStripeWebhookPayload(payload: string): Record<string, unknown> {\n try {\n const event = JSON.parse(payload);\n\n if (!event || typeof event !== 'object' || Array.isArray(event)) {\n throw new PaymentProviderError('Invalid Stripe webhook JSON payload.');\n }\n\n return event as Record<string, unknown>;\n } catch (error) {\n if (error instanceof PaymentProviderError) {\n throw error;\n }\n\n throw new PaymentProviderError('Invalid Stripe webhook JSON payload.', {\n cause: error,\n });\n }\n}\n\nfunction normalizeOptionalWebhookString(\n value: string | undefined,\n): string | undefined {\n const normalized = value?.trim();\n\n return normalized ? normalized : undefined;\n}\n\nfunction normalizeOptionalProviderString(\n value: string | undefined,\n): string | undefined {\n const normalized = value?.trim();\n\n return normalized ? normalized : undefined;\n}\n\nfunction readProviderString(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const item = value[key];\n\n return typeof item === 'string' ? item : undefined;\n}\n\nfunction readRequiredWebhookString(\n value: Record<string, unknown>,\n key: string,\n context: string,\n): string {\n const item = value[key];\n\n if (typeof item !== 'string') {\n throw new PaymentProviderError(`${context} must be a string.`);\n }\n\n return normalizeNonEmptyString(item, context);\n}\n\nfunction readStripeSessionQuoteId(\n session: Record<string, unknown>,\n): string | undefined {\n return normalizeOptionalWebhookString(\n readString(session, 'client_reference_id') ??\n readString(\n (session.metadata as Record<string, unknown>) ?? {},\n 'quoteId',\n ),\n );\n}\n\nfunction mapStripeStatus(\n checkoutStatus: string | undefined,\n paymentStatus: string | undefined,\n): PaymentStatus {\n if (paymentStatus === 'paid' || paymentStatus === 'no_payment_required') {\n return 'confirmed';\n }\n\n if (checkoutStatus === 'expired') {\n return 'expired';\n }\n\n if (paymentStatus === 'unpaid' || checkoutStatus === 'open') {\n return 'pending';\n }\n\n if (checkoutStatus === 'complete') {\n return 'processing';\n }\n\n return 'pending';\n}\n\nfunction mapStripeWebhookStatus(\n type: string | undefined,\n object: Record<string, unknown> | undefined,\n): PaymentStatus {\n if (type === 'checkout.session.completed') {\n return mapStripeStatus(\n readString(object, 'status'),\n readString(object, 'payment_status'),\n );\n }\n\n if (type === 'checkout.session.async_payment_succeeded') {\n return 'confirmed';\n }\n\n if (type === 'checkout.session.async_payment_failed') {\n return 'failed';\n }\n\n if (type === 'checkout.session.expired') {\n return 'expired';\n }\n\n // Manual-capture PaymentIntent lifecycle (authorize → capture / void). Only\n // treat these as terminal for intents WE created and can correlate — i.e.\n // ones carrying our `quoteId` in metadata. Checkout Sessions create their own\n // PaymentIntents (which fire these same events with no quoteId on the intent);\n // those are handled via the `checkout.session.*` events above, so here they\n // stay non-terminal (`processing`) rather than emitting a spurious,\n // uncorrelatable terminal event. Handled before the generic `failed` catch\n // below so an un-owned `payment_intent.payment_failed` isn't reclassified.\n if (\n type === 'payment_intent.succeeded' ||\n type === 'payment_intent.canceled' ||\n type === 'payment_intent.payment_failed'\n ) {\n const metadata = (object?.metadata as Record<string, unknown>) ?? {};\n // Match parseWebhookEvent's normalization so an empty/blank quoteId is\n // treated as un-owned by both — gate and reporter must agree on ownership.\n const owned =\n normalizeOptionalWebhookString(readString(metadata, 'quoteId')) !==\n undefined;\n if (owned) {\n if (type === 'payment_intent.succeeded') {\n return 'confirmed';\n }\n // A manual-capture hold Stripe released automatically (it lapsed) is\n // `expired`, distinct from a deliberate void or hard decline (`failed`);\n // the shared PaymentStatus union has no `canceled`.\n if (\n type === 'payment_intent.canceled' &&\n readString(object, 'cancellation_reason') === 'automatic'\n ) {\n return 'expired';\n }\n return 'failed';\n }\n return 'processing';\n }\n\n // Terminal failure/refund only for payment-in objects (Checkout Session,\n // PaymentIntent, Charge). Money-out / unrelated events (transfer.failed,\n // payout.failed, refund.failed, application_fee.refunded, …) also match a\n // naive substring scan — and a failed Transfer even carries our quoteId\n // (sendPayout stamps it), which would miscorrelate a payout failure as a\n // payment failure — so they must not surface as a terminal payment status.\n const isPaymentInEvent =\n type?.startsWith('checkout.session.') === true ||\n type?.startsWith('payment_intent.') === true ||\n type?.startsWith('charge.') === true;\n\n if (isPaymentInEvent && type?.includes('refunded')) {\n return 'refunded';\n }\n\n if (isPaymentInEvent && type?.includes('failed')) {\n return 'failed';\n }\n\n return 'processing';\n}\n\nfunction mapStripeRefundStatus(\n status: string | undefined,\n): RefundResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'succeeded';\n case 'failed':\n case 'canceled':\n return 'failed';\n case 'requires_action':\n return 'requires_action';\n default:\n return 'submitted';\n }\n}\n\nfunction mapStripeAuthorizationStatus(\n status: string | undefined,\n): AuthorizationResult['status'] {\n switch (status) {\n case 'requires_capture':\n return 'requires_capture';\n case 'succeeded':\n return 'succeeded';\n case 'requires_action':\n return 'requires_action';\n case 'processing':\n return 'processing';\n default:\n return 'failed';\n }\n}\n\nfunction mapStripeCaptureStatus(\n status: string | undefined,\n): CaptureResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'succeeded';\n // Capturing an authorized intent shouldn't re-enter authentication; treat\n // any in-flight/action state as still processing rather than a failure.\n case 'processing':\n case 'requires_action':\n return 'processing';\n default:\n return 'failed';\n }\n}\n\nfunction mapStripeVoidStatus(status: string | undefined): VoidResult['status'] {\n return status === 'canceled' ? 'canceled' : 'failed';\n}\n\nfunction readStripeResultCurrency(\n value: Record<string, unknown>,\n): string | undefined {\n const currency = readString(value, 'currency');\n\n return currency === undefined ? undefined : currency.toUpperCase();\n}\n\nfunction mapStripeSetupStatus(\n sessionStatus: string | undefined,\n setupIntentStatus: string | undefined,\n): SavedPaymentMethod['status'] {\n if (sessionStatus === 'expired') {\n return 'expired';\n }\n\n if (sessionStatus === 'complete') {\n // The method is reusable only once the SetupIntent itself has succeeded —\n // the Session can be `complete` while the intent is still `processing`\n // (async setup methods via dynamic payment methods).\n if (setupIntentStatus === 'succeeded') {\n return 'complete';\n }\n // A finished session whose SetupIntent didn't succeed is a terminal\n // failure (card declined → `requires_payment_method`, or `canceled`), so\n // callers can stop polling instead of waiting on a `pending` that will\n // never resolve. Still-in-flight states (`processing`, `requires_action`)\n // remain `pending`.\n if (\n setupIntentStatus === 'canceled' ||\n setupIntentStatus === 'requires_payment_method'\n ) {\n return 'failed';\n }\n }\n\n return 'pending';\n}\n\nfunction readObject(\n value: Record<string, unknown> | undefined,\n key: string,\n): Record<string, unknown> | undefined {\n const item = value?.[key];\n\n return item && typeof item === 'object' && !Array.isArray(item)\n ? (item as Record<string, unknown>)\n : undefined;\n}\n\nfunction extractStripeSessionId(payTo: string): string | undefined {\n if (/^cs_(test_|live_)?[A-Za-z0-9_]+$/.test(payTo)) {\n return payTo;\n }\n\n try {\n const url = new URL(payTo);\n const match = url.pathname.match(/\\/pay\\/([^/?#]+)/);\n\n const sessionId = match?.[1];\n\n return sessionId && /^cs_(test_|live_)?[A-Za-z0-9_]+$/.test(sessionId)\n ? sessionId\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction flattenStripeMetadata(\n metadata:\n | Record<string, string | number | boolean | null | undefined>\n | undefined,\n): Record<string, string | number | boolean> {\n const result: Record<string, string | number | boolean> = {};\n\n for (const [key, value] of Object.entries(metadata ?? {})) {\n if (value !== undefined && value !== null) {\n result[`metadata[${key}]`] = value;\n }\n }\n\n return result;\n}\n\nfunction readString(\n value: Record<string, unknown> | undefined,\n key: string,\n): string | undefined {\n if (!value) {\n return undefined;\n }\n\n const item = value[key];\n\n if (typeof item === 'string') {\n return item;\n }\n\n if (typeof item === 'number') {\n return String(item);\n }\n\n return undefined;\n}\n\nfunction readSafeInteger(\n value: Record<string, unknown> | undefined,\n key: string,\n): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const item = value[key];\n\n return typeof item === 'number' && Number.isSafeInteger(item) && item >= 0\n ? item\n : undefined;\n}\n"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -18,6 +18,18 @@ export interface PaymentBackendCapabilities {
18
18
  supportsRefunds: boolean;
19
19
  supportsPayouts: boolean;
20
20
  supportsWebhooks: boolean;
21
+ /**
22
+ * Whether the backend supports the manual-capture card lifecycle
23
+ * (`authorizePayment` → `capturePayment` / `voidPayment`). Card processors
24
+ * such as Stripe set this; settlement-only rails (crypto) leave it unset.
25
+ */
26
+ supportsManualCapture?: boolean;
27
+ /**
28
+ * Whether the backend can save a reusable payment method (card on file)
29
+ * via `createSetupSession` / `getSetupResult`. Card processors such as
30
+ * Stripe set this; settlement-only rails (crypto) leave it unset.
31
+ */
32
+ supportsSavedPaymentMethods?: boolean;
21
33
  metadata?: Record<string, unknown>;
22
34
  }
23
35
  export interface CreatePaymentOptionInput {
@@ -160,6 +172,175 @@ export interface RefundResult {
160
172
  currency?: string;
161
173
  raw?: unknown;
162
174
  }
175
+ export interface AuthorizePaymentInput {
176
+ /** Amount to authorize, in the currency's smallest unit (e.g. cents). */
177
+ amount: number;
178
+ /** Currency (ISO 4217). Must be in the backend's configured supported set. */
179
+ currency: string;
180
+ /**
181
+ * Provider payment-method reference to charge (e.g. a Stripe `pm_...` id) —
182
+ * the `providerPaymentMethodId` a saved-card / setup flow returns.
183
+ */
184
+ providerPaymentMethodId: string;
185
+ /**
186
+ * Provider customer reference (e.g. a Stripe `cus_...` id). Required when the
187
+ * payment method is attached to a customer — which a saved card always is, so
188
+ * this is required for the save-card → charge flow — or the provider rejects
189
+ * the charge. Optional only for a one-off, unattached payment method.
190
+ */
191
+ providerCustomerId?: string;
192
+ description?: string;
193
+ /**
194
+ * Whether the customer is absent — an off-session, merchant-initiated charge
195
+ * (e.g. charging a saved card at approval time). Defaults to `true`, the
196
+ * primary use of this method. Set `false` for on-session authorizations where
197
+ * the buyer is present to complete any authentication challenge.
198
+ *
199
+ * Note: off-session, an issuer step-up surfaces as a thrown error
200
+ * (`authentication_required`), NOT a `requires_action` result — the absent
201
+ * buyer can't authenticate, so the caller must re-prompt on-session.
202
+ * `requires_action` (with `clientSecret`/`nextAction`) only occurs when
203
+ * `offSession` is `false`.
204
+ */
205
+ offSession?: boolean;
206
+ /**
207
+ * Optional caller reference, surfaced to the provider as metadata. Also
208
+ * correlates this intent's capture/void/fail webhooks: without it, those
209
+ * PaymentIntent events surface as `processing` (non-terminal) rather than
210
+ * `confirmed`/`failed`, since they can't be attributed.
211
+ */
212
+ quoteId?: string;
213
+ idempotencyKey?: string;
214
+ metadata?: Record<string, string | number | boolean | null | undefined>;
215
+ }
216
+ export interface AuthorizationResult {
217
+ backendId: string;
218
+ /**
219
+ * `requires_capture` on a successful hold (the normal manual-capture result).
220
+ * `succeeded` means the intent was already captured (an auto-capture backend/
221
+ * config) — treat it as captured, do NOT then call `capturePayment`.
222
+ * `requires_action` (on-session only — see `AuthorizePaymentInput.offSession`)
223
+ * needs the buyer to complete authentication via `clientSecret`/`nextAction`.
224
+ * `processing` is an async authorization still in flight; `failed` is a
225
+ * declined/unusable intent.
226
+ */
227
+ status: 'requires_capture' | 'requires_action' | 'processing' | 'succeeded' | 'failed';
228
+ /** Provider id of the authorized payment, needed to capture or void it. */
229
+ providerPaymentId?: string;
230
+ amount?: number;
231
+ currency?: string;
232
+ /**
233
+ * Client secret to complete authentication when `status` is
234
+ * `requires_action` (e.g. 3-D Secure). The buyer's client uses it to finish
235
+ * the challenge, after which the intent moves to `requires_capture`.
236
+ */
237
+ clientSecret?: string;
238
+ /**
239
+ * Provider-specific next-action payload when `status` is `requires_action`
240
+ * (e.g. the redirect/challenge details). Present only when action is needed.
241
+ */
242
+ nextAction?: unknown;
243
+ raw?: unknown;
244
+ }
245
+ export interface CapturePaymentInput {
246
+ /** Provider id returned by `authorizePayment`. */
247
+ providerPaymentId: string;
248
+ /** Partial capture amount in the smallest unit; omit to capture in full. */
249
+ amount?: number;
250
+ idempotencyKey?: string;
251
+ metadata?: Record<string, string | number | boolean | null | undefined>;
252
+ }
253
+ export interface CaptureResult {
254
+ backendId: string;
255
+ status: 'succeeded' | 'processing' | 'failed';
256
+ providerPaymentId?: string;
257
+ amount?: number;
258
+ currency?: string;
259
+ raw?: unknown;
260
+ }
261
+ export interface VoidPaymentInput {
262
+ /** Provider id returned by `authorizePayment`. */
263
+ providerPaymentId: string;
264
+ idempotencyKey?: string;
265
+ /**
266
+ * Optional cancellation reason. Constrained to the provider's accepted set —
267
+ * Stripe rejects any other value, which would fail the cancel and leave the
268
+ * authorization hold in place.
269
+ */
270
+ reason?: 'duplicate' | 'fraudulent' | 'requested_by_customer' | 'abandoned';
271
+ }
272
+ export interface VoidResult {
273
+ backendId: string;
274
+ status: 'canceled' | 'failed';
275
+ providerPaymentId?: string;
276
+ amount?: number;
277
+ currency?: string;
278
+ raw?: unknown;
279
+ }
280
+ export interface CreateSetupSessionInput {
281
+ /**
282
+ * Settlement currency for the setup session. Stripe requires a currency for
283
+ * setup-mode Checkout Sessions; defaults to the backend's configured
284
+ * currency when omitted.
285
+ */
286
+ currency?: string;
287
+ /** Where Stripe returns the buyer after saving the card. */
288
+ successUrl?: string;
289
+ cancelUrl?: string;
290
+ /** Prefill / create the customer by email (ignored if providerCustomerId is set). */
291
+ customerEmail?: string;
292
+ /** Attach the saved method to an existing provider customer (e.g. cus_...). */
293
+ providerCustomerId?: string;
294
+ idempotencyKey?: string;
295
+ metadata?: Record<string, string | number | boolean | null | undefined>;
296
+ }
297
+ export interface SetupSession {
298
+ backendId: string;
299
+ /** Provider session id (e.g. a Stripe Checkout Session cs_...). */
300
+ sessionId: string;
301
+ /** Hosted URL the buyer completes to save their card. */
302
+ url: string;
303
+ /**
304
+ * Provider customer id — present only when one was supplied on input. For the
305
+ * email / auto-create path the customer is created when the buyer completes
306
+ * the flow, so this is typically `undefined` here; read it from
307
+ * {@link getSetupResult} after completion instead.
308
+ */
309
+ providerCustomerId?: string;
310
+ raw?: unknown;
311
+ }
312
+ export interface GetSetupResultInput {
313
+ /** The `sessionId` returned by createSetupSession. */
314
+ sessionId: string;
315
+ }
316
+ export interface SavedPaymentMethod {
317
+ backendId: string;
318
+ /**
319
+ * `complete` only when the method is actually reusable — the setup succeeded
320
+ * AND both reusable references are present. `pending` while still in progress,
321
+ * `failed` on a declined/canceled setup (terminal — stop polling), `expired`
322
+ * when the session lapsed.
323
+ */
324
+ status: 'complete' | 'pending' | 'failed' | 'expired';
325
+ /**
326
+ * Reusable references to persist — never card data. Both are guaranteed
327
+ * present whenever `status === 'complete'`.
328
+ */
329
+ providerCustomerId?: string;
330
+ providerPaymentMethodId?: string;
331
+ /** Non-sensitive display fields. */
332
+ type?: string;
333
+ brand?: string;
334
+ last4?: string;
335
+ expMonth?: number;
336
+ expYear?: number;
337
+ /**
338
+ * Full, untrimmed provider object for inspection. May contain PII (e.g. a
339
+ * Checkout Session's `customer_details`) — persist the typed reference/display
340
+ * fields above, not `raw`.
341
+ */
342
+ raw?: unknown;
343
+ }
163
344
  export interface PaymentBackend {
164
345
  readonly capabilities: PaymentBackendCapabilities;
165
346
  createPaymentOption(input: CreatePaymentOptionInput): Promise<PaymentOption>;
@@ -168,6 +349,33 @@ export interface PaymentBackend {
168
349
  verifyX402Proof?(input: VerifyX402ProofInput): Promise<X402VerificationResult>;
169
350
  sendPayout(input: SendPayoutInput): Promise<PayoutResult>;
170
351
  refundPayment?(input: RefundPaymentInput): Promise<RefundResult>;
352
+ /**
353
+ * Authorize (place a hold on) funds without capturing them, returning an
354
+ * uncaptured payment that can later be captured or voided. Card-processor
355
+ * backends implement this; settlement-only rails do not.
356
+ */
357
+ authorizePayment?(input: AuthorizePaymentInput): Promise<AuthorizationResult>;
358
+ /**
359
+ * Capture a previously authorized payment — in full, or a partial `amount`.
360
+ */
361
+ capturePayment?(input: CapturePaymentInput): Promise<CaptureResult>;
362
+ /**
363
+ * Void (cancel) an authorized-but-uncaptured payment. No funds move.
364
+ */
365
+ voidPayment?(input: VoidPaymentInput): Promise<VoidResult>;
366
+ /**
367
+ * Start a hosted flow to save a reusable payment method (card on file)
368
+ * without charging. Returns a redirect URL the buyer completes; the saved
369
+ * method is then read back with {@link getSetupResult}. Card-processor
370
+ * backends implement this; settlement-only rails do not.
371
+ */
372
+ createSetupSession?(input: CreateSetupSessionInput): Promise<SetupSession>;
373
+ /**
374
+ * Read the outcome of a {@link createSetupSession} flow — the saved
375
+ * payment-method + customer references and non-sensitive card display
376
+ * fields (brand / last4 / expiry). Never returns raw card data.
377
+ */
378
+ getSetupResult?(input: GetSetupResultInput): Promise<SavedPaymentMethod>;
171
379
  parseWebhookEvent?(payload: string, signature?: string): PaymentWebhookEvent;
172
380
  }
173
381
  export type PaymentBackendFactory<TOptions> = (options: TOptions) => PaymentBackend | Promise<PaymentBackend>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/payments",
3
- "version": "0.74.11",
3
+ "version": "0.76.0",
4
4
  "description": "Payment backend abstraction with adapters for Base USDC, BTCPay Server, and Stripe",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",