@vio-live/web-sdk 0.27.0 → 0.29.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.
@@ -2214,7 +2214,36 @@ var CartManager = class extends EventTarget {
2214
2214
  /** Quantity intents for lines whose backend id hasn't arrived yet — replayed
2215
2215
  * when the AddItem response reconciles (keyed by product::variant). */
2216
2216
  this.pendingQtyIntents = /* @__PURE__ */ new Map();
2217
+ /**
2218
+ * Another tab of the site wrote the carts: adopt what it wrote, sponsor by
2219
+ * sponsor — its lines and its backend cart id, or nothing when it cleared
2220
+ * the cart (a payment) — except for a sponsor this tab is mid-write for:
2221
+ * its own answer lands in a moment and is persisted then, over whatever
2222
+ * the other tab had. `key` is null when the other tab cleared the whole
2223
+ * storage. Says `change` (the drawer) and `vio:cart-updated` per sponsor
2224
+ * that changed (`source: 'storage'`); nothing when nothing did.
2225
+ */
2226
+ this.onStorage = (e) => {
2227
+ if (e.key !== null && e.key !== STORAGE_KEY) return;
2228
+ const stored = this.loadFromStorage();
2229
+ const changed = [];
2230
+ for (const sponsorId of /* @__PURE__ */ new Set([...this.cartsBySponsor.keys(), ...stored.keys()])) {
2231
+ if (this.hasMutationsInFlight(sponsorId) || this.cartIdPromises.has(sponsorId)) continue;
2232
+ const mine = this.cartsBySponsor.get(sponsorId);
2233
+ const theirs = stored.get(sponsorId);
2234
+ if (JSON.stringify(mine ?? null) === JSON.stringify(theirs ?? null)) continue;
2235
+ if (theirs) this.cartsBySponsor.set(sponsorId, theirs);
2236
+ else this.cartsBySponsor.delete(sponsorId);
2237
+ changed.push(sponsorId);
2238
+ }
2239
+ if (changed.length === 0) return;
2240
+ this.emit();
2241
+ for (const sponsorId of changed) this.emitCartUpdated(sponsorId, "storage");
2242
+ };
2217
2243
  this.cartsBySponsor = this.loadFromStorage();
2244
+ if (typeof window !== "undefined" && typeof window.addEventListener === "function") {
2245
+ window.addEventListener("storage", this.onStorage);
2246
+ }
2218
2247
  }
2219
2248
  nextSeq(sponsorId) {
2220
2249
  const n = (this.mutationSeq.get(sponsorId) ?? 0) + 1;
@@ -2374,6 +2403,9 @@ var CartManager = class extends EventTarget {
2374
2403
  * Overwrite local cart state with the backend cart response (source of
2375
2404
  * truth). `opts.settling` is the mutation whose answer this is: it does not
2376
2405
  * count as "in flight" for the origins (see `hasMutationsInFlight`).
2406
+ * `opts.authoritative` is a GetCart taken with nothing of this tab's in
2407
+ * flight (`refreshFromServer`): an empty answer then means the cart IS
2408
+ * empty, and the local lines go — not an add still on its way.
2377
2409
  */
2378
2410
  updateFromBackendCart(sponsorId, backendCart, opts = {}) {
2379
2411
  const cart = this.cartsBySponsor.get(sponsorId);
@@ -2389,7 +2421,7 @@ var CartManager = class extends EventTarget {
2389
2421
  const removedBeforeSync = [];
2390
2422
  if (Array.isArray(backendCart.line_items)) {
2391
2423
  const existingItems = cart.items || [];
2392
- if (backendCart.line_items.length === 0 && existingItems.length > 0) {
2424
+ if (backendCart.line_items.length === 0 && existingItems.length > 0 && !opts.authoritative) {
2393
2425
  this.persist();
2394
2426
  this.emit();
2395
2427
  return;
@@ -2743,6 +2775,60 @@ var CartManager = class extends EventTarget {
2743
2775
  if (resCart) this.updateFromBackendCart(sponsorId, resCart);
2744
2776
  return resCart;
2745
2777
  }
2778
+ /**
2779
+ * The cart as the server has it, for the moment a checkout is about to be
2780
+ * built on it: what the shopper is about to pay must be what the page shows.
2781
+ * Waits for this tab's own mutations (their answers are the server's too),
2782
+ * then applies GetCart as it is — a line another tab added, one it removed,
2783
+ * an empty cart — and tells the page: `change` for the drawer, and
2784
+ * `vio:cart-updated` on `document` (`source: 'server'`) for a host that
2785
+ * draws its own. A mutation that starts while the server is answering makes
2786
+ * that answer old: it is asked once more. Nothing to ask without a backend
2787
+ * cart. A GetCart that fails leaves the local state as it was and does not
2788
+ * throw — the checkout then goes on with the lines the last mutation
2789
+ * answered, as it always did. Resolves with the sponsor's cart.
2790
+ */
2791
+ async refreshFromServer(sponsorId) {
2792
+ for (let attempt = 0; attempt < 2; attempt++) {
2793
+ await this.waitForCartMutations(sponsorId);
2794
+ const cart = this.cartsBySponsor.get(sponsorId);
2795
+ if (!cart?.cartId) return cart;
2796
+ let resCart;
2797
+ try {
2798
+ const gqlOpts = await getCartGraphQLOptions(sponsorId);
2799
+ resCart = await getCart(cart.cartId, gqlOpts);
2800
+ } catch (err) {
2801
+ if (typeof console !== "undefined") {
2802
+ console.warn("[CartManager] GetCart before the checkout failed \u2014 the local cart stands", err);
2803
+ }
2804
+ return cart;
2805
+ }
2806
+ if (this.hasMutationsInFlight(sponsorId)) continue;
2807
+ const backendCart = resCart;
2808
+ if (backendCart && Array.isArray(backendCart.line_items)) {
2809
+ this.updateFromBackendCart(sponsorId, backendCart, { authoritative: true });
2810
+ this.emitCartUpdated(sponsorId, "server");
2811
+ }
2812
+ return this.cartsBySponsor.get(sponsorId);
2813
+ }
2814
+ return this.cartsBySponsor.get(sponsorId);
2815
+ }
2816
+ /** `vio:cart-updated` on `document` — see `CartUpdatedDetail`. */
2817
+ emitCartUpdated(sponsorId, source) {
2818
+ if (typeof document === "undefined") return;
2819
+ const cart = this.cartsBySponsor.get(sponsorId);
2820
+ const items = (cart?.items ?? []).map((item) => ({ ...item }));
2821
+ const detail = {
2822
+ sponsorId,
2823
+ cartId: cart?.cartId,
2824
+ items,
2825
+ itemCount: items.reduce((count, item) => count + item.quantity, 0),
2826
+ subtotal: items.reduce((sum, item) => sum + item.unitPrice * item.quantity, 0),
2827
+ currency: cart?.currency || getGlobalCurrency(),
2828
+ source
2829
+ };
2830
+ document.dispatchEvent(new CustomEvent("vio:cart-updated", { bubbles: true, detail }));
2831
+ }
2746
2832
  /** Line items grouped by supplier (shipping is per-supplier server-side). */
2747
2833
  async fetchLineItemsBySupplier(sponsorId) {
2748
2834
  const cart = this.cartsBySponsor.get(sponsorId);
@@ -2930,6 +3016,15 @@ function urlOrNull(value) {
2930
3016
  const v = value.trim();
2931
3017
  return v ? v : null;
2932
3018
  }
3019
+ function pageUrlOrNull(value) {
3020
+ const v = urlOrNull(value);
3021
+ if (!v) return null;
3022
+ try {
3023
+ return new URL(v).protocol === "https:" ? v : null;
3024
+ } catch {
3025
+ return null;
3026
+ }
3027
+ }
2933
3028
  function nameOf(value) {
2934
3029
  return typeof value === "string" ? value.trim() : "";
2935
3030
  }
@@ -2958,7 +3053,16 @@ function sponsorIdentityFrom(boot, sponsorId) {
2958
3053
  const name = nameOf(sponsor.name);
2959
3054
  const logoUrl = urlOrNull(sponsor.logoUrl);
2960
3055
  if (!name && !logoUrl) return null;
2961
- return { id, name, logoUrl, avatarUrl: urlOrNull(sponsor.avatarUrl) };
3056
+ const termsUrl = pageUrlOrNull(sponsor.termsUrl);
3057
+ const refundPolicyUrl = pageUrlOrNull(sponsor.refundPolicyUrl);
3058
+ return {
3059
+ id,
3060
+ name,
3061
+ logoUrl,
3062
+ avatarUrl: urlOrNull(sponsor.avatarUrl),
3063
+ ...termsUrl ? { termsUrl } : {},
3064
+ ...refundPolicyUrl ? { refundPolicyUrl } : {}
3065
+ };
2962
3066
  } catch {
2963
3067
  return null;
2964
3068
  }
@@ -3249,7 +3353,7 @@ async function prepareApplePay(config) {
3249
3353
  }
3250
3354
 
3251
3355
  // src/core/version.ts
3252
- var SDK_VERSION = "0.27.0";
3356
+ var SDK_VERSION = "0.29.0";
3253
3357
 
3254
3358
  // src/core/checkout/payments/stripe-embedded.ts
3255
3359
  var CREATE_PAYMENT_INTENT_STRIPE_MUTATION = `
@@ -4711,6 +4815,11 @@ function adyenReturnUrl(params) {
4711
4815
  bare.search = "";
4712
4816
  return build(bare);
4713
4817
  }
4818
+ function paymentMethodName(method) {
4819
+ if (typeof method !== "string") return void 0;
4820
+ const name = method.trim().toLowerCase().replace(/\s+/g, "-");
4821
+ return name || void 0;
4822
+ }
4714
4823
  function resolveHttpsReturnUrl(overrideUrl, params = null) {
4715
4824
  let url = overrideUrl ?? void 0;
4716
4825
  if (!url && typeof window !== "undefined" && window.location) {
@@ -4753,6 +4862,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4753
4862
  this.currentStateValue = null;
4754
4863
  /** The last checkout + identity written to the memory — the state is set on every keystroke of the form. */
4755
4864
  this.lastRememberedSponsor = "";
4865
+ /** Backend checkouts this page load announced with `vio:checkout-created`: one event each. */
4866
+ this.announcedCheckouts = /* @__PURE__ */ new Set();
4756
4867
  /** Counts `open()` calls — see CheckoutState.session. */
4757
4868
  this.sessionSeq = 0;
4758
4869
  this.applePayAvailableCache = null;
@@ -4791,10 +4902,15 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4791
4902
  this.paymentMethodsCache = /* @__PURE__ */ new Map();
4792
4903
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
4793
4904
  this.paymentMethodsPromises = /* @__PURE__ */ new Map();
4905
+ /** What the open checkout's cart looked like when it was last emitted. */
4906
+ this.lastCartSignature = null;
4794
4907
  /** In-flight `getOrderReference` per checkout id (see there). */
4795
4908
  this.referenceInFlight = /* @__PURE__ */ new Map();
4796
4909
  this.kustomController = null;
4797
4910
  preloadStripeJs();
4911
+ if (typeof cartManager.addEventListener === "function") {
4912
+ cartManager.addEventListener("change", () => this.onCartChange());
4913
+ }
4798
4914
  }
4799
4915
  /**
4800
4916
  * Every write of the state goes through here: a state that names its
@@ -4808,6 +4924,21 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4808
4924
  this.currentStateValue = next;
4809
4925
  if (next?.checkoutId && next.sponsorId) this.rememberSponsorOfCheckout(next.checkoutId, next.sponsorId);
4810
4926
  }
4927
+ /** The open checkout's lines as a signature, to tell a real change from an echo. */
4928
+ cartSignature(sponsorId) {
4929
+ return (this.cartManager.getCart(sponsorId)?.items ?? []).map((i) => `${i.productId}:${i.variantId ?? ""}:${i.quantity}:${i.unitPrice}`).join("|");
4930
+ }
4931
+ /** The open checkout follows its cart: subtotal recomputed and `change` said when the lines differ. */
4932
+ onCartChange() {
4933
+ const state = this.state;
4934
+ if (!state) return;
4935
+ const subtotal = this.cartManager.subtotalForSponsor(state.sponsorId);
4936
+ const signature = this.cartSignature(state.sponsorId);
4937
+ if (subtotal === state.subtotal && signature === this.lastCartSignature) return;
4938
+ this.lastCartSignature = signature;
4939
+ this.state = { ...state, subtotal };
4940
+ this.emit();
4941
+ }
4811
4942
  open(sponsorId) {
4812
4943
  const cart = this.cartManager.getCart(sponsorId);
4813
4944
  if (!cart || cart.items.length === 0) {
@@ -4821,6 +4952,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4821
4952
  // the host may have switched currency since the cart was created.
4822
4953
  currency: getGlobalCurrency()
4823
4954
  };
4955
+ this.lastCartSignature = this.cartSignature(sponsorId);
4824
4956
  this.emit();
4825
4957
  return this.state;
4826
4958
  }
@@ -4845,9 +4977,15 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4845
4977
  return void 0;
4846
4978
  }
4847
4979
  }
4848
- /** Create the backend checkout for the sponsor's cart (auto-accepts terms); born attributed when the facade knows the attribution. */
4849
- async createCheckout(sponsorId) {
4980
+ /**
4981
+ * Create the backend checkout for the sponsor's cart (auto-accepts terms);
4982
+ * born attributed when the facade knows the attribution. `paymentMethod` is
4983
+ * the method it is created to pay with, when the caller knows it (else the
4984
+ * state's): it goes on `vio:checkout-created`.
4985
+ */
4986
+ async createCheckout(sponsorId, paymentMethod) {
4850
4987
  await this.cartManager.waitForCartMutations(sponsorId);
4988
+ await this.cartManager.refreshFromServer(sponsorId);
4851
4989
  const cart = this.cartManager.getCart(sponsorId);
4852
4990
  let cartId = cart?.cartId;
4853
4991
  if (!cartId) {
@@ -4867,6 +5005,9 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4867
5005
  checkout
4868
5006
  };
4869
5007
  this.emit();
5008
+ this.announceCheckout(checkout.id, sponsorId, paymentMethod ?? this.state?.paymentMethod, {
5009
+ campaignId: attribution?.campaign_id
5010
+ });
4870
5011
  try {
4871
5012
  const updated = await updateCheckout(
4872
5013
  {
@@ -4889,6 +5030,35 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
4889
5030
  }
4890
5031
  return checkout;
4891
5032
  }
5033
+ /**
5034
+ * `vio:checkout-created` on `window` — `{ sponsorId, checkoutId,
5035
+ * paymentMethod, campaignId?, redirect }` — the moment a backend checkout
5036
+ * exists for a payment, before anything is asked of the provider. Analytics
5037
+ * answers it with `add_payment_info` (ADR-0039: the one link from the
5038
+ * order Commerce confirms back to this browser's session); `redirect: true`
5039
+ * when the page is about to leave for the provider. Once per checkout per
5040
+ * page load; never throws.
5041
+ */
5042
+ announceCheckout(checkoutId, sponsorId, paymentMethod, opts = {}) {
5043
+ if (!checkoutId || this.announcedCheckouts.has(checkoutId)) return;
5044
+ this.announcedCheckouts.add(checkoutId);
5045
+ if (typeof window === "undefined" || typeof window.dispatchEvent !== "function") return;
5046
+ const method = paymentMethodName(paymentMethod);
5047
+ try {
5048
+ window.dispatchEvent(
5049
+ new CustomEvent("vio:checkout-created", {
5050
+ detail: {
5051
+ sponsorId,
5052
+ checkoutId,
5053
+ ...method ? { paymentMethod: method } : {},
5054
+ ...typeof opts.campaignId === "number" ? { campaignId: opts.campaignId } : {},
5055
+ redirect: opts.redirect === true
5056
+ }
5057
+ })
5058
+ );
5059
+ } catch {
5060
+ }
5061
+ }
4892
5062
  /** Update the backend checkout (terms are re-asserted unless overridden; the attribution rides along unless the caller gives its own). */
4893
5063
  async updateCheckout(variables, sponsorId) {
4894
5064
  const spId = sponsorId ?? this.state?.sponsorId;
@@ -5118,10 +5288,11 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5118
5288
  * backend cart + checkout exist, push email/address onto the checkout, and
5119
5289
  * return everything the payment mutation needs.
5120
5290
  */
5121
- async prepareRedirectPayment(sponsorId, formData, extraUpdateVars = {}) {
5291
+ async prepareRedirectPayment(sponsorId, formData, extraUpdateVars = {}, leaving = false) {
5122
5292
  const spId = sponsorId ?? this.state?.sponsorId;
5123
5293
  if (!spId) throw new Error("[CheckoutManager] no sponsor for payment");
5124
5294
  await this.cartManager.waitForCartMutations(spId);
5295
+ await this.cartManager.refreshFromServer(spId);
5125
5296
  const cart = this.cartManager.getCart(spId);
5126
5297
  let cartId = cart?.cartId;
5127
5298
  if (!cartId) {
@@ -5136,6 +5307,10 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5136
5307
  if (!checkoutId) {
5137
5308
  const checkoutRes = attribution ? await createCheckout(cartId, opts, { attribution }) : await createCheckout(cartId, opts);
5138
5309
  checkoutId = checkoutRes?.id;
5310
+ this.announceCheckout(checkoutId, spId, String(extraUpdateVars.paymentMethod ?? "") || this.state?.paymentMethod, {
5311
+ redirect: leaving,
5312
+ campaignId: attribution?.campaign_id
5313
+ });
5139
5314
  }
5140
5315
  if (!checkoutId) {
5141
5316
  throw new Error("[CheckoutManager] no backend checkout \u2014 cannot start the payment");
@@ -5204,7 +5379,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5204
5379
  const { spId, checkoutId, emailVal, opts } = await this.prepareRedirectPayment(
5205
5380
  sponsorId,
5206
5381
  formData,
5207
- { paymentMethod: "Stripe" }
5382
+ { paymentMethod: "Stripe" },
5383
+ true
5208
5384
  );
5209
5385
  const successUrl = resolveHttpsReturnUrl(null, {
5210
5386
  vio_payment: "success",
@@ -5243,7 +5419,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5243
5419
  const { spId, checkoutId, emailVal, opts } = await this.prepareRedirectPayment(
5244
5420
  sponsorId,
5245
5421
  formData,
5246
- { paymentMethod: "Vipps" }
5422
+ { paymentMethod: "Vipps" },
5423
+ true
5247
5424
  );
5248
5425
  const returnUrl = resolveHttpsReturnUrl(null, {
5249
5426
  vio_payment: "success",
@@ -5300,7 +5477,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5300
5477
  const opts = await getCartGraphQLOptions(spId);
5301
5478
  let checkoutId = this.state?.checkoutId;
5302
5479
  if (!checkoutId) {
5303
- const checkoutRes = await this.createCheckout(spId);
5480
+ const checkoutRes = await this.createCheckout(spId, "kustom");
5304
5481
  checkoutId = checkoutRes?.id;
5305
5482
  if (checkoutId && this.state) {
5306
5483
  this.state = { ...this.state, checkoutId };
@@ -5376,7 +5553,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5376
5553
  const opts = await getCartGraphQLOptions(spId);
5377
5554
  let checkoutId = this.state?.checkoutId;
5378
5555
  if (!checkoutId) {
5379
- const checkoutRes = await this.createCheckout(spId);
5556
+ const checkoutRes = await this.createCheckout(spId, "qliro");
5380
5557
  checkoutId = checkoutRes?.id;
5381
5558
  if (checkoutId && this.state) {
5382
5559
  this.state = { ...this.state, checkoutId };
@@ -5464,7 +5641,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5464
5641
  const opts = await getCartGraphQLOptions(spId);
5465
5642
  let checkoutId = this.state?.checkoutId;
5466
5643
  if (!checkoutId) {
5467
- const checkoutRes = await this.createCheckout(spId);
5644
+ const checkoutRes = await this.createCheckout(spId, "walley");
5468
5645
  checkoutId = checkoutRes?.id;
5469
5646
  if (checkoutId && this.state) {
5470
5647
  this.state = { ...this.state, checkoutId };
@@ -5533,7 +5710,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
5533
5710
  if (this.state) this.state = { ...this.state, checkoutId };
5534
5711
  }
5535
5712
  if (!checkoutId) {
5536
- const checkoutRes = await this.createCheckout(spId);
5713
+ const checkoutRes = await this.createCheckout(spId, "nexi");
5537
5714
  checkoutId = checkoutRes?.id;
5538
5715
  if (checkoutId && this.state) {
5539
5716
  this.state = { ...this.state, checkoutId };
@@ -6098,7 +6275,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
6098
6275
  return async (raw) => {
6099
6276
  let checkoutId = this.state?.checkoutId;
6100
6277
  if (!checkoutId) {
6101
- const created = await this.createCheckout(spId);
6278
+ const created = await this.createCheckout(spId, "apple-pay");
6102
6279
  checkoutId = created?.id ?? this.state?.checkoutId;
6103
6280
  }
6104
6281
  if (!checkoutId) {
@@ -6150,7 +6327,12 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
6150
6327
  );
6151
6328
  }
6152
6329
  const buyerRef = normalizeBuyerRef(confirmRes?.[BUYER_REF_FIELD]);
6153
- return { orderId: confirmRes?.order_id, status: confirmRes?.status, ...buyerRef ? { buyerRef } : {} };
6330
+ return {
6331
+ orderId: confirmRes?.order_id,
6332
+ status: confirmRes?.status,
6333
+ checkoutId,
6334
+ ...buyerRef ? { buyerRef } : {}
6335
+ };
6154
6336
  };
6155
6337
  }
6156
6338
  static {
@@ -6325,7 +6507,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
6325
6507
  }
6326
6508
  let checkoutId = ctx.checkoutId ?? this.state.checkoutId;
6327
6509
  try {
6328
- const checkoutRes = await this.createCheckout(sponsorId);
6510
+ const checkoutRes = await this.createCheckout(sponsorId, "klarna");
6329
6511
  if (checkoutRes?.id) {
6330
6512
  checkoutId = checkoutRes.id;
6331
6513
  ctx.checkoutId = checkoutRes.id;
@@ -6377,6 +6559,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
6377
6559
  if (nativeRes.checkout_id) {
6378
6560
  ctx.checkoutId = nativeRes.checkout_id;
6379
6561
  this.state = { ...this.state, checkoutId: nativeRes.checkout_id };
6562
+ this.announceCheckout(nativeRes.checkout_id, sponsorId, "klarna");
6380
6563
  }
6381
6564
  if (nativeRes.session_id) {
6382
6565
  ctx.sessionId = nativeRes.session_id;
@@ -6474,7 +6657,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
6474
6657
  try {
6475
6658
  let checkoutId = ctx.checkoutId ?? this.state.checkoutId;
6476
6659
  try {
6477
- const checkoutRes = await this.createCheckout(sponsorId);
6660
+ const checkoutRes = await this.createCheckout(sponsorId, "klarna");
6478
6661
  if (checkoutRes?.id) {
6479
6662
  checkoutId = checkoutRes.id;
6480
6663
  ctx.checkoutId = checkoutRes.id;
@@ -6520,6 +6703,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
6520
6703
  if (nativeRes.checkout_id) {
6521
6704
  ctx.checkoutId = nativeRes.checkout_id;
6522
6705
  this.state = { ...this.state, checkoutId: nativeRes.checkout_id };
6706
+ this.announceCheckout(nativeRes.checkout_id, sponsorId, "klarna");
6523
6707
  }
6524
6708
  if (nativeRes.session_id) {
6525
6709
  ctx.sessionId = nativeRes.session_id;
@@ -6979,6 +7163,8 @@ function hasExplicitCampaign(lines) {
6979
7163
  }
6980
7164
 
6981
7165
  // src/core/analytics/analytics-manager.ts
7166
+ var ORDER_NUMBER_BACKOFF_MS = [500, 1e3, 2e3, 3e3, 3e3];
7167
+ var ORDER_NUMBER_MAX_WAIT_MS = 1e4;
6982
7168
  var SESSION_TTL_MS = 30 * 60 * 1e3;
6983
7169
  var FLUSH_INTERVAL_MS = 5e3;
6984
7170
  var FLUSH_AT_COUNT = 20;
@@ -7013,6 +7199,14 @@ var AnalyticsManager = class extends EventTarget {
7013
7199
  this.client = null;
7014
7200
  /** The landing it was read from — persisted later when consent arrives after the first event. */
7015
7201
  this.landing = null;
7202
+ /** Checkouts (`c:<id>`) and orders (`o:<number>`) this page load reported a `purchase` for: one each. */
7203
+ this.purchased = /* @__PURE__ */ new Set();
7204
+ /** Checkouts this page load reported an `add_payment_info` for: one each. */
7205
+ this.paymentInfoReported = /* @__PURE__ */ new Set();
7206
+ /** Purchases still waiting for Vio's order number: each sends at once, with what it has, when called. */
7207
+ this.pendingPurchases = /* @__PURE__ */ new Set();
7208
+ /** Between `pagehide` and `pageshow` (bfcache): nothing waits, it all goes out now. */
7209
+ this.pageHiding = false;
7016
7210
  this.teardown = [];
7017
7211
  }
7018
7212
  /** The landing this manager resolved on this page load (the first event's), or null before it; read only — for the order's entry context when nothing is stored yet. */
@@ -7062,15 +7256,32 @@ var AnalyticsManager = class extends EventTarget {
7062
7256
  this.ensureSession();
7063
7257
  this.flushTimer = setInterval(() => void this.flush(), FLUSH_INTERVAL_MS);
7064
7258
  const onPageHide = () => {
7259
+ this.pageHiding = true;
7260
+ this.settlePendingPurchases();
7065
7261
  this.trackSessionEnd();
7066
7262
  this.flushWithBeacon();
7067
7263
  };
7264
+ const onPageShow = () => {
7265
+ this.pageHiding = false;
7266
+ };
7068
7267
  window.addEventListener("pagehide", onPageHide);
7268
+ window.addEventListener("pageshow", onPageShow);
7069
7269
  this.teardown.push(() => window.removeEventListener("pagehide", onPageHide));
7270
+ this.teardown.push(() => window.removeEventListener("pageshow", onPageShow));
7271
+ if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
7272
+ const onVisibility = () => {
7273
+ if (document.visibilityState !== "hidden") return;
7274
+ this.settlePendingPurchases();
7275
+ this.flushWithBeacon();
7276
+ };
7277
+ document.addEventListener("visibilitychange", onVisibility);
7278
+ this.teardown.push(() => document.removeEventListener("visibilitychange", onVisibility));
7279
+ }
7070
7280
  if (this.options.autoTrack) this.installAutoListeners();
7071
7281
  }
7072
- /** Stop timers + listeners (tests / SPA unmount). Queue survives. */
7282
+ /** Stop timers + listeners (tests / SPA unmount). Queue survives — a purchase still waiting for its order number joins it now. */
7073
7283
  stop() {
7284
+ this.settlePendingPurchases();
7074
7285
  if (this.flushTimer) clearInterval(this.flushTimer);
7075
7286
  this.flushTimer = null;
7076
7287
  for (const fn of this.teardown.splice(0)) fn();
@@ -7083,7 +7294,10 @@ var AnalyticsManager = class extends EventTarget {
7083
7294
  /** Queue one event. Works pre-init and pre-start (SSR: no-op). */
7084
7295
  track(name, opts = {}) {
7085
7296
  if (!hasDom()) return;
7086
- const event = this.buildEvent(name, opts);
7297
+ this.record(this.buildEvent(name, opts));
7298
+ }
7299
+ /** The sinks and the queue for one built event — `track`'s second half. */
7300
+ record(event) {
7087
7301
  if (!event) return;
7088
7302
  if (this.options.debug) {
7089
7303
  console.debug("[Vio.analytics]", event.name, event);
@@ -7230,6 +7444,8 @@ var AnalyticsManager = class extends EventTarget {
7230
7444
  value: com.value,
7231
7445
  currency: com.currency,
7232
7446
  order_id: com.orderId,
7447
+ // A uuid always fits; anything over the collector's 128 is left out, not cut.
7448
+ checkout_id: fitsId(com.checkoutId),
7233
7449
  payment_method: com.paymentMethod,
7234
7450
  // Only a reference survives — never an email, whatever a host passes —
7235
7451
  // and only with consent to persist: a visit measured with ephemeral
@@ -7467,34 +7683,173 @@ var AnalyticsManager = class extends EventTarget {
7467
7683
  ...snap || buyerId !== void 0 ? { commerce: { ...snap ?? {}, ...buyer } } : {}
7468
7684
  });
7469
7685
  });
7470
- on("vio:payment-success", (ev) => {
7686
+ on("vio:checkout-created", (ev) => {
7471
7687
  const d = ev.detail ?? {};
7472
- const sponsorId = d.sponsorId !== void 0 ? Number(d.sponsorId) : void 0;
7688
+ const checkoutId = firstId(d.checkoutId);
7689
+ if (!checkoutId || this.paymentInfoReported.has(checkoutId)) return;
7690
+ this.paymentInfoReported.add(checkoutId);
7691
+ const sponsorId = toNumber(d.sponsorId);
7473
7692
  const base = { sponsorId, campaignId: campaignOf(d), slot: slotOf(d), ...contentOf(d) };
7693
+ const payment = {
7694
+ checkoutId,
7695
+ ...typeof d.paymentMethod === "string" && d.paymentMethod ? { paymentMethod: d.paymentMethod } : {}
7696
+ };
7474
7697
  const { slices, explicit } = this.cartSlices(sponsorId);
7475
7698
  if (slices.length > 1) {
7476
7699
  for (const slice of slices) {
7477
- this.track("purchase", {
7700
+ this.track("add_payment_info", {
7478
7701
  context: this.sliceContext(slice, base),
7479
- commerce: { ...sliceCommerce(slice), ...purchaseFromPaymentSuccess(d), paymentMethod: d.method },
7702
+ commerce: { ...sliceCommerce(slice), ...payment },
7480
7703
  props: { slice: slice.slice, slices: slice.slices }
7481
7704
  });
7482
7705
  }
7483
- return;
7706
+ } else {
7707
+ this.track("add_payment_info", {
7708
+ context: this.singleSliceContext(slices[0], explicit, base),
7709
+ commerce: { ...this.cartCommerce(sponsorId) ?? {}, ...payment }
7710
+ });
7484
7711
  }
7485
- const snap = this.cartCommerce(sponsorId);
7486
- this.track("purchase", {
7487
- context: this.singleSliceContext(slices[0], explicit, base),
7488
- commerce: {
7712
+ if (d.redirect === true) this.flushWithBeacon();
7713
+ });
7714
+ on("vio:payment-success", (ev) => {
7715
+ const d = ev.detail ?? {};
7716
+ const ids = purchaseIdsOf(d);
7717
+ if (!this.claimPurchase(ids)) return;
7718
+ const sponsorId = d.sponsorId !== void 0 ? Number(d.sponsorId) : void 0;
7719
+ const base = { sponsorId, campaignId: campaignOf(d), slot: slotOf(d), ...contentOf(d) };
7720
+ const { slices, explicit } = this.cartSlices(sponsorId);
7721
+ const parts = slices.length > 1 ? (
7722
+ // Several campaigns paid in one go: one purchase per campaign — its
7723
+ // items and value, the SAME order_id — so each campaign's revenue is
7724
+ // its own and the order still adds up. `props.slice/slices` lets the
7725
+ // collector count the order once.
7726
+ slices.map((slice) => ({
7727
+ context: this.sliceContext(slice, base),
7728
+ commerce: { ...sliceCommerce(slice), paymentMethod: d.method },
7729
+ props: { slice: slice.slice, slices: slice.slices }
7730
+ }))
7731
+ ) : [
7732
+ {
7733
+ context: this.singleSliceContext(slices[0], explicit, base),
7489
7734
  // value / currency / items: the cart snapshot, on every path.
7490
- ...snap ?? {},
7491
- // order_id: Vio's id for the purchase (never the provider's).
7492
- ...purchaseFromPaymentSuccess(d),
7493
- paymentMethod: d.method
7735
+ commerce: { ...this.cartCommerce(sponsorId) ?? {}, paymentMethod: d.method }
7494
7736
  }
7495
- });
7737
+ ];
7738
+ this.reportPurchase(parts, ids, buyerRefOf(d), sponsorId);
7496
7739
  });
7497
7740
  }
7741
+ /**
7742
+ * Claims the purchase of a payment for this page load: false when its
7743
+ * checkout (or its order) already has one, reported or waiting.
7744
+ */
7745
+ claimPurchase(ids) {
7746
+ const keys = [];
7747
+ if (ids.checkoutId) keys.push(`c:${ids.checkoutId}`);
7748
+ if (ids.orderIdKind === "order" && ids.orderId) keys.push(`o:${ids.orderId}`);
7749
+ if (keys.some((key) => this.purchased.has(key))) return false;
7750
+ for (const key of keys) this.purchased.add(key);
7751
+ return true;
7752
+ }
7753
+ /**
7754
+ * Sends the `purchase` event(s) of one payment — ONCE, with Vio's order
7755
+ * number as `order_id` (`props.order_id_kind: 'order'`) and the checkout id
7756
+ * as `checkout_id`. When the payment event did not bring the number (a
7757
+ * redirect return, an order a webhook creates) the checkout is asked for it
7758
+ * — the receipt's own path, `Vio.checkout.getOrderReference` — at once and
7759
+ * after 0.5 / 1 / 2 / 3 / 3 s, for at most 10 s; nothing else waits for it.
7760
+ * Unanswered, or when the page hides or `stop()` comes first, the events go
7761
+ * out with what they have: the checkout id as `order_id`
7762
+ * (`order_id_kind: 'checkout'`), as before — and the late number adds no
7763
+ * second event. The events are BUILT at the payment — its moment (`ts`),
7764
+ * `event_id`, session, page and content — and only the order number (and a
7765
+ * buyer reference the payment did not bring) is filled in when it comes.
7766
+ */
7767
+ reportPurchase(parts, ids, buyerId, sponsorId) {
7768
+ const events = parts.map(
7769
+ (part) => this.buildEvent("purchase", {
7770
+ ...part,
7771
+ commerce: {
7772
+ ...part.commerce,
7773
+ ...ids.orderId !== void 0 ? { orderId: ids.orderId } : {},
7774
+ ...ids.checkoutId !== void 0 ? { checkoutId: ids.checkoutId } : {},
7775
+ ...buyerId !== void 0 ? { buyerId } : {}
7776
+ },
7777
+ ...ids.orderIdKind ? { props: { ...part.props, order_id_kind: ids.orderIdKind } } : {}
7778
+ })
7779
+ );
7780
+ const send = (found = {}) => {
7781
+ if (found.orderNumber) this.purchased.add(`o:${found.orderNumber}`);
7782
+ const lateBuyer = this.canPersist ? normalizeBuyerRef(found.buyerRef) : void 0;
7783
+ for (const event of events) {
7784
+ if (!event) continue;
7785
+ if (found.orderNumber) {
7786
+ event.commerce = { ...event.commerce, order_id: found.orderNumber };
7787
+ event.props = { ...event.props, order_id_kind: "order" };
7788
+ }
7789
+ if (lateBuyer && event.commerce && event.commerce.buyer_id === void 0) {
7790
+ event.commerce = { ...event.commerce, buyer_id: lateBuyer };
7791
+ }
7792
+ this.record(event);
7793
+ }
7794
+ this.sendNow();
7795
+ };
7796
+ const ask = ids.orderIdKind === "checkout" ? this.orderReferenceAsker(ids.checkoutId, sponsorId) : null;
7797
+ if (!ask) {
7798
+ send();
7799
+ return;
7800
+ }
7801
+ if (this.isPageHidden()) {
7802
+ send();
7803
+ return;
7804
+ }
7805
+ let done = false;
7806
+ const settle = (found) => {
7807
+ if (done) return;
7808
+ done = true;
7809
+ this.pendingPurchases.delete(settleNow);
7810
+ send(found);
7811
+ };
7812
+ const settleNow = () => settle();
7813
+ this.pendingPurchases.add(settleNow);
7814
+ void waitForOrderNumber(ask, () => done).then(settle, () => settle());
7815
+ }
7816
+ /**
7817
+ * Sends the queue now, not at the next tick: by beacon when the page is
7818
+ * hidden or going away (a request may not survive it), else by fetch.
7819
+ */
7820
+ sendNow() {
7821
+ if (this.isPageHidden()) this.flushWithBeacon();
7822
+ else void this.flush();
7823
+ }
7824
+ /** Sends every purchase still waiting for its order number, at once, with what it has. */
7825
+ settlePendingPurchases() {
7826
+ for (const settle of [...this.pendingPurchases]) settle();
7827
+ }
7828
+ /** Whether the page is hidden or going away (`pagehide` until `pageshow`). */
7829
+ isPageHidden() {
7830
+ if (this.pageHiding) return true;
7831
+ try {
7832
+ return typeof document !== "undefined" && document.visibilityState === "hidden";
7833
+ } catch {
7834
+ return false;
7835
+ }
7836
+ }
7837
+ /**
7838
+ * How a purchase asks a checkout for Vio's order number: through the SDK's
7839
+ * checkout manager (`getOrderReference`, which never throws and shares its
7840
+ * in-flight ask with the receipt's). `null` when there is nothing to ask —
7841
+ * no checkout id, or no checkout manager on this page.
7842
+ */
7843
+ orderReferenceAsker(checkoutId, sponsorId) {
7844
+ if (!checkoutId) return null;
7845
+ try {
7846
+ const checkout = vioFacade()?.checkout;
7847
+ if (!checkout || typeof checkout.getOrderReference !== "function") return null;
7848
+ return () => checkout.getOrderReference(checkoutId, sponsorId || void 0);
7849
+ } catch {
7850
+ return null;
7851
+ }
7852
+ }
7498
7853
  /** The lines of the cart (current, else the pre-clear snapshot), optionally one sponsor's. */
7499
7854
  cartLines(sponsorId) {
7500
7855
  let items = [];
@@ -7728,15 +8083,63 @@ function buyerRefOf(d) {
7728
8083
  }
7729
8084
  return void 0;
7730
8085
  }
7731
- function purchaseFromPaymentSuccess(d) {
8086
+ function purchaseIdsOf(d) {
8087
+ if (!d) return {};
7732
8088
  const r = d.result ?? {};
7733
- const orderId = firstId(d.orderId, r.confirmation?.orderId, d.checkoutId);
8089
+ const legacy = firstId(d.orderId);
8090
+ const legacyIsNumber = legacy !== void 0 && isOrderNumber(legacy);
8091
+ const orderNumber = firstId(d.orderNumber, r.confirmation?.orderId, legacyIsNumber ? legacy : void 0);
8092
+ const checkoutId = firstId(legacyIsNumber ? void 0 : legacy, d.checkoutId, r.confirmation?.checkoutId);
8093
+ if (orderNumber !== void 0) {
8094
+ return { orderId: orderNumber, ...checkoutId !== void 0 ? { checkoutId } : {}, orderIdKind: "order" };
8095
+ }
8096
+ if (checkoutId !== void 0) return { orderId: checkoutId, checkoutId, orderIdKind: "checkout" };
8097
+ return {};
8098
+ }
8099
+ function purchaseFromPaymentSuccess(d) {
8100
+ const { orderId, checkoutId } = purchaseIdsOf(d);
7734
8101
  const buyerId = buyerRefOf(d);
7735
8102
  return {
7736
8103
  ...orderId !== void 0 ? { orderId } : {},
8104
+ ...checkoutId !== void 0 ? { checkoutId } : {},
7737
8105
  ...buyerId !== void 0 ? { buyerId } : {}
7738
8106
  };
7739
8107
  }
8108
+ function isOrderNumber(value) {
8109
+ return /^[1-9][0-9]*$/.test(value);
8110
+ }
8111
+ async function waitForOrderNumber(ask, stopped) {
8112
+ let deadline;
8113
+ const timeUp = new Promise((resolve) => {
8114
+ deadline = setTimeout(() => resolve(null), ORDER_NUMBER_MAX_WAIT_MS);
8115
+ });
8116
+ let buyerRef;
8117
+ const found = (orderNumber) => ({
8118
+ ...orderNumber ? { orderNumber } : {},
8119
+ ...buyerRef ? { buyerRef } : {}
8120
+ });
8121
+ try {
8122
+ for (let attempt = 0; attempt <= ORDER_NUMBER_BACKOFF_MS.length; attempt++) {
8123
+ if (attempt > 0) {
8124
+ const wait = ORDER_NUMBER_BACKOFF_MS[attempt - 1];
8125
+ const slept = await Promise.race([new Promise((resolve) => setTimeout(() => resolve(true), wait)), timeUp]);
8126
+ if (slept === null) break;
8127
+ }
8128
+ if (stopped()) break;
8129
+ try {
8130
+ const reference = await Promise.race([ask(), timeUp]);
8131
+ if (reference === null) break;
8132
+ buyerRef ??= normalizeBuyerRef(reference?.buyerRef);
8133
+ const orderNumber = firstId(reference?.orderNumber);
8134
+ if (orderNumber !== void 0 && isOrderNumber(orderNumber)) return found(orderNumber);
8135
+ } catch {
8136
+ }
8137
+ }
8138
+ return found();
8139
+ } finally {
8140
+ clearTimeout(deadline);
8141
+ }
8142
+ }
7740
8143
  function firstId(...candidates) {
7741
8144
  for (const c of candidates) {
7742
8145
  if (c === void 0 || c === null) continue;
@@ -7753,6 +8156,7 @@ function pushGa4(event) {
7753
8156
  "add_to_cart",
7754
8157
  "view_cart",
7755
8158
  "begin_checkout",
8159
+ "add_payment_info",
7756
8160
  "purchase"
7757
8161
  ]);
7758
8162
  if (!commerceNames.has(event.name)) return;
@@ -7766,6 +8170,7 @@ function pushGa4(event) {
7766
8170
  currency: commerce.currency,
7767
8171
  value: commerce.value,
7768
8172
  transaction_id: commerce.order_id,
8173
+ payment_type: event.name === "add_payment_info" ? commerce.payment_method : void 0,
7769
8174
  items: commerce.items?.map(
7770
8175
  (i) => compact({
7771
8176
  item_id: i.product_id,
@@ -8589,6 +8994,6 @@ function vippsButtonAttributes(verb = "buy", opts = {}) {
8589
8994
  };
8590
8995
  }
8591
8996
 
8592
- export { ADD_ITEM_MUTATION, ADYEN_RETURN_METHOD, ADYEN_RETURN_QUERY_KEYS, AdyenOriginError, AnalyticsManager, BUYER_REF_MAX_LENGTH, CHECKOUT_ATTRIBUTION_CAPS, CHECKOUT_SPONSOR_STORAGE_KEY, CLIENT_LANDING_URL_MAX_LENGTH, CONTENT_URL_MAX_LENGTH, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, CartManager, CheckoutManager, CommerceClient, Configuration, DELETE_ITEM_MUTATION, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, GRAPHQL_INT_MAX, KUSTOM_RETURN_QUERY_KEYS, LINE_ORIGIN_CAPS, SDK_VERSION, UPDATE_CHECKOUT_MUTATION, UPDATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_ITEM_WITH_ORIGIN_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, VIPPS_BUTTON_SCRIPT, VIPPS_BUTTON_TAG, Vio, VioApi, VioApiError, __decorateClass, activeCampaignEntry, addItem, adyenReturnOutcome, adyenReturnParams, autoSlotDisplayName, autoSlotId, buyerRefOf, campaignCandidates, capContentUrl, cartSlicesFrom, checkApplePayAvailability, checkoutAttributionOf, checkoutSponsorOf, componentKindOf, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, dominantCampaignOf, ensureVippsButton, entryContextOf, executeCartGraphQL, formatPrice, gatewayHas, gatewayHasBuyerRef, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCheckoutReference, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, isUnknownFeatureError, isUnknownTokenError, kustomReturnOutcome, landingUrl, lineOriginWire, lineOrigins, nexiReturnPaymentId, normalizeBuyerRef, normalizeOrigin, normalizeScope, normalizeSlotId, normalizeSlotKind, originAndPath, primaryImageUrl, purchaseFromPaymentSuccess, readNexiPending, rememberedCheckoutSponsor, resetGatewayFeatures, resolveCampaignId, resolveClientContext, resolveContent, resolveLanding, resolveSlotCampaign, sameOrigin, showApplePaySheet, sponsorCampaignEntry, sponsorIdentityFrom, storedLanding, toCampaignId, updateCheckout, updateItem, updateShippingsBySupplier, vippsButtonAttributes, withGatewayFeature };
8593
- //# sourceMappingURL=chunk-HJRIPCWB.js.map
8594
- //# sourceMappingURL=chunk-HJRIPCWB.js.map
8997
+ export { ADD_ITEM_MUTATION, ADYEN_RETURN_METHOD, ADYEN_RETURN_QUERY_KEYS, AdyenOriginError, AnalyticsManager, BUYER_REF_MAX_LENGTH, CHECKOUT_ATTRIBUTION_CAPS, CHECKOUT_SPONSOR_STORAGE_KEY, CLIENT_LANDING_URL_MAX_LENGTH, CONTENT_URL_MAX_LENGTH, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, CartManager, CheckoutManager, CommerceClient, Configuration, DELETE_ITEM_MUTATION, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, GRAPHQL_INT_MAX, KUSTOM_RETURN_QUERY_KEYS, LINE_ORIGIN_CAPS, SDK_VERSION, UPDATE_CHECKOUT_MUTATION, UPDATE_CHECKOUT_WITH_ATTRIBUTION_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_ITEM_WITH_ORIGIN_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, VIPPS_BUTTON_SCRIPT, VIPPS_BUTTON_TAG, Vio, VioApi, VioApiError, __decorateClass, activeCampaignEntry, addItem, adyenReturnOutcome, adyenReturnParams, autoSlotDisplayName, autoSlotId, buyerRefOf, campaignCandidates, capContentUrl, cartSlicesFrom, checkApplePayAvailability, checkoutAttributionOf, checkoutSponsorOf, componentKindOf, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, dominantCampaignOf, ensureVippsButton, entryContextOf, executeCartGraphQL, formatPrice, gatewayHas, gatewayHasBuyerRef, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCheckoutReference, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, isUnknownFeatureError, isUnknownTokenError, kustomReturnOutcome, landingUrl, lineOriginWire, lineOrigins, nexiReturnPaymentId, normalizeBuyerRef, normalizeOrigin, normalizeScope, normalizeSlotId, normalizeSlotKind, originAndPath, primaryImageUrl, purchaseFromPaymentSuccess, purchaseIdsOf, readNexiPending, rememberedCheckoutSponsor, resetGatewayFeatures, resolveCampaignId, resolveClientContext, resolveContent, resolveLanding, resolveSlotCampaign, sameOrigin, showApplePaySheet, sponsorCampaignEntry, sponsorIdentityFrom, storedLanding, toCampaignId, updateCheckout, updateItem, updateShippingsBySupplier, vippsButtonAttributes, withGatewayFeature };
8998
+ //# sourceMappingURL=chunk-AG4G2S2M.js.map
8999
+ //# sourceMappingURL=chunk-AG4G2S2M.js.map