@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.
- package/CHANGELOG.md +359 -0
- package/README.md +185 -0
- package/dist/{chunk-HJRIPCWB.js → chunk-AG4G2S2M.js} +442 -37
- package/dist/chunk-AG4G2S2M.js.map +1 -0
- package/dist/{chunk-GLAKUYQA.js → chunk-L6YYYKQK.js} +905 -188
- package/dist/chunk-L6YYYKQK.js.map +1 -0
- package/dist/core/index.d.ts +187 -20
- 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-CihuCU2l.d.ts → tokens-Dok4d21V.d.ts} +131 -9
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.js +3 -3
- package/package.json +3 -2
- package/dist/chunk-GLAKUYQA.js.map +0 -1
- package/dist/chunk-HJRIPCWB.js.map +0 -1
|
@@ -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
|
-
|
|
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.
|
|
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
|
-
/**
|
|
4849
|
-
|
|
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 {
|
|
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
|
-
|
|
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:
|
|
7686
|
+
on("vio:checkout-created", (ev) => {
|
|
7471
7687
|
const d = ev.detail ?? {};
|
|
7472
|
-
const
|
|
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("
|
|
7700
|
+
this.track("add_payment_info", {
|
|
7478
7701
|
context: this.sliceContext(slice, base),
|
|
7479
|
-
commerce: { ...sliceCommerce(slice), ...
|
|
7702
|
+
commerce: { ...sliceCommerce(slice), ...payment },
|
|
7480
7703
|
props: { slice: slice.slice, slices: slice.slices }
|
|
7481
7704
|
});
|
|
7482
7705
|
}
|
|
7483
|
-
|
|
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
|
-
|
|
7486
|
-
|
|
7487
|
-
|
|
7488
|
-
|
|
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
|
-
...
|
|
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
|
|
8086
|
+
function purchaseIdsOf(d) {
|
|
8087
|
+
if (!d) return {};
|
|
7732
8088
|
const r = d.result ?? {};
|
|
7733
|
-
const
|
|
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-
|
|
8594
|
-
//# sourceMappingURL=chunk-
|
|
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
|