@vio-live/web-sdk 0.28.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.
- package/CHANGELOG.md +72 -2
- package/README.md +69 -0
- package/dist/{chunk-AFJ5M53F.js → chunk-AG4G2S2M.js} +219 -18
- package/dist/chunk-AG4G2S2M.js.map +1 -0
- package/dist/{chunk-Q2NALS7P.js → chunk-L6YYYKQK.js} +76 -12
- package/dist/chunk-L6YYYKQK.js.map +1 -0
- package/dist/core/index.d.ts +81 -5
- package/dist/core/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +3 -3
- package/dist/{tokens-y0KzN7bP.d.ts → tokens-Dok4d21V.d.ts} +28 -0
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-AFJ5M53F.js.map +0 -1
- package/dist/chunk-Q2NALS7P.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -14,9 +14,79 @@ How to keep this file: see [CONTRIBUTING → Changelog](CONTRIBUTING.md#changelo
|
|
|
14
14
|
The details of each feature live in the [README](README.md); this file says *what*
|
|
15
15
|
and *when*, and links there.
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## 0.29.0 — 2026-10-24
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
### Added
|
|
20
|
+
- **`vio:cart-updated`** on `document` — `{ sponsorId, cartId, items, itemCount, subtotal, currency, source }`,
|
|
21
|
+
`source: 'server'` when the cart was just read from the server (right before a checkout is
|
|
22
|
+
created or a payment link minted, and when the drawer or the checkout opens), `'storage'` when
|
|
23
|
+
another tab of the site changed it. For hosts that draw their own cart or badge.
|
|
24
|
+
`Vio.cart.refreshFromServer(sponsorId)` asks on demand. See
|
|
25
|
+
[README → What the shopper pays is what the page shows](README.md#what-the-shopper-pays-is-what-the-page-shows--the-cart-the-server-the-other-tabs).
|
|
26
|
+
- **`add_payment_info`** (analytics, GA4 name) the moment a backend checkout exists for a payment
|
|
27
|
+
— Vipps from the detail, the cart or the checkout, a Stripe payment link or Element, Klarna,
|
|
28
|
+
Apple Pay, Nexi, Kustom, Qliro, Walley, Adyen — with `commerce.checkout_id`, `payment_method`,
|
|
29
|
+
the cart's lines and the same context as `begin_checkout` (per campaign like it). Once per
|
|
30
|
+
checkout per page load, none when the checkout could not be created, and by beacon BEFORE the
|
|
31
|
+
page leaves for Vipps or a Stripe link. It is how a paid order whose `purchase` never came back
|
|
32
|
+
keeps its session, page and slot (ADR-0039; order 4128, 2026-10-23). The checkout manager
|
|
33
|
+
announces it on `window` as **`vio:checkout-created`** `{ sponsorId, checkoutId, paymentMethod,
|
|
34
|
+
campaignId?, redirect }`. See [README → `add_payment_info`](README.md#add_payment_info--the-checkout-linked-to-this-session-0290).
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
- **«Kjøp nå med Vipps» on the product detail goes straight to Vipps only when the cart is
|
|
38
|
+
empty.** With lines already in the cart, the product is added and the checkout opens first
|
|
39
|
+
(`vio:checkout-open`, Vipps preselected, no `vio:payment-redirect-*` events), every line and
|
|
40
|
+
the total on screen. Before, the tap paid the WHOLE cart with only the Vipps page saying so
|
|
41
|
+
(Mote & Livsstil, 2026-10-23: a jumper left in the cart 13 minutes earlier was paid along
|
|
42
|
+
with the top bought «nå»). The cart's own Vipps button is unchanged: it pays the lines it shows.
|
|
43
|
+
- **Apple Pay on the product detail shows what it charges.** The sheet's amount is fixed before
|
|
44
|
+
the tap and was the product's price, while the charge was the sponsor's whole cart. The sheet
|
|
45
|
+
now opens only on an empty cart, prepared for the product × the chosen quantity (it is prepared
|
|
46
|
+
again when the quantity or variant changes); with lines already in the cart — or while the
|
|
47
|
+
sheet for a new quantity is still being prepared — the product is added and the checkout opens
|
|
48
|
+
(`vio:checkout-open` with `paymentMethod: 'apple-pay'`), where Apple Pay charges the total shown.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
- **The lines the shopper pays for are the lines the page shows.** The checkout, and the
|
|
52
|
+
Vipps / Stripe page, are built on the backend cart — every line in it — while the drawer
|
|
53
|
+
and the checkout summary drew this tab's memory. Now the SDK reads the server's cart right
|
|
54
|
+
before a checkout is created or a payment link minted, and when `<vio-cart>` / `<vio-checkout>`
|
|
55
|
+
open, and draws that; an open checkout recomputes its lines and total when the cart changes
|
|
56
|
+
under it.
|
|
57
|
+
- **Other tabs of the site are heard.** The carts are shared through `localStorage` but each
|
|
58
|
+
tab read them once, at load: a payment in one tab left the others showing — and adding to —
|
|
59
|
+
a cart that was already paid; a line added in one tab was missing from the others until a
|
|
60
|
+
reload. Now a tab adopts what another tab wrote (`storage` event), except for a sponsor it is
|
|
61
|
+
mid-add for.
|
|
62
|
+
- **Vipps Express: the checkout no longer adds our shipping to the total.** The delivery is
|
|
63
|
+
chosen and paid inside Vipps, but with Vipps selected the checkout still added the seller's
|
|
64
|
+
first rate (Careless QA, 2026-10-24: «Frakt – Default Shipping» 10 kr, 1 308 kr on screen and
|
|
65
|
+
on the button, 1 298 kr in Vipps). With Vipps as the method and Express on for the seller,
|
|
66
|
+
the summary says «Frakt: Velges i Vipps» and the total and «Betal … med Vipps» are the items.
|
|
67
|
+
Vipps without Express, and every other method, still add the rate as before.
|
|
68
|
+
- **The `purchase` of a paid return is sent, not left in the queue** (2026-10-24). Order 4128
|
|
69
|
+
(Careless, prod, 2026-10-23 22:40, after two abandoned trips to Vipps): the shopper
|
|
70
|
+
paid, came back, saw the confirmation, and the brand's panel never counted the sale — Commerce
|
|
71
|
+
had its `order_paid`, the collector no `purchase`. The return was read as paid; the one way the
|
|
72
|
+
code loses that purchase is the queue: it was built, with the order number, into a queue sent
|
|
73
|
+
every 5 s, and leaving the page right away (back to the Vipps app, the home screen) beaconed
|
|
74
|
+
only a purchase still waiting for its number — a phone that discards a hidden tab never runs
|
|
75
|
+
the next tick. Now the purchase is sent as soon as it is built, and when the page hides
|
|
76
|
+
everything still queued leaves by beacon.
|
|
77
|
+
|
|
78
|
+
### ⚠️ Upgrade notes
|
|
79
|
+
- **The collector must accept `add_payment_info`** before it is counted: one that does not know the
|
|
80
|
+
name rejects that event alone (`202` with `rejected`), the rest of the batch is kept. Nothing to
|
|
81
|
+
do in the host.
|
|
82
|
+
- A host that handles `vio:checkout-open` only from the cart: the product detail now emits it
|
|
83
|
+
too when «Kjøp nå med Vipps» or Apple Pay is tapped on a non-empty cart (it already did when
|
|
84
|
+
Express was off for the seller), now also with `paymentMethod: 'apple-pay'`. Check that your
|
|
85
|
+
handler opens `<vio-checkout>` for the detail's event.
|
|
86
|
+
- A host with its own cart drawer or badge: listen to `vio:cart-updated` (or `Vio.cart`'s
|
|
87
|
+
`change`) — the lines can now change without a tap in that tab.
|
|
88
|
+
- One more `GetCart` per checkout creation / payment link and per opening of the drawer or the
|
|
89
|
+
checkout.
|
|
20
90
|
|
|
21
91
|
## 0.28.0 — 2026-10-22
|
|
22
92
|
|
package/README.md
CHANGED
|
@@ -487,11 +487,38 @@ could never be netted.
|
|
|
487
487
|
arrives after the event left with the checkout id adds no second event. `ts`
|
|
488
488
|
and `event_id` are fixed at the payment, whenever the event leaves; a purchase
|
|
489
489
|
split per campaign waits once and every slice carries the same number.
|
|
490
|
+
- **Sent at once.** A `purchase` does not wait for the queue's 5 s tick: it is
|
|
491
|
+
sent as soon as it is built, and when the page hides (`visibilitychange`, the
|
|
492
|
+
last thing a phone is sure to say before it discards a tab) whatever is still
|
|
493
|
+
queued leaves by beacon (0.29.0; order 4128 had been recorded and never sent).
|
|
490
494
|
- **A host with its own sink** (Vev) reads the same ids from the detail with
|
|
491
495
|
`purchaseIdsOf(detail)` → `{ orderId, checkoutId, orderIdKind }` (or
|
|
492
496
|
`purchaseFromPaymentSuccess(detail)`, exported from `/core`), and waits for the
|
|
493
497
|
number the same way through `Vio.checkout.getOrderReference(checkoutId)`.
|
|
494
498
|
|
|
499
|
+
### `add_payment_info` — the checkout, linked to this session (0.29.0)
|
|
500
|
+
|
|
501
|
+
The moment a backend checkout exists for a payment — Vipps (from the product
|
|
502
|
+
detail, the cart or the checkout), a Stripe payment link or Element, Klarna, Apple
|
|
503
|
+
Pay, Nexi, Kustom, Qliro, Walley, Adyen — the SDK emits **`add_payment_info`**
|
|
504
|
+
(the GA4 name) with **`commerce.checkout_id`**, **`payment_method`**, the cart's
|
|
505
|
+
lines (`items`, `value`, `currency`) and the same context as `begin_checkout`
|
|
506
|
+
(sponsor, campaign, slot, content), split per campaign like it. Once per checkout
|
|
507
|
+
per page load; nothing when the checkout could not be created. When the page is
|
|
508
|
+
about to leave for the provider (Vipps, a Stripe payment link) it goes out by
|
|
509
|
+
beacon first.
|
|
510
|
+
|
|
511
|
+
Why (ADR-0039): Commerce's `order_paid` is what says a sale happened, and the
|
|
512
|
+
browser's `purchase` can be missing (a closed tab, a phone that discards the page
|
|
513
|
+
on the way back). The collector attributes an `order_paid` without a `purchase` to
|
|
514
|
+
the session, page and slot of the `add_payment_info` with the same `checkout_id`.
|
|
515
|
+
|
|
516
|
+
The checkout manager announces each checkout on `window` as
|
|
517
|
+
**`vio:checkout-created`** — `{ sponsorId, checkoutId, paymentMethod, campaignId?,
|
|
518
|
+
redirect }` — which is what analytics listens to; a host with its own sink can
|
|
519
|
+
listen to it too. With `dataLayer: true` it is pushed as GA4's `add_payment_info`
|
|
520
|
+
with `payment_type`.
|
|
521
|
+
|
|
495
522
|
## Sponsor identity — name and logo
|
|
496
523
|
|
|
497
524
|
The elements say **who sells**: the sponsor's (brand's) display name and logo.
|
|
@@ -674,6 +701,48 @@ tap, so a second payment cannot start. Events on `document`:
|
|
|
674
701
|
`source` is `'detail'`, `'cart'` or `'checkout'`. The overlay is `.vio-redirect-overlay`
|
|
675
702
|
in the light DOM.
|
|
676
703
|
|
|
704
|
+
**The detail's Vipps button pays the whole cart.** «Kjøp nå med Vipps» on the product
|
|
705
|
+
detail adds the product to the sponsor's cart and the checkout is built on that cart —
|
|
706
|
+
every line in it. It goes straight to Vipps only when the cart was **empty**; with lines
|
|
707
|
+
already in it, the product is added and the checkout opens first (`vio:checkout-open`
|
|
708
|
+
with `paymentMethod: 'vipps'`, no hand-over events), every line and the total on screen,
|
|
709
|
+
so what the Vipps page lists is what the shopper saw. The cart's own Vipps button always
|
|
710
|
+
pays the whole cart — the lines are right there. **Apple Pay on the detail follows the same
|
|
711
|
+
rule**: its sheet's amount is fixed before the tap, so it opens only on an empty cart, for the
|
|
712
|
+
product × the chosen quantity; otherwise the checkout opens (`paymentMethod: 'apple-pay'`).
|
|
713
|
+
|
|
714
|
+
### What the shopper pays is what the page shows — the cart, the server, the other tabs
|
|
715
|
+
|
|
716
|
+
The cart lives in this tab's memory and in `localStorage` (`vio.cart.v1`, one entry per
|
|
717
|
+
sponsor with the backend cart id), and the checkout — and the Vipps / Stripe page — is
|
|
718
|
+
built on the **backend** cart, every line of it. Three things keep the two the same:
|
|
719
|
+
|
|
720
|
+
- **Before a checkout is created or a payment link minted**, and **when `<vio-cart>` or
|
|
721
|
+
`<vio-checkout>` opens**, the SDK asks the server for the cart (`GetCart`) and draws that
|
|
722
|
+
answer: a line another tab added, a cart another tab emptied. `Vio.cart.refreshFromServer(sponsorId)`
|
|
723
|
+
does the same on demand and resolves with the sponsor's cart. A `GetCart` that fails leaves
|
|
724
|
+
the cart as it was (and warns) — the checkout then goes on with the lines the last mutation
|
|
725
|
+
answered, as before.
|
|
726
|
+
- **Other tabs of the site are heard.** A payment in one tab (its cart cleared) empties the
|
|
727
|
+
drawer of the others and the next add there opens a new backend cart; a line added in one
|
|
728
|
+
tab is in the others without a reload. Through the browser's `storage` event — a tab that
|
|
729
|
+
is mid-add for a sponsor keeps its own lines until its answer lands.
|
|
730
|
+
- **An open checkout follows its cart**: its lines and its total are recomputed when the
|
|
731
|
+
cart changes under it (the widgets that captured an amount at mount ask to be refreshed,
|
|
732
|
+
as they already did for a changed cart).
|
|
733
|
+
|
|
734
|
+
`vio:cart-updated` on `document` says when either of the first two happened:
|
|
735
|
+
|
|
736
|
+
```ts
|
|
737
|
+
document.addEventListener('vio:cart-updated', (e) => {
|
|
738
|
+
const { sponsorId, cartId, items, itemCount, subtotal, currency, source } = e.detail
|
|
739
|
+
// source: 'server' (GetCart, right before a checkout / on opening) | 'storage' (another tab)
|
|
740
|
+
})
|
|
741
|
+
```
|
|
742
|
+
|
|
743
|
+
`items` are copies of the lines (`CartLineItem[]`). A host that draws its own cart or badge
|
|
744
|
+
redraws it from this event; `<vio-cart>` and the badge wired to `Vio.cart`'s `change` need nothing.
|
|
745
|
+
|
|
677
746
|
## Headless / SSR
|
|
678
747
|
|
|
679
748
|
The root and `/core` entries export the framework-agnostic core with **no DOM side-effects** — SSR-safe and **tree-shakeable** (importing one helper pulls only that helper, ~0.5 kB):
|
|
@@ -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);
|
|
@@ -3267,7 +3353,7 @@ async function prepareApplePay(config) {
|
|
|
3267
3353
|
}
|
|
3268
3354
|
|
|
3269
3355
|
// src/core/version.ts
|
|
3270
|
-
var SDK_VERSION = "0.
|
|
3356
|
+
var SDK_VERSION = "0.29.0";
|
|
3271
3357
|
|
|
3272
3358
|
// src/core/checkout/payments/stripe-embedded.ts
|
|
3273
3359
|
var CREATE_PAYMENT_INTENT_STRIPE_MUTATION = `
|
|
@@ -4729,6 +4815,11 @@ function adyenReturnUrl(params) {
|
|
|
4729
4815
|
bare.search = "";
|
|
4730
4816
|
return build(bare);
|
|
4731
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
|
+
}
|
|
4732
4823
|
function resolveHttpsReturnUrl(overrideUrl, params = null) {
|
|
4733
4824
|
let url = overrideUrl ?? void 0;
|
|
4734
4825
|
if (!url && typeof window !== "undefined" && window.location) {
|
|
@@ -4771,6 +4862,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4771
4862
|
this.currentStateValue = null;
|
|
4772
4863
|
/** The last checkout + identity written to the memory — the state is set on every keystroke of the form. */
|
|
4773
4864
|
this.lastRememberedSponsor = "";
|
|
4865
|
+
/** Backend checkouts this page load announced with `vio:checkout-created`: one event each. */
|
|
4866
|
+
this.announcedCheckouts = /* @__PURE__ */ new Set();
|
|
4774
4867
|
/** Counts `open()` calls — see CheckoutState.session. */
|
|
4775
4868
|
this.sessionSeq = 0;
|
|
4776
4869
|
this.applePayAvailableCache = null;
|
|
@@ -4809,10 +4902,15 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4809
4902
|
this.paymentMethodsCache = /* @__PURE__ */ new Map();
|
|
4810
4903
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4811
4904
|
this.paymentMethodsPromises = /* @__PURE__ */ new Map();
|
|
4905
|
+
/** What the open checkout's cart looked like when it was last emitted. */
|
|
4906
|
+
this.lastCartSignature = null;
|
|
4812
4907
|
/** In-flight `getOrderReference` per checkout id (see there). */
|
|
4813
4908
|
this.referenceInFlight = /* @__PURE__ */ new Map();
|
|
4814
4909
|
this.kustomController = null;
|
|
4815
4910
|
preloadStripeJs();
|
|
4911
|
+
if (typeof cartManager.addEventListener === "function") {
|
|
4912
|
+
cartManager.addEventListener("change", () => this.onCartChange());
|
|
4913
|
+
}
|
|
4816
4914
|
}
|
|
4817
4915
|
/**
|
|
4818
4916
|
* Every write of the state goes through here: a state that names its
|
|
@@ -4826,6 +4924,21 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4826
4924
|
this.currentStateValue = next;
|
|
4827
4925
|
if (next?.checkoutId && next.sponsorId) this.rememberSponsorOfCheckout(next.checkoutId, next.sponsorId);
|
|
4828
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
|
+
}
|
|
4829
4942
|
open(sponsorId) {
|
|
4830
4943
|
const cart = this.cartManager.getCart(sponsorId);
|
|
4831
4944
|
if (!cart || cart.items.length === 0) {
|
|
@@ -4839,6 +4952,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4839
4952
|
// the host may have switched currency since the cart was created.
|
|
4840
4953
|
currency: getGlobalCurrency()
|
|
4841
4954
|
};
|
|
4955
|
+
this.lastCartSignature = this.cartSignature(sponsorId);
|
|
4842
4956
|
this.emit();
|
|
4843
4957
|
return this.state;
|
|
4844
4958
|
}
|
|
@@ -4863,9 +4977,15 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4863
4977
|
return void 0;
|
|
4864
4978
|
}
|
|
4865
4979
|
}
|
|
4866
|
-
/**
|
|
4867
|
-
|
|
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) {
|
|
4868
4987
|
await this.cartManager.waitForCartMutations(sponsorId);
|
|
4988
|
+
await this.cartManager.refreshFromServer(sponsorId);
|
|
4869
4989
|
const cart = this.cartManager.getCart(sponsorId);
|
|
4870
4990
|
let cartId = cart?.cartId;
|
|
4871
4991
|
if (!cartId) {
|
|
@@ -4885,6 +5005,9 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4885
5005
|
checkout
|
|
4886
5006
|
};
|
|
4887
5007
|
this.emit();
|
|
5008
|
+
this.announceCheckout(checkout.id, sponsorId, paymentMethod ?? this.state?.paymentMethod, {
|
|
5009
|
+
campaignId: attribution?.campaign_id
|
|
5010
|
+
});
|
|
4888
5011
|
try {
|
|
4889
5012
|
const updated = await updateCheckout(
|
|
4890
5013
|
{
|
|
@@ -4907,6 +5030,35 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
4907
5030
|
}
|
|
4908
5031
|
return checkout;
|
|
4909
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
|
+
}
|
|
4910
5062
|
/** Update the backend checkout (terms are re-asserted unless overridden; the attribution rides along unless the caller gives its own). */
|
|
4911
5063
|
async updateCheckout(variables, sponsorId) {
|
|
4912
5064
|
const spId = sponsorId ?? this.state?.sponsorId;
|
|
@@ -5136,10 +5288,11 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5136
5288
|
* backend cart + checkout exist, push email/address onto the checkout, and
|
|
5137
5289
|
* return everything the payment mutation needs.
|
|
5138
5290
|
*/
|
|
5139
|
-
async prepareRedirectPayment(sponsorId, formData, extraUpdateVars = {}) {
|
|
5291
|
+
async prepareRedirectPayment(sponsorId, formData, extraUpdateVars = {}, leaving = false) {
|
|
5140
5292
|
const spId = sponsorId ?? this.state?.sponsorId;
|
|
5141
5293
|
if (!spId) throw new Error("[CheckoutManager] no sponsor for payment");
|
|
5142
5294
|
await this.cartManager.waitForCartMutations(spId);
|
|
5295
|
+
await this.cartManager.refreshFromServer(spId);
|
|
5143
5296
|
const cart = this.cartManager.getCart(spId);
|
|
5144
5297
|
let cartId = cart?.cartId;
|
|
5145
5298
|
if (!cartId) {
|
|
@@ -5154,6 +5307,10 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5154
5307
|
if (!checkoutId) {
|
|
5155
5308
|
const checkoutRes = attribution ? await createCheckout(cartId, opts, { attribution }) : await createCheckout(cartId, opts);
|
|
5156
5309
|
checkoutId = checkoutRes?.id;
|
|
5310
|
+
this.announceCheckout(checkoutId, spId, String(extraUpdateVars.paymentMethod ?? "") || this.state?.paymentMethod, {
|
|
5311
|
+
redirect: leaving,
|
|
5312
|
+
campaignId: attribution?.campaign_id
|
|
5313
|
+
});
|
|
5157
5314
|
}
|
|
5158
5315
|
if (!checkoutId) {
|
|
5159
5316
|
throw new Error("[CheckoutManager] no backend checkout \u2014 cannot start the payment");
|
|
@@ -5222,7 +5379,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5222
5379
|
const { spId, checkoutId, emailVal, opts } = await this.prepareRedirectPayment(
|
|
5223
5380
|
sponsorId,
|
|
5224
5381
|
formData,
|
|
5225
|
-
{ paymentMethod: "Stripe" }
|
|
5382
|
+
{ paymentMethod: "Stripe" },
|
|
5383
|
+
true
|
|
5226
5384
|
);
|
|
5227
5385
|
const successUrl = resolveHttpsReturnUrl(null, {
|
|
5228
5386
|
vio_payment: "success",
|
|
@@ -5261,7 +5419,8 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5261
5419
|
const { spId, checkoutId, emailVal, opts } = await this.prepareRedirectPayment(
|
|
5262
5420
|
sponsorId,
|
|
5263
5421
|
formData,
|
|
5264
|
-
{ paymentMethod: "Vipps" }
|
|
5422
|
+
{ paymentMethod: "Vipps" },
|
|
5423
|
+
true
|
|
5265
5424
|
);
|
|
5266
5425
|
const returnUrl = resolveHttpsReturnUrl(null, {
|
|
5267
5426
|
vio_payment: "success",
|
|
@@ -5318,7 +5477,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5318
5477
|
const opts = await getCartGraphQLOptions(spId);
|
|
5319
5478
|
let checkoutId = this.state?.checkoutId;
|
|
5320
5479
|
if (!checkoutId) {
|
|
5321
|
-
const checkoutRes = await this.createCheckout(spId);
|
|
5480
|
+
const checkoutRes = await this.createCheckout(spId, "kustom");
|
|
5322
5481
|
checkoutId = checkoutRes?.id;
|
|
5323
5482
|
if (checkoutId && this.state) {
|
|
5324
5483
|
this.state = { ...this.state, checkoutId };
|
|
@@ -5394,7 +5553,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5394
5553
|
const opts = await getCartGraphQLOptions(spId);
|
|
5395
5554
|
let checkoutId = this.state?.checkoutId;
|
|
5396
5555
|
if (!checkoutId) {
|
|
5397
|
-
const checkoutRes = await this.createCheckout(spId);
|
|
5556
|
+
const checkoutRes = await this.createCheckout(spId, "qliro");
|
|
5398
5557
|
checkoutId = checkoutRes?.id;
|
|
5399
5558
|
if (checkoutId && this.state) {
|
|
5400
5559
|
this.state = { ...this.state, checkoutId };
|
|
@@ -5482,7 +5641,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5482
5641
|
const opts = await getCartGraphQLOptions(spId);
|
|
5483
5642
|
let checkoutId = this.state?.checkoutId;
|
|
5484
5643
|
if (!checkoutId) {
|
|
5485
|
-
const checkoutRes = await this.createCheckout(spId);
|
|
5644
|
+
const checkoutRes = await this.createCheckout(spId, "walley");
|
|
5486
5645
|
checkoutId = checkoutRes?.id;
|
|
5487
5646
|
if (checkoutId && this.state) {
|
|
5488
5647
|
this.state = { ...this.state, checkoutId };
|
|
@@ -5551,7 +5710,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
5551
5710
|
if (this.state) this.state = { ...this.state, checkoutId };
|
|
5552
5711
|
}
|
|
5553
5712
|
if (!checkoutId) {
|
|
5554
|
-
const checkoutRes = await this.createCheckout(spId);
|
|
5713
|
+
const checkoutRes = await this.createCheckout(spId, "nexi");
|
|
5555
5714
|
checkoutId = checkoutRes?.id;
|
|
5556
5715
|
if (checkoutId && this.state) {
|
|
5557
5716
|
this.state = { ...this.state, checkoutId };
|
|
@@ -6116,7 +6275,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
6116
6275
|
return async (raw) => {
|
|
6117
6276
|
let checkoutId = this.state?.checkoutId;
|
|
6118
6277
|
if (!checkoutId) {
|
|
6119
|
-
const created = await this.createCheckout(spId);
|
|
6278
|
+
const created = await this.createCheckout(spId, "apple-pay");
|
|
6120
6279
|
checkoutId = created?.id ?? this.state?.checkoutId;
|
|
6121
6280
|
}
|
|
6122
6281
|
if (!checkoutId) {
|
|
@@ -6348,7 +6507,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
6348
6507
|
}
|
|
6349
6508
|
let checkoutId = ctx.checkoutId ?? this.state.checkoutId;
|
|
6350
6509
|
try {
|
|
6351
|
-
const checkoutRes = await this.createCheckout(sponsorId);
|
|
6510
|
+
const checkoutRes = await this.createCheckout(sponsorId, "klarna");
|
|
6352
6511
|
if (checkoutRes?.id) {
|
|
6353
6512
|
checkoutId = checkoutRes.id;
|
|
6354
6513
|
ctx.checkoutId = checkoutRes.id;
|
|
@@ -6400,6 +6559,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
6400
6559
|
if (nativeRes.checkout_id) {
|
|
6401
6560
|
ctx.checkoutId = nativeRes.checkout_id;
|
|
6402
6561
|
this.state = { ...this.state, checkoutId: nativeRes.checkout_id };
|
|
6562
|
+
this.announceCheckout(nativeRes.checkout_id, sponsorId, "klarna");
|
|
6403
6563
|
}
|
|
6404
6564
|
if (nativeRes.session_id) {
|
|
6405
6565
|
ctx.sessionId = nativeRes.session_id;
|
|
@@ -6497,7 +6657,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
6497
6657
|
try {
|
|
6498
6658
|
let checkoutId = ctx.checkoutId ?? this.state.checkoutId;
|
|
6499
6659
|
try {
|
|
6500
|
-
const checkoutRes = await this.createCheckout(sponsorId);
|
|
6660
|
+
const checkoutRes = await this.createCheckout(sponsorId, "klarna");
|
|
6501
6661
|
if (checkoutRes?.id) {
|
|
6502
6662
|
checkoutId = checkoutRes.id;
|
|
6503
6663
|
ctx.checkoutId = checkoutRes.id;
|
|
@@ -6543,6 +6703,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
|
|
|
6543
6703
|
if (nativeRes.checkout_id) {
|
|
6544
6704
|
ctx.checkoutId = nativeRes.checkout_id;
|
|
6545
6705
|
this.state = { ...this.state, checkoutId: nativeRes.checkout_id };
|
|
6706
|
+
this.announceCheckout(nativeRes.checkout_id, sponsorId, "klarna");
|
|
6546
6707
|
}
|
|
6547
6708
|
if (nativeRes.session_id) {
|
|
6548
6709
|
ctx.sessionId = nativeRes.session_id;
|
|
@@ -7040,6 +7201,8 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
7040
7201
|
this.landing = null;
|
|
7041
7202
|
/** Checkouts (`c:<id>`) and orders (`o:<number>`) this page load reported a `purchase` for: one each. */
|
|
7042
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();
|
|
7043
7206
|
/** Purchases still waiting for Vio's order number: each sends at once, with what it has, when called. */
|
|
7044
7207
|
this.pendingPurchases = /* @__PURE__ */ new Set();
|
|
7045
7208
|
/** Between `pagehide` and `pageshow` (bfcache): nothing waits, it all goes out now. */
|
|
@@ -7107,7 +7270,7 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
7107
7270
|
this.teardown.push(() => window.removeEventListener("pageshow", onPageShow));
|
|
7108
7271
|
if (typeof document !== "undefined" && typeof document.addEventListener === "function") {
|
|
7109
7272
|
const onVisibility = () => {
|
|
7110
|
-
if (document.visibilityState !== "hidden"
|
|
7273
|
+
if (document.visibilityState !== "hidden") return;
|
|
7111
7274
|
this.settlePendingPurchases();
|
|
7112
7275
|
this.flushWithBeacon();
|
|
7113
7276
|
};
|
|
@@ -7520,6 +7683,34 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
7520
7683
|
...snap || buyerId !== void 0 ? { commerce: { ...snap ?? {}, ...buyer } } : {}
|
|
7521
7684
|
});
|
|
7522
7685
|
});
|
|
7686
|
+
on("vio:checkout-created", (ev) => {
|
|
7687
|
+
const d = ev.detail ?? {};
|
|
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);
|
|
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
|
+
};
|
|
7697
|
+
const { slices, explicit } = this.cartSlices(sponsorId);
|
|
7698
|
+
if (slices.length > 1) {
|
|
7699
|
+
for (const slice of slices) {
|
|
7700
|
+
this.track("add_payment_info", {
|
|
7701
|
+
context: this.sliceContext(slice, base),
|
|
7702
|
+
commerce: { ...sliceCommerce(slice), ...payment },
|
|
7703
|
+
props: { slice: slice.slice, slices: slice.slices }
|
|
7704
|
+
});
|
|
7705
|
+
}
|
|
7706
|
+
} else {
|
|
7707
|
+
this.track("add_payment_info", {
|
|
7708
|
+
context: this.singleSliceContext(slices[0], explicit, base),
|
|
7709
|
+
commerce: { ...this.cartCommerce(sponsorId) ?? {}, ...payment }
|
|
7710
|
+
});
|
|
7711
|
+
}
|
|
7712
|
+
if (d.redirect === true) this.flushWithBeacon();
|
|
7713
|
+
});
|
|
7523
7714
|
on("vio:payment-success", (ev) => {
|
|
7524
7715
|
const d = ev.detail ?? {};
|
|
7525
7716
|
const ids = purchaseIdsOf(d);
|
|
@@ -7600,6 +7791,7 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
7600
7791
|
}
|
|
7601
7792
|
this.record(event);
|
|
7602
7793
|
}
|
|
7794
|
+
this.sendNow();
|
|
7603
7795
|
};
|
|
7604
7796
|
const ask = ids.orderIdKind === "checkout" ? this.orderReferenceAsker(ids.checkoutId, sponsorId) : null;
|
|
7605
7797
|
if (!ask) {
|
|
@@ -7608,7 +7800,6 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
7608
7800
|
}
|
|
7609
7801
|
if (this.isPageHidden()) {
|
|
7610
7802
|
send();
|
|
7611
|
-
this.flushWithBeacon();
|
|
7612
7803
|
return;
|
|
7613
7804
|
}
|
|
7614
7805
|
let done = false;
|
|
@@ -7622,6 +7813,14 @@ var AnalyticsManager = class extends EventTarget {
|
|
|
7622
7813
|
this.pendingPurchases.add(settleNow);
|
|
7623
7814
|
void waitForOrderNumber(ask, () => done).then(settle, () => settle());
|
|
7624
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
|
+
}
|
|
7625
7824
|
/** Sends every purchase still waiting for its order number, at once, with what it has. */
|
|
7626
7825
|
settlePendingPurchases() {
|
|
7627
7826
|
for (const settle of [...this.pendingPurchases]) settle();
|
|
@@ -7957,6 +8156,7 @@ function pushGa4(event) {
|
|
|
7957
8156
|
"add_to_cart",
|
|
7958
8157
|
"view_cart",
|
|
7959
8158
|
"begin_checkout",
|
|
8159
|
+
"add_payment_info",
|
|
7960
8160
|
"purchase"
|
|
7961
8161
|
]);
|
|
7962
8162
|
if (!commerceNames.has(event.name)) return;
|
|
@@ -7970,6 +8170,7 @@ function pushGa4(event) {
|
|
|
7970
8170
|
currency: commerce.currency,
|
|
7971
8171
|
value: commerce.value,
|
|
7972
8172
|
transaction_id: commerce.order_id,
|
|
8173
|
+
payment_type: event.name === "add_payment_info" ? commerce.payment_method : void 0,
|
|
7973
8174
|
items: commerce.items?.map(
|
|
7974
8175
|
(i) => compact({
|
|
7975
8176
|
item_id: i.product_id,
|
|
@@ -8794,5 +8995,5 @@ function vippsButtonAttributes(verb = "buy", opts = {}) {
|
|
|
8794
8995
|
}
|
|
8795
8996
|
|
|
8796
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 };
|
|
8797
|
-
//# sourceMappingURL=chunk-
|
|
8798
|
-
//# sourceMappingURL=chunk-
|
|
8998
|
+
//# sourceMappingURL=chunk-AG4G2S2M.js.map
|
|
8999
|
+
//# sourceMappingURL=chunk-AG4G2S2M.js.map
|