@delopay/sdk 0.77.0 → 0.79.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.
@@ -1053,10 +1053,45 @@ var PaymentMethods = class {
1053
1053
  return this.request("DELETE", `/payment-methods/${encodeURIComponent(methodId)}`);
1054
1054
  }
1055
1055
  /**
1056
- * List payment methods using a client secret.
1056
+ * List the payment methods available for a payment — the discovery endpoint a
1057
+ * custom checkout renders its tiles from.
1057
1058
  *
1058
- * @param params - Filter by `client_secret`.
1059
- * @returns Array of payment methods.
1059
+ * Callable with a publishable key plus the payment's `client_secret`, so it
1060
+ * runs from the browser. The returned set is already filtered by country,
1061
+ * order value and the merchant's availability rules, and each entry carries
1062
+ * `display` (name + icon slug) and `amount_limits` (the order values it stays
1063
+ * available for) so you do not have to maintain either alongside.
1064
+ *
1065
+ * This is *not* the customer's saved methods — see {@link listForCustomer}.
1066
+ *
1067
+ * @param params - `client_secret`, plus optional `country`, `amount` and filters.
1068
+ * @returns The methods available for the payment, grouped by payment method.
1069
+ *
1070
+ * @example
1071
+ * ```typescript
1072
+ * const { payment_methods } = await delopay.paymentMethods.list({
1073
+ * client_secret: 'pay_abc_secret_xyz',
1074
+ * country: 'DE',
1075
+ * amount: 25000,
1076
+ * });
1077
+ *
1078
+ * for (const group of payment_methods) {
1079
+ * for (const method of group.payment_method_types) {
1080
+ * // Re-check availability yourself as the cart total changes, instead of
1081
+ * // re-listing on every keystroke.
1082
+ * const limits = method.amount_limits;
1083
+ * const available =
1084
+ * !limits ||
1085
+ * ((limits.min_amount == null || cartTotal >= limits.min_amount) &&
1086
+ * (limits.max_amount == null || cartTotal <= limits.max_amount) &&
1087
+ * !limits.excluded_ranges.some(
1088
+ * (band) => cartTotal >= band.min_amount && cartTotal <= band.max_amount,
1089
+ * ));
1090
+ *
1091
+ * if (available) render(method.display?.display_name, method.display?.icon_slug);
1092
+ * }
1093
+ * }
1094
+ * ```
1060
1095
  */
1061
1096
  async list(params) {
1062
1097
  return this.request("GET", "/payment-methods", {
@@ -4683,6 +4718,230 @@ function shadowFor(style) {
4683
4718
  }
4684
4719
  }
4685
4720
 
4721
+ // src/nativePanes.ts
4722
+ var STRIPE_NATIVE_PANE_METHODS = [
4723
+ {
4724
+ key: "apple_pay",
4725
+ rail: "wallet",
4726
+ defaultLabel: "Apple Pay",
4727
+ defaultSublabel: "Pay with Apple Pay",
4728
+ defaultCategory: "wallet",
4729
+ defaultIcon: "apple"
4730
+ },
4731
+ {
4732
+ key: "google_pay",
4733
+ rail: "wallet",
4734
+ defaultLabel: "Google Pay",
4735
+ defaultSublabel: "Pay with Google Pay",
4736
+ defaultCategory: "wallet",
4737
+ defaultIcon: "google"
4738
+ },
4739
+ {
4740
+ key: "link",
4741
+ rail: "wallet",
4742
+ defaultLabel: "Link",
4743
+ defaultSublabel: "Pay with saved details",
4744
+ defaultCategory: "wallet",
4745
+ defaultIcon: "wallet"
4746
+ },
4747
+ {
4748
+ key: "klarna",
4749
+ rail: "redirect",
4750
+ defaultLabel: "Klarna",
4751
+ defaultSublabel: "Pay later or in instalments",
4752
+ defaultCategory: "bnpl",
4753
+ defaultIcon: "bnpl"
4754
+ },
4755
+ {
4756
+ key: "affirm",
4757
+ rail: "redirect",
4758
+ defaultLabel: "Affirm",
4759
+ defaultSublabel: "Pay over time",
4760
+ defaultCategory: "bnpl",
4761
+ defaultIcon: "bnpl"
4762
+ },
4763
+ {
4764
+ key: "ideal",
4765
+ rail: "redirect",
4766
+ defaultLabel: "iDEAL",
4767
+ defaultSublabel: "Pay from your bank",
4768
+ defaultCategory: "bank_redirect",
4769
+ defaultIcon: "bank"
4770
+ },
4771
+ // eps / p24 / bancontact were removed from the router catalog: Stripe
4772
+ // hard-requires billing fields the focused checkout never collects (full
4773
+ // name for EPS/Bancontact, email for Przelewy24), so their tiles could
4774
+ // never succeed. They may return behind billing-aware gating.
4775
+ {
4776
+ key: "alipay",
4777
+ rail: "redirect",
4778
+ defaultLabel: "Alipay",
4779
+ defaultSublabel: "Pay with Alipay",
4780
+ defaultCategory: "wallet",
4781
+ defaultIcon: "wallet"
4782
+ },
4783
+ {
4784
+ key: "revolut_pay",
4785
+ rail: "redirect",
4786
+ defaultLabel: "Revolut Pay",
4787
+ defaultSublabel: "Pay with Revolut",
4788
+ defaultCategory: "wallet",
4789
+ defaultIcon: "wallet"
4790
+ },
4791
+ {
4792
+ key: "amazon_pay",
4793
+ rail: "redirect",
4794
+ defaultLabel: "Amazon Pay",
4795
+ defaultSublabel: "Pay with Amazon",
4796
+ defaultCategory: "wallet",
4797
+ defaultIcon: "wallet"
4798
+ }
4799
+ ];
4800
+ var NATIVE_PANE_ICON_KEYS = [
4801
+ "wallet",
4802
+ "card",
4803
+ "bank",
4804
+ "apple",
4805
+ "google",
4806
+ "bnpl",
4807
+ "cash"
4808
+ ];
4809
+ var NATIVE_PANE_CATEGORY_KEYS = [
4810
+ "wallet",
4811
+ "card",
4812
+ "bnpl",
4813
+ "bank_redirect",
4814
+ "bank_transfer",
4815
+ "cash"
4816
+ ];
4817
+ var NATIVE_PANES_MAX = 12;
4818
+ function nativePaneMethodInfo(method) {
4819
+ return STRIPE_NATIVE_PANE_METHODS.find((m) => m.key === method);
4820
+ }
4821
+ function defaultNativePane(method) {
4822
+ const info = nativePaneMethodInfo(method);
4823
+ return {
4824
+ method,
4825
+ enabled: true,
4826
+ label: "",
4827
+ labelTranslations: {},
4828
+ sublabel: null,
4829
+ sublabelTranslations: {},
4830
+ category: "",
4831
+ icon: info?.defaultIcon ?? "",
4832
+ iconSvg: "",
4833
+ displayOrder: 0,
4834
+ visibility: "always"
4835
+ };
4836
+ }
4837
+ function cloneNativePane(pane) {
4838
+ return {
4839
+ ...pane,
4840
+ labelTranslations: { ...pane.labelTranslations },
4841
+ sublabelTranslations: { ...pane.sublabelTranslations }
4842
+ };
4843
+ }
4844
+ function isObject2(value) {
4845
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4846
+ }
4847
+ function parseTranslations2(raw) {
4848
+ if (!isObject2(raw)) return {};
4849
+ const out = {};
4850
+ for (const [locale, value] of Object.entries(raw)) {
4851
+ if (typeof value === "string" && value.length > 0) out[locale] = value;
4852
+ }
4853
+ return out;
4854
+ }
4855
+ function str(raw) {
4856
+ return typeof raw === "string" ? raw : "";
4857
+ }
4858
+ var DISPLAY_ORDER_MIN = -2147483648;
4859
+ var DISPLAY_ORDER_MAX = 2147483647;
4860
+ function clampDisplayOrder(raw) {
4861
+ if (!Number.isFinite(raw)) return 0;
4862
+ return Math.min(DISPLAY_ORDER_MAX, Math.max(DISPLAY_ORDER_MIN, Math.trunc(raw)));
4863
+ }
4864
+ function decodeNativePanes(raw) {
4865
+ if (!Array.isArray(raw)) return null;
4866
+ const decodeRow = (entry, method) => ({
4867
+ method,
4868
+ enabled: entry["enabled"] !== false,
4869
+ label: str(entry["label"]),
4870
+ labelTranslations: parseTranslations2(entry["label_translations"]),
4871
+ sublabel: typeof entry["sublabel"] === "string" ? entry["sublabel"] : null,
4872
+ sublabelTranslations: parseTranslations2(entry["sublabel_translations"]),
4873
+ category: str(entry["category"]),
4874
+ icon: str(entry["icon"]),
4875
+ iconSvg: str(entry["icon_svg"]),
4876
+ displayOrder: clampDisplayOrder(Number(entry["display_order"])),
4877
+ // Anything unrecognised degrades to `always` rather than dropping the row.
4878
+ visibility: entry["visibility"] === "embedded_only" ? "embedded_only" : "always"
4879
+ });
4880
+ const indexByMethod = /* @__PURE__ */ new Map();
4881
+ const out = [];
4882
+ for (const entry of raw) {
4883
+ if (out.length >= NATIVE_PANES_MAX) break;
4884
+ if (!isObject2(entry)) continue;
4885
+ const method = str(entry["method"]).trim();
4886
+ if (!method) continue;
4887
+ const kept = indexByMethod.get(method);
4888
+ if (kept !== void 0) {
4889
+ const enabled = entry["enabled"] !== false;
4890
+ const existing = out[kept];
4891
+ if (enabled && existing && !existing.enabled) out[kept] = decodeRow(entry, method);
4892
+ continue;
4893
+ }
4894
+ indexByMethod.set(method, out.length);
4895
+ out.push(decodeRow(entry, method));
4896
+ }
4897
+ return out;
4898
+ }
4899
+ function encodeNativePanes(panes) {
4900
+ const nonEmpty = (map) => {
4901
+ const entries = Object.entries(map).filter(([, v]) => v.trim().length > 0);
4902
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
4903
+ };
4904
+ return panes.slice(0, NATIVE_PANES_MAX).map((pane) => {
4905
+ const labelTranslations = nonEmpty(pane.labelTranslations);
4906
+ const sublabelTranslations = nonEmpty(pane.sublabelTranslations);
4907
+ return {
4908
+ method: pane.method,
4909
+ enabled: pane.enabled,
4910
+ ...pane.label.trim() ? { label: pane.label.trim() } : {},
4911
+ ...labelTranslations ? { label_translations: labelTranslations } : {},
4912
+ // `null` omits the key entirely (catalog default wins); `''` is sent
4913
+ // as-is because that is how the merchant hides the second line.
4914
+ ...pane.sublabel !== null ? { sublabel: pane.sublabel } : {},
4915
+ ...sublabelTranslations ? { sublabel_translations: sublabelTranslations } : {},
4916
+ ...pane.category.trim() ? { category: pane.category.trim() } : {},
4917
+ ...pane.icon.trim() ? { icon: pane.icon.trim() } : {},
4918
+ ...pane.iconSvg.trim() ? { icon_svg: pane.iconSvg.trim() } : {},
4919
+ // Clamped on encode too, not only decode: the router's strict i32 row
4920
+ // decode drops a row whole for a fractional or out-of-range value, so
4921
+ // writing e.g. 3.5 or Date.now() verbatim would silently delete the
4922
+ // pane at render while every read surface shows it healthy.
4923
+ display_order: clampDisplayOrder(pane.displayOrder),
4924
+ visibility: pane.visibility
4925
+ };
4926
+ });
4927
+ }
4928
+ function focusedCheckoutUrl(params) {
4929
+ const base = params.checkoutBaseUrl.replace(/\/+$/, "");
4930
+ const path = `${base}/pay/${encodeURIComponent(params.merchantId)}/${encodeURIComponent(
4931
+ params.paymentId
4932
+ )}`;
4933
+ const query = new URLSearchParams({ pane: params.method });
4934
+ if (params.locale) query.set("locale", params.locale);
4935
+ if (params.customFieldsCollected) query.set("cf", "1");
4936
+ return `${path}?${query.toString()}`;
4937
+ }
4938
+ var CHECKOUT_EVENT_KINDS = [
4939
+ "native_pane_selected",
4940
+ "native_pane_tab_opened",
4941
+ "native_pane_tab_blocked",
4942
+ "native_pane_abandoned"
4943
+ ];
4944
+
4686
4945
  export {
4687
4946
  DelopayError,
4688
4947
  DelopayAuthenticationError,
@@ -4758,6 +5017,17 @@ export {
4758
5017
  buildBrandingExport,
4759
5018
  parseImportedBranding,
4760
5019
  applyBrandingVariables,
4761
- shadowFor
5020
+ shadowFor,
5021
+ STRIPE_NATIVE_PANE_METHODS,
5022
+ NATIVE_PANE_ICON_KEYS,
5023
+ NATIVE_PANE_CATEGORY_KEYS,
5024
+ NATIVE_PANES_MAX,
5025
+ nativePaneMethodInfo,
5026
+ defaultNativePane,
5027
+ cloneNativePane,
5028
+ decodeNativePanes,
5029
+ encodeNativePanes,
5030
+ focusedCheckoutUrl,
5031
+ CHECKOUT_EVENT_KINDS
4762
5032
  };
4763
- //# sourceMappingURL=chunk-RODMYISN.js.map
5033
+ //# sourceMappingURL=chunk-TV4YASDP.js.map