@alphawebai/hs-prism 0.1.0-rc.45 → 0.1.0-rc.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  export declare const ALPHAWEB_STRIPE_WEBHOOK_EVENTS: readonly ["charge.dispute.closed", "charge.dispute.created", "charge.dispute.funds_reinstated", "charge.dispute.funds_withdrawn", "charge.dispute.updated", "mandate.updated", "payment_intent.amount_capturable_updated", "payment_intent.canceled", "payment_intent.payment_failed", "payment_intent.processing", "payment_intent.requires_action", "payment_intent.succeeded", "payment_method.attached", "payment_method.automatically_updated", "payment_method.detached", "payment_method.updated", "refund.created", "refund.failed", "refund.updated", "setup_intent.canceled", "setup_intent.requires_action", "setup_intent.setup_failed", "setup_intent.succeeded"];
2
2
  export declare const ALPHAWEB_PAYPAL_WEBHOOK_EVENTS: readonly ["CHECKOUT.ORDER.APPROVED", "CHECKOUT.ORDER.COMPLETED", "CHECKOUT.ORDER.PROCESSED", "CHECKOUT.PAYMENT-APPROVAL.REVERSED", "CUSTOMER.DISPUTE.CREATED", "CUSTOMER.DISPUTE.RESOLVED", "CUSTOMER.DISPUTE.UPDATED", "PAYMENT.AUTHORIZATION.CREATED", "PAYMENT.AUTHORIZATION.VOIDED", "PAYMENT.CAPTURE.COMPLETED", "PAYMENT.CAPTURE.DECLINED", "PAYMENT.CAPTURE.PENDING", "PAYMENT.CAPTURE.REFUNDED", "PAYMENT.CAPTURE.REVERSED", "PAYMENT.REFUND.FAILED", "PAYMENT.REFUND.PENDING", "RISK.DISPUTE.CREATED", "VAULT.PAYMENT-TOKEN.CREATED", "VAULT.PAYMENT-TOKEN.DELETED", "VAULT.PAYMENT-TOKEN.DELETION-INITIATED"];
3
3
  export declare const ALPHAWEB_PRISM_COMPATIBILITY_MANIFEST: Readonly<{
4
- readonly release: "0.1.0-rc.45";
4
+ readonly release: "0.1.0-rc.46";
5
5
  readonly upstreamCommit: "b07af7d9dac271de729548e74217ddcf895c602b";
6
6
  readonly medusaRange: ">=2.17.2 <2.18.0";
7
7
  readonly stripeApiVersion: "2026-06-24.dahlia";
@@ -49,7 +49,7 @@ exports.ALPHAWEB_PAYPAL_WEBHOOK_EVENTS = Object.freeze([
49
49
  'VAULT.PAYMENT-TOKEN.DELETION-INITIATED',
50
50
  ]);
51
51
  exports.ALPHAWEB_PRISM_COMPATIBILITY_MANIFEST = Object.freeze({
52
- release: '0.1.0-rc.45',
52
+ release: '0.1.0-rc.46',
53
53
  upstreamCommit: 'b07af7d9dac271de729548e74217ddcf895c602b',
54
54
  medusaRange: '>=2.17.2 <2.18.0',
55
55
  stripeApiVersion: '2026-06-24.dahlia',
@@ -30,6 +30,7 @@ export declare class PrismStripeConnector implements PrismStripeConnectorV1 {
30
30
  private assertOperation;
31
31
  private recoverRepeatPayment;
32
32
  private stripeRequest;
33
+ private checkoutPaymentMethodSelection;
33
34
  createPayment(input: PrismMerchantOperation): Promise<PrismPaymentResult>;
34
35
  repeatPayment(input: PrismMerchantOperation): Promise<PrismPaymentResult>;
35
36
  retryPayment(input: PrismRetryPaymentInput): Promise<PrismPaymentResult>;
@@ -167,9 +167,8 @@ function buildResult(response, money, fallbackConnectorPaymentId = null) {
167
167
  * Package-owned intersection of Stripe's API support contract and the payment
168
168
  * method types represented by Prism's recurring-payment ABI.
169
169
  *
170
- * An interactive PaymentIntent can still use any method Stripe exposes through
171
- * automatic payment methods. This table only governs server-side reuse after
172
- * Stripe has attached the method to the proven Customer.
170
+ * One-time interactive payments retain Stripe's dynamic methods. Future-use
171
+ * checkout and server-side reuse share this capability authority.
173
172
  */
174
173
  const STRIPE_REUSABLE_PAYMENT_METHOD_PROFILES = Object.freeze({
175
174
  amazon_pay: {
@@ -191,6 +190,7 @@ const STRIPE_REUSABLE_PAYMENT_METHOD_PROFILES = Object.freeze({
191
190
  prismPaymentMethodType: proto_1.types.PaymentMethodType.IDEAL,
192
191
  supportsFutureUsage: true,
193
192
  supportsManualCapture: false,
193
+ requiresGeneratedDebit: true,
194
194
  },
195
195
  link: {
196
196
  prismPaymentMethodType: proto_1.types.PaymentMethodType.CREDIT,
@@ -207,6 +207,11 @@ const STRIPE_REUSABLE_PAYMENT_METHOD_PROFILES = Object.freeze({
207
207
  supportsFutureUsage: true,
208
208
  supportsManualCapture: true,
209
209
  },
210
+ satispay: {
211
+ prismPaymentMethodType: proto_1.types.PaymentMethodType.SATISPAY,
212
+ supportsFutureUsage: true,
213
+ supportsManualCapture: true,
214
+ },
210
215
  sepa_debit: {
211
216
  prismPaymentMethodType: proto_1.types.PaymentMethodType.SEPA,
212
217
  supportsFutureUsage: true,
@@ -223,13 +228,20 @@ const STRIPE_REUSABLE_PAYMENT_METHOD_PROFILES = Object.freeze({
223
228
  supportsManualCapture: false,
224
229
  },
225
230
  });
226
- function reusablePaymentMethodProfile(type) {
231
+ function reusablePaymentMethodProfile(type, manualCapture = false) {
227
232
  const profile = STRIPE_REUSABLE_PAYMENT_METHOD_PROFILES[type];
228
233
  if (!profile?.supportsFutureUsage) {
229
234
  throw configurationError('The saved Stripe payment method is not supported for a reusable Prism payment.', 'PRISM_REUSABLE_METHOD_UNSUPPORTED');
230
235
  }
236
+ if (manualCapture && !profile.supportsManualCapture) {
237
+ throw configurationError('The saved Stripe payment method does not support manual capture.', 'PRISM_REUSABLE_CAPTURE_UNSUPPORTED');
238
+ }
231
239
  return profile;
232
240
  }
241
+ function supportsStripeFutureUse(profile, purposes) {
242
+ return profile.supportsFutureUsage &&
243
+ (!purposes.includes('post_purchase') || profile.supportsManualCapture);
244
+ }
233
245
  const STRIPE_HARD_DECLINE_CODES = new Set([
234
246
  'authentication_required',
235
247
  'highest_risk_level',
@@ -749,6 +761,49 @@ class PrismStripeConnector {
749
761
  clearTimeout(timeout);
750
762
  }
751
763
  }
764
+ async checkoutPaymentMethodSelection(input) {
765
+ const purposes = input.futureUse?.purposes ??
766
+ (input.metadata.alphaweb_setup_future_usage === 'off_session' ? ['post_purchase'] : []);
767
+ if (purposes.length === 0)
768
+ return undefined;
769
+ const configurationId = input.methodSelection.kind === 'interactive_dynamic'
770
+ ? input.methodSelection.paymentMethodConfigurationId : undefined;
771
+ let configuration;
772
+ if (configurationId) {
773
+ configuration = recordOf(await this.stripeRequest('GET', `/payment_method_configurations/${encodeURIComponent(configurationId)}`));
774
+ }
775
+ else {
776
+ let after = null;
777
+ do {
778
+ const params = new URLSearchParams({ limit: '100', ...(after ? { starting_after: after } : {}) });
779
+ const page = recordOf(await this.stripeRequest('GET', `/payment_method_configurations?${params}`));
780
+ const configurations = Array.isArray(page.data) ? page.data.map(recordOf) : [];
781
+ configuration = configurations.find((entry) => entry.is_default === true);
782
+ if (configuration)
783
+ break;
784
+ after = page.has_more === true ? stringOf(configurations.at(-1)?.id) : null;
785
+ } while (after);
786
+ }
787
+ const selectedId = stringOf(configuration?.id);
788
+ if (configuration?.active !== true || !selectedId) {
789
+ throw configurationError('Stripe payment method configuration is unavailable.', 'PRISM_METHOD_CONFIGURATION_UNAVAILABLE');
790
+ }
791
+ // Keep Stripe's configuration (including wallet controls). Translate our
792
+ // supported-flow table into native exclusions using Stripe's own method list.
793
+ const methods = Object.entries(configuration).filter(([, value]) => recordOf(value).display_preference);
794
+ const excludedPaymentMethodTypes = methods.filter(([type]) => {
795
+ // These configuration controls are card wallets/networks, not distinct PM types.
796
+ const method = ['apple_pay', 'google_pay', 'cartes_bancaires'].includes(type) ? 'card' : type;
797
+ const profile = STRIPE_REUSABLE_PAYMENT_METHOD_PROFILES[method];
798
+ return !profile || !supportsStripeFutureUse(profile, purposes) || profile.requiresGeneratedDebit ||
799
+ (input.metadata.alphaweb_capture_method === 'manual' && !profile.supportsManualCapture);
800
+ }).map(([type]) => type);
801
+ if (!methods.some(([type, value]) => !excludedPaymentMethodTypes.includes(type) &&
802
+ recordOf(value).available === true && recordOf(recordOf(value).display_preference).value === 'on')) {
803
+ throw configurationError('No enabled Stripe payment method supports this purchase and its future payments.', 'PRISM_PAYMENT_METHOD_FLOW_UNSUPPORTED');
804
+ }
805
+ return { paymentMethodConfigurationId: selectedId, excludedPaymentMethodTypes };
806
+ }
752
807
  async createPayment(input) {
753
808
  this.assertOperation(input);
754
809
  if (input.methodSelection.kind !== 'interactive_dynamic' || input.reusableReference) {
@@ -758,6 +813,7 @@ class PrismStripeConnector {
758
813
  throw configurationError('Interactive Stripe checkout requires a publishable key.', 'PRISM_PUBLISHABLE_KEY_REQUIRED');
759
814
  }
760
815
  try {
816
+ const methodSelection = await this.checkoutPaymentMethodSelection(input);
761
817
  const response = await this.dependencies.merchantAuthentication.createClientAuthenticationToken({
762
818
  merchantClientSessionId: input.idempotencyKey,
763
819
  testMode: this.options.environment === 'test',
@@ -771,7 +827,9 @@ class PrismStripeConnector {
771
827
  captureMethod: input.metadata.alphaweb_capture_method === 'manual'
772
828
  ? proto_1.types.CaptureMethod.MANUAL
773
829
  : proto_1.types.CaptureMethod.AUTOMATIC,
774
- paymentMethodConfigurationId: input.methodSelection.paymentMethodConfigurationId,
830
+ paymentMethodConfigurationId: methodSelection?.paymentMethodConfigurationId ??
831
+ input.methodSelection.paymentMethodConfigurationId,
832
+ excludedPaymentMethodTypes: methodSelection?.excludedPaymentMethodTypes,
775
833
  merchantMetadata: operationMetadata(input),
776
834
  },
777
835
  });
@@ -838,7 +896,7 @@ class PrismStripeConnector {
838
896
  ? proto_1.types.CaptureMethod.MANUAL
839
897
  : proto_1.types.CaptureMethod.AUTOMATIC,
840
898
  connectorCustomerId: reference.connectorCustomerId,
841
- paymentMethodType: reusablePaymentMethodProfile(paymentMethod.type).prismPaymentMethodType,
899
+ paymentMethodType: reusablePaymentMethodProfile(paymentMethod.type, input.metadata.alphaweb_capture_method === 'manual').prismPaymentMethodType,
842
900
  offSession: true,
843
901
  metadata: secret(JSON.stringify(operationMetadata(input))),
844
902
  });
@@ -892,7 +950,7 @@ class PrismStripeConnector {
892
950
  paymentMethod.livemode !== reference.livemode) {
893
951
  throw configurationError('Existing Stripe PaymentIntent is not eligible for this retry.', 'PRISM_RETRY_OWNERSHIP');
894
952
  }
895
- reusablePaymentMethodProfile(paymentMethod.type);
953
+ reusablePaymentMethodProfile(paymentMethod.type, input.metadata.alphaweb_capture_method === 'manual');
896
954
  const body = new URLSearchParams({
897
955
  payment_method: reference.connectorPaymentMethodId,
898
956
  off_session: 'true',
@@ -989,7 +1047,7 @@ class PrismStripeConnector {
989
1047
  }
990
1048
  const requested = new Set(input.purposes);
991
1049
  const capabilities = ['off_session'];
992
- if (requested.has('post_purchase') && profile.supportsManualCapture) {
1050
+ if (requested.has('post_purchase') && supportsStripeFutureUse(profile, ['post_purchase'])) {
993
1051
  capabilities.push('post_purchase', 'manual_capture');
994
1052
  }
995
1053
  if (requested.has('subscription'))
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/dist/src/payments/generated/libconnector_service_ffi.so
3
- size: 105627896 bytes
4
- sha256: 338db46bdefabbbfe0a0bad89f21961c800ddb7d2dca338005861f4c6a8c49d0
3
+ size: 105630648 bytes
4
+ sha256: 93607402e9d0d7ffa2a03ca3c6ca04573d10d767acc8dca694864c2f65280ffc
@@ -14793,6 +14793,9 @@ export namespace types {
14793
14793
 
14794
14794
  /** PaymentClientAuthenticationContext merchantMetadata */
14795
14795
  merchantMetadata?: ({ [k: string]: string }|null);
14796
+
14797
+ /** Flow-specific exclusions; empty retains the connector's dynamic defaults. */
14798
+ excludedPaymentMethodTypes?: (string[]|null);
14796
14799
  }
14797
14800
 
14798
14801
  /** Payment-specific context for client authentication token creation */
@@ -14843,6 +14846,9 @@ export namespace types {
14843
14846
  /** PaymentClientAuthenticationContext merchantMetadata. */
14844
14847
  public merchantMetadata: { [k: string]: string };
14845
14848
 
14849
+ /** Flow-specific exclusions; empty retains the connector's dynamic defaults. */
14850
+ public excludedPaymentMethodTypes: string[];
14851
+
14846
14852
  /**
14847
14853
  * Creates a new PaymentClientAuthenticationContext instance using the specified properties.
14848
14854
  * @param [properties] Properties to set
@@ -45916,6 +45916,7 @@ $root.types = (function() {
45916
45916
  * @property {types.CaptureMethod|null} [captureMethod] PaymentClientAuthenticationContext captureMethod
45917
45917
  * @property {string|null} [paymentMethodConfigurationId] PaymentClientAuthenticationContext paymentMethodConfigurationId
45918
45918
  * @property {Object.<string,string>|null} [merchantMetadata] PaymentClientAuthenticationContext merchantMetadata
45919
+ * @property {Array.<string>|null} [excludedPaymentMethodTypes] Flow-specific exclusions; empty retains the connector's dynamic defaults.
45919
45920
  */
45920
45921
 
45921
45922
  /**
@@ -45928,6 +45929,7 @@ $root.types = (function() {
45928
45929
  */
45929
45930
  function PaymentClientAuthenticationContext(properties) {
45930
45931
  this.merchantMetadata = {};
45932
+ this.excludedPaymentMethodTypes = [];
45931
45933
  if (properties)
45932
45934
  for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
45933
45935
  if (properties[keys[i]] != null && keys[i] !== "__proto__")
@@ -46038,6 +46040,14 @@ $root.types = (function() {
46038
46040
  */
46039
46041
  PaymentClientAuthenticationContext.prototype.merchantMetadata = $util.emptyObject;
46040
46042
 
46043
+ /**
46044
+ * Flow-specific exclusions; empty retains the connector's dynamic defaults.
46045
+ * @member {Array.<string>} excludedPaymentMethodTypes
46046
+ * @memberof types.PaymentClientAuthenticationContext
46047
+ * @instance
46048
+ */
46049
+ PaymentClientAuthenticationContext.prototype.excludedPaymentMethodTypes = $util.emptyArray;
46050
+
46041
46051
  // OneOf field names bound to virtual getters and setters
46042
46052
  var $oneOfFields;
46043
46053
 
@@ -46162,6 +46172,9 @@ $root.types = (function() {
46162
46172
  if (message.merchantMetadata != null && Object.hasOwnProperty.call(message, "merchantMetadata"))
46163
46173
  for (var keys = Object.keys(message.merchantMetadata), i = 0; i < keys.length; ++i)
46164
46174
  writer.uint32(/* id 13, wireType 2 =*/106).fork().uint32(/* id 1, wireType 2 =*/10).string(keys[i]).uint32(/* id 2, wireType 2 =*/18).string(message.merchantMetadata[keys[i]]).ldelim();
46175
+ if (message.excludedPaymentMethodTypes != null && message.excludedPaymentMethodTypes.length)
46176
+ for (var i = 0; i < message.excludedPaymentMethodTypes.length; ++i)
46177
+ writer.uint32(/* id 14, wireType 2 =*/114).string(message.excludedPaymentMethodTypes[i]);
46165
46178
  return writer;
46166
46179
  };
46167
46180
 
@@ -46262,6 +46275,12 @@ $root.types = (function() {
46262
46275
  message.merchantMetadata[key] = value;
46263
46276
  break;
46264
46277
  }
46278
+ case 14: {
46279
+ if (!(message.excludedPaymentMethodTypes && message.excludedPaymentMethodTypes.length))
46280
+ message.excludedPaymentMethodTypes = [];
46281
+ message.excludedPaymentMethodTypes.push(reader.string());
46282
+ break;
46283
+ }
46265
46284
  default:
46266
46285
  reader.skipType(tag & 7, long);
46267
46286
  break;
@@ -46746,6 +46765,13 @@ $root.types = (function() {
46746
46765
  if (!$util.isString(message.merchantMetadata[key[i]]))
46747
46766
  return "merchantMetadata: string{k:string} expected";
46748
46767
  }
46768
+ if (message.excludedPaymentMethodTypes != null && Object.hasOwnProperty.call(message, "excludedPaymentMethodTypes")) {
46769
+ if (!Array.isArray(message.excludedPaymentMethodTypes))
46770
+ return "excludedPaymentMethodTypes: array expected";
46771
+ for (var i = 0; i < message.excludedPaymentMethodTypes.length; ++i)
46772
+ if (!$util.isString(message.excludedPaymentMethodTypes[i]))
46773
+ return "excludedPaymentMethodTypes: string[] expected";
46774
+ }
46749
46775
  return null;
46750
46776
  };
46751
46777
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alphawebai/hs-prism",
3
- "version": "0.1.0-rc.45",
3
+ "version": "0.1.0-rc.46",
4
4
  "description": "Hyperswitch Payments SDK — Node.js client for connector integrations via UniFFI FFI",
5
5
  "main": "dist/src/index.js",
6
6
  "exports": {