@delopay/sdk 0.108.0 → 0.109.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.
@@ -484,23 +484,38 @@ var Connectors = class {
484
484
  );
485
485
  }
486
486
  /**
487
- * Every connector's native-pane capabilities, as the router itself knows
488
- * them — which rails a connector supports, and which methods it can publish
489
- * as a pane with the confirm routing keys each one carries.
487
+ * Every connector's pane capabilities, as the router itself knows them —
488
+ * which rails a connector supports, and which methods it can publish as a
489
+ * pane with the confirm routing keys each one carries.
490
490
  *
491
491
  * Capability facts only: no label, sublabel or category comes back. A
492
492
  * designer renders a method's copy from its own locale files, keyed by
493
493
  * `key`, and takes `payment_method` / `payment_method_type` from here
494
494
  * verbatim rather than deriving them client-side.
495
495
  *
496
+ * This is what the pane helpers in `src/panes.ts` should be driven from —
497
+ * `paneMethodInfo`, `defaultPane` and `validatePanes` all take a
498
+ * {@link PanesConnectorCatalog} out of this response, so a connector the
499
+ * router starts publishing panes for needs no SDK release.
500
+ *
496
501
  * `GET /account/{accountId}/connectors/native-panes/catalog`
502
+ *
503
+ * The path keeps the `native-panes` spelling deliberately. The identifiers
504
+ * were renamed off "native pane"; the route was not, and pointing at the
505
+ * backend's new name before it is deployed everywhere would both 404 against
506
+ * un-upgraded replicas mid-rollout and fail `scripts/parity-check.mjs`,
507
+ * which blocks publishing.
497
508
  */
498
- async getNativePanesCatalog(accountId) {
509
+ async getPanesCatalog(accountId) {
499
510
  return this.request(
500
511
  "GET",
501
512
  `/account/${encodeURIComponent(accountId)}/connectors/native-panes/catalog`
502
513
  );
503
514
  }
515
+ /** @deprecated Renamed to {@link getPanesCatalog}. Removed in 0.112.0. */
516
+ async getNativePanesCatalog(accountId) {
517
+ return this.getPanesCatalog(accountId);
518
+ }
504
519
  /**
505
520
  * Sweep the merchant's own e-Payouts module and return the rails it
506
521
  * actually has enabled. Server-side this makes many upstream calls, so it
@@ -6261,11 +6276,23 @@ var CheckoutSession = class {
6261
6276
  }
6262
6277
  };
6263
6278
 
6264
- // src/nativePanes.ts
6265
- var STRIPE_NATIVE_PANE_METHODS = [
6279
+ // src/panes.ts
6280
+ var PANE_VISIBILITIES = ["always", "embedded_only", "external_only"];
6281
+ function parseVisibility(raw) {
6282
+ return PANE_VISIBILITIES.find((value) => value === raw) ?? "always";
6283
+ }
6284
+ function paneViewVisibility(view) {
6285
+ const declared = PANE_VISIBILITIES.find((value) => value === view.visibility);
6286
+ if (declared) return declared;
6287
+ return view.embedded_only === true ? "embedded_only" : "always";
6288
+ }
6289
+ var STRIPE_FALLBACK_PANE_METHODS = [
6266
6290
  {
6267
6291
  key: "apple_pay",
6268
6292
  rail: "wallet",
6293
+ paymentMethod: "wallet",
6294
+ paymentMethodType: "apple_pay",
6295
+ requiresBillingCountry: false,
6269
6296
  defaultLabel: "Apple Pay",
6270
6297
  defaultSublabel: "Pay with Apple Pay",
6271
6298
  defaultCategory: "wallet",
@@ -6274,6 +6301,9 @@ var STRIPE_NATIVE_PANE_METHODS = [
6274
6301
  {
6275
6302
  key: "google_pay",
6276
6303
  rail: "wallet",
6304
+ paymentMethod: "wallet",
6305
+ paymentMethodType: "google_pay",
6306
+ requiresBillingCountry: false,
6277
6307
  defaultLabel: "Google Pay",
6278
6308
  defaultSublabel: "Pay with Google Pay",
6279
6309
  defaultCategory: "wallet",
@@ -6282,6 +6312,9 @@ var STRIPE_NATIVE_PANE_METHODS = [
6282
6312
  {
6283
6313
  key: "link",
6284
6314
  rail: "wallet",
6315
+ paymentMethod: "wallet",
6316
+ paymentMethodType: "link",
6317
+ requiresBillingCountry: false,
6285
6318
  defaultLabel: "Link",
6286
6319
  defaultSublabel: "Pay with saved details",
6287
6320
  defaultCategory: "wallet",
@@ -6290,7 +6323,18 @@ var STRIPE_NATIVE_PANE_METHODS = [
6290
6323
  {
6291
6324
  key: "klarna",
6292
6325
  rail: "redirect",
6326
+ paymentMethod: "pay_later",
6327
+ paymentMethodType: "klarna",
6328
+ // Stripe's Klarna needs the buyer's country echoed into the confirm body.
6329
+ requiresBillingCountry: true,
6293
6330
  defaultLabel: "Klarna",
6331
+ // NOT the router's current "Pay later or in 3 instalments". This table is
6332
+ // what a router predating the capability endpoint (delopay-backend#964)
6333
+ // renders, and that copy only gained the "3" in delopay-backend#1051 —
6334
+ // the same release that added the endpoint. Restating the new string here
6335
+ // would put copy no reachable router emits in front of a merchant, and
6336
+ // would change what the deprecated `nativePaneMethodInfo` has returned
6337
+ // since 0.106.0.
6294
6338
  defaultSublabel: "Pay later or in instalments",
6295
6339
  defaultCategory: "bnpl",
6296
6340
  defaultIcon: "bnpl"
@@ -6298,6 +6342,9 @@ var STRIPE_NATIVE_PANE_METHODS = [
6298
6342
  {
6299
6343
  key: "affirm",
6300
6344
  rail: "redirect",
6345
+ paymentMethod: "pay_later",
6346
+ paymentMethodType: "affirm",
6347
+ requiresBillingCountry: false,
6301
6348
  defaultLabel: "Affirm",
6302
6349
  defaultSublabel: "Pay over time",
6303
6350
  defaultCategory: "bnpl",
@@ -6306,18 +6353,20 @@ var STRIPE_NATIVE_PANE_METHODS = [
6306
6353
  {
6307
6354
  key: "ideal",
6308
6355
  rail: "redirect",
6356
+ paymentMethod: "bank_redirect",
6357
+ paymentMethodType: "ideal",
6358
+ requiresBillingCountry: false,
6309
6359
  defaultLabel: "iDEAL",
6310
6360
  defaultSublabel: "Pay from your bank",
6311
6361
  defaultCategory: "bank_redirect",
6312
6362
  defaultIcon: "bank"
6313
6363
  },
6314
- // eps / p24 / bancontact were removed from the router catalog: Stripe
6315
- // hard-requires billing fields the focused checkout never collects (full
6316
- // name for EPS/Bancontact, email for Przelewy24), so their tiles could
6317
- // never succeed. They may return behind billing-aware gating.
6318
6364
  {
6319
6365
  key: "alipay",
6320
6366
  rail: "redirect",
6367
+ paymentMethod: "wallet",
6368
+ paymentMethodType: "ali_pay",
6369
+ requiresBillingCountry: false,
6321
6370
  defaultLabel: "Alipay",
6322
6371
  defaultSublabel: "Pay with Alipay",
6323
6372
  defaultCategory: "wallet",
@@ -6326,6 +6375,9 @@ var STRIPE_NATIVE_PANE_METHODS = [
6326
6375
  {
6327
6376
  key: "revolut_pay",
6328
6377
  rail: "redirect",
6378
+ paymentMethod: "wallet",
6379
+ paymentMethodType: "revolut_pay",
6380
+ requiresBillingCountry: false,
6329
6381
  defaultLabel: "Revolut Pay",
6330
6382
  defaultSublabel: "Pay with Revolut",
6331
6383
  defaultCategory: "wallet",
@@ -6334,13 +6386,33 @@ var STRIPE_NATIVE_PANE_METHODS = [
6334
6386
  {
6335
6387
  key: "amazon_pay",
6336
6388
  rail: "redirect",
6389
+ paymentMethod: "wallet",
6390
+ paymentMethodType: "amazon_pay",
6391
+ requiresBillingCountry: false,
6337
6392
  defaultLabel: "Amazon Pay",
6338
6393
  defaultSublabel: "Pay with Amazon",
6339
6394
  defaultCategory: "wallet",
6340
6395
  defaultIcon: "wallet"
6341
6396
  }
6342
6397
  ];
6343
- var NATIVE_PANE_ICON_KEYS = [
6398
+ var STRIPE_FALLBACK_PANE_CATALOG = {
6399
+ connector: "stripe",
6400
+ allowed_rails: ["wallet", "redirect"],
6401
+ methods: STRIPE_FALLBACK_PANE_METHODS.map((info) => ({
6402
+ key: info.key,
6403
+ rail: info.rail,
6404
+ payment_method: info.paymentMethod,
6405
+ payment_method_type: info.paymentMethodType,
6406
+ requires_billing_country: info.requiresBillingCountry
6407
+ }))
6408
+ };
6409
+ function emptyPaneCatalog(connector) {
6410
+ return { connector, allowed_rails: [], methods: [] };
6411
+ }
6412
+ function paneCatalogFor(response, connector) {
6413
+ return response.connectors.find((entry) => entry.connector === connector) ?? emptyPaneCatalog(connector);
6414
+ }
6415
+ var PANE_ICON_KEYS = [
6344
6416
  "wallet",
6345
6417
  "card",
6346
6418
  "bank",
@@ -6349,20 +6421,70 @@ var NATIVE_PANE_ICON_KEYS = [
6349
6421
  "bnpl",
6350
6422
  "cash"
6351
6423
  ];
6352
- var NATIVE_PANE_CATEGORY_KEYS = [
6424
+ var PANE_CATEGORY_KEYS = [
6353
6425
  "wallet",
6354
6426
  "card",
6355
6427
  "bnpl",
6356
6428
  "bank_redirect",
6357
6429
  "bank_transfer",
6430
+ "crypto",
6431
+ "game_items",
6358
6432
  "cash"
6359
6433
  ];
6360
- var NATIVE_PANES_MAX = 12;
6361
- function nativePaneMethodInfo(method) {
6362
- return STRIPE_NATIVE_PANE_METHODS.find((m) => m.key === method);
6434
+ var PANES_MAX = 12;
6435
+ function paneMethodInfo(method, catalog = STRIPE_FALLBACK_PANE_CATALOG) {
6436
+ return catalog.methods.find((info) => info.key === method);
6363
6437
  }
6364
- function defaultNativePane(method) {
6365
- const info = nativePaneMethodInfo(method);
6438
+ function paneRailAllowed(rail, catalog) {
6439
+ return catalog.allowed_rails.includes(rail);
6440
+ }
6441
+ function offerablePaneMethods(catalog) {
6442
+ return catalog.methods.filter((info) => paneRailAllowed(info.rail, catalog));
6443
+ }
6444
+ var DISPLAY_DEFAULTS_BY_KEY = {
6445
+ apple_pay: { icon: "apple", category: "wallet" },
6446
+ google_pay: { icon: "google", category: "wallet" }
6447
+ };
6448
+ var DISPLAY_DEFAULTS_BY_PAYMENT_METHOD = {
6449
+ wallet: { icon: "wallet", category: "wallet" },
6450
+ card: { icon: "card", category: "card" },
6451
+ card_redirect: { icon: "card", category: "card" },
6452
+ pay_later: { icon: "bnpl", category: "bnpl" },
6453
+ bank_redirect: { icon: "bank", category: "bank_redirect" },
6454
+ bank_transfer: { icon: "bank", category: "bank_transfer" },
6455
+ bank_debit: { icon: "bank", category: "bank_transfer" },
6456
+ crypto: { icon: "wallet", category: "crypto" },
6457
+ game_items: { icon: "wallet", category: "game_items" },
6458
+ cash: { icon: "cash", category: "cash" },
6459
+ voucher: { icon: "cash", category: "cash" }
6460
+ };
6461
+ var DISPLAY_DEFAULTS_FALLBACK = { icon: "wallet", category: "wallet" };
6462
+ function paneDisplayDefaults(info) {
6463
+ if (!info) return DISPLAY_DEFAULTS_FALLBACK;
6464
+ return DISPLAY_DEFAULTS_BY_KEY[info.key] ?? DISPLAY_DEFAULTS_BY_PAYMENT_METHOD[info.payment_method] ?? DISPLAY_DEFAULTS_FALLBACK;
6465
+ }
6466
+ function validatePanes(panes, catalog = STRIPE_FALLBACK_PANE_CATALOG) {
6467
+ const issues = [];
6468
+ const claimedBy = /* @__PURE__ */ new Set();
6469
+ panes.forEach((pane, index) => {
6470
+ const info = paneMethodInfo(pane.method, catalog);
6471
+ if (!info) {
6472
+ issues.push({ index, method: pane.method, code: "method_unknown" });
6473
+ } else if (!paneRailAllowed(info.rail, catalog)) {
6474
+ issues.push({ index, method: pane.method, code: "rail_not_allowed" });
6475
+ } else if (pane.enabled) {
6476
+ if (claimedBy.has(info.key)) {
6477
+ issues.push({ index, method: pane.method, code: "duplicate_method" });
6478
+ } else {
6479
+ claimedBy.add(info.key);
6480
+ }
6481
+ }
6482
+ if (index >= PANES_MAX) issues.push({ index, method: pane.method, code: "over_cap" });
6483
+ });
6484
+ return issues;
6485
+ }
6486
+ function defaultPane(method, catalog = STRIPE_FALLBACK_PANE_CATALOG) {
6487
+ const defaults = paneDisplayDefaults(paneMethodInfo(method, catalog));
6366
6488
  return {
6367
6489
  method,
6368
6490
  enabled: true,
@@ -6370,15 +6492,15 @@ function defaultNativePane(method) {
6370
6492
  labelTranslations: {},
6371
6493
  sublabel: null,
6372
6494
  sublabelTranslations: {},
6373
- category: "",
6374
- icon: info?.defaultIcon ?? "",
6495
+ category: defaults.category,
6496
+ icon: defaults.icon,
6375
6497
  iconSvg: "",
6376
6498
  displayOrder: 0,
6377
6499
  visibility: "always",
6378
6500
  openIn: "tab"
6379
6501
  };
6380
6502
  }
6381
- function cloneNativePane(pane) {
6503
+ function clonePane(pane) {
6382
6504
  return {
6383
6505
  ...pane,
6384
6506
  labelTranslations: { ...pane.labelTranslations },
@@ -6405,7 +6527,7 @@ function clampDisplayOrder(raw) {
6405
6527
  if (!Number.isFinite(raw)) return 0;
6406
6528
  return Math.min(DISPLAY_ORDER_MAX, Math.max(DISPLAY_ORDER_MIN, Math.trunc(raw)));
6407
6529
  }
6408
- function decodeNativePanes(raw) {
6530
+ function decodePanes(raw) {
6409
6531
  if (!Array.isArray(raw)) return null;
6410
6532
  const decodeRow = (entry, method) => ({
6411
6533
  method,
@@ -6419,14 +6541,14 @@ function decodeNativePanes(raw) {
6419
6541
  iconSvg: str(entry["icon_svg"]),
6420
6542
  displayOrder: clampDisplayOrder(Number(entry["display_order"])),
6421
6543
  // Anything unrecognised degrades to `always` rather than dropping the row.
6422
- visibility: entry["visibility"] === "embedded_only" ? "embedded_only" : "always",
6544
+ visibility: parseVisibility(entry["visibility"]),
6423
6545
  // Same tolerance: an unknown value degrades to the default `tab`.
6424
6546
  openIn: entry["open_in"] === "popup" ? "popup" : "tab"
6425
6547
  });
6426
6548
  const indexByMethod = /* @__PURE__ */ new Map();
6427
6549
  const out = [];
6428
6550
  for (const entry of raw) {
6429
- if (out.length >= NATIVE_PANES_MAX) break;
6551
+ if (out.length >= PANES_MAX) break;
6430
6552
  if (!isObject2(entry)) continue;
6431
6553
  const method = str(entry["method"]).trim();
6432
6554
  if (!method) continue;
@@ -6442,12 +6564,12 @@ function decodeNativePanes(raw) {
6442
6564
  }
6443
6565
  return out;
6444
6566
  }
6445
- function encodeNativePanes(panes) {
6567
+ function encodePanes(panes) {
6446
6568
  const nonEmpty = (map) => {
6447
6569
  const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);
6448
6570
  return entries.length > 0 ? Object.fromEntries(entries) : void 0;
6449
6571
  };
6450
- return panes.slice(0, NATIVE_PANES_MAX).map((pane) => {
6572
+ return panes.slice(0, PANES_MAX).map((pane) => {
6451
6573
  const labelTranslations = nonEmpty(pane.labelTranslations);
6452
6574
  const sublabelTranslations = nonEmpty(pane.sublabelTranslations);
6453
6575
  return {
@@ -6455,7 +6577,7 @@ function encodeNativePanes(panes) {
6455
6577
  enabled: pane.enabled,
6456
6578
  ...pane.label.trim() ? { label: pane.label.trim() } : {},
6457
6579
  ...labelTranslations ? { label_translations: labelTranslations } : {},
6458
- // `null` omits the key entirely (catalog default wins); `''` is sent
6580
+ // `null` omits the key entirely (catalogue default wins); `''` is sent
6459
6581
  // as-is because that is how the merchant hides the second line.
6460
6582
  ...pane.sublabel !== null ? { sublabel: pane.sublabel } : {},
6461
6583
  ...sublabelTranslations ? { sublabel_translations: sublabelTranslations } : {},
@@ -6467,8 +6589,13 @@ function encodeNativePanes(panes) {
6467
6589
  // writing e.g. 3.5 or Date.now() verbatim would silently delete the
6468
6590
  // pane at render while every read surface shows it healthy.
6469
6591
  display_order: clampDisplayOrder(pane.displayOrder),
6470
- visibility: pane.visibility,
6471
- open_in: pane.openIn
6592
+ // Normalised on encode for the same reason `display_order` is clamped:
6593
+ // the router's strict row decode drops a row whole on a value outside
6594
+ // its enum, and a caller who built a `Pane` by hand (or in plain JS)
6595
+ // never went through `decodePanes`. A decoded pane always holds a valid
6596
+ // value, so this is a no-op on the round-trip path.
6597
+ visibility: parseVisibility(pane.visibility),
6598
+ open_in: pane.openIn === "popup" ? "popup" : "tab"
6472
6599
  };
6473
6600
  });
6474
6601
  }
@@ -6478,6 +6605,10 @@ function focusedCheckoutUrl(params) {
6478
6605
  params.paymentId
6479
6606
  )}`;
6480
6607
  const query = new URLSearchParams({ pane: params.method });
6608
+ const connector = params.connector?.trim();
6609
+ if (connector) query.set("connector", connector);
6610
+ const merchantConnectorId = params.merchantConnectorId?.trim();
6611
+ if (merchantConnectorId) query.set("mca", merchantConnectorId);
6481
6612
  if (params.locale) query.set("locale", params.locale);
6482
6613
  if (params.customFieldsCollected) query.set("cf", "1");
6483
6614
  return `${path}?${query.toString()}`;
@@ -6489,6 +6620,24 @@ var CHECKOUT_EVENT_KINDS = [
6489
6620
  "native_pane_abandoned",
6490
6621
  "native_pane_returned"
6491
6622
  ];
6623
+ var STRIPE_NATIVE_PANE_METHODS = STRIPE_FALLBACK_PANE_METHODS;
6624
+ var NATIVE_PANE_ICON_KEYS = PANE_ICON_KEYS;
6625
+ var NATIVE_PANE_CATEGORY_KEYS = PANE_CATEGORY_KEYS;
6626
+ var NATIVE_PANES_MAX = PANES_MAX;
6627
+ function nativePaneMethodInfo(method) {
6628
+ return STRIPE_FALLBACK_PANE_METHODS.find((info) => info.key === method);
6629
+ }
6630
+ function defaultNativePane(method) {
6631
+ const info = nativePaneMethodInfo(method);
6632
+ return {
6633
+ ...defaultPane(method),
6634
+ category: "",
6635
+ icon: info?.defaultIcon ?? ""
6636
+ };
6637
+ }
6638
+ var cloneNativePane = clonePane;
6639
+ var decodeNativePanes = decodePanes;
6640
+ var encodeNativePanes = encodePanes;
6492
6641
 
6493
6642
  export {
6494
6643
  DelopayError,
@@ -6570,6 +6719,25 @@ export {
6570
6719
  applyBrandingVariables,
6571
6720
  shadowFor,
6572
6721
  CheckoutSession,
6722
+ paneViewVisibility,
6723
+ STRIPE_FALLBACK_PANE_METHODS,
6724
+ STRIPE_FALLBACK_PANE_CATALOG,
6725
+ emptyPaneCatalog,
6726
+ paneCatalogFor,
6727
+ PANE_ICON_KEYS,
6728
+ PANE_CATEGORY_KEYS,
6729
+ PANES_MAX,
6730
+ paneMethodInfo,
6731
+ paneRailAllowed,
6732
+ offerablePaneMethods,
6733
+ paneDisplayDefaults,
6734
+ validatePanes,
6735
+ defaultPane,
6736
+ clonePane,
6737
+ decodePanes,
6738
+ encodePanes,
6739
+ focusedCheckoutUrl,
6740
+ CHECKOUT_EVENT_KINDS,
6573
6741
  STRIPE_NATIVE_PANE_METHODS,
6574
6742
  NATIVE_PANE_ICON_KEYS,
6575
6743
  NATIVE_PANE_CATEGORY_KEYS,
@@ -6578,8 +6746,6 @@ export {
6578
6746
  defaultNativePane,
6579
6747
  cloneNativePane,
6580
6748
  decodeNativePanes,
6581
- encodeNativePanes,
6582
- focusedCheckoutUrl,
6583
- CHECKOUT_EVENT_KINDS
6749
+ encodeNativePanes
6584
6750
  };
6585
- //# sourceMappingURL=chunk-C2O3D7ZM.js.map
6751
+ //# sourceMappingURL=chunk-XMFG7CPX.js.map