@vio-live/web-sdk 0.5.1 → 0.7.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.
@@ -2501,6 +2501,96 @@ async function createKlarnaPaymentsWidget(input) {
2501
2501
  };
2502
2502
  }
2503
2503
 
2504
+ // src/core/checkout/payments/kustom.ts
2505
+ var CREATE_PAYMENT_KUSTOM_MUTATION = `
2506
+ mutation CreatePaymentKustom($checkoutId: String!, $countryCode: String!, $href: String!, $email: String) {
2507
+ Payment {
2508
+ CreatePaymentKustom(checkout_id: $checkoutId, country_code: $countryCode, href: $href, email: $email) {
2509
+ order_id
2510
+ status
2511
+ html_snippet
2512
+ purchase_country
2513
+ purchase_currency
2514
+ }
2515
+ }
2516
+ }
2517
+ `;
2518
+ var GET_KUSTOM_ORDER_QUERY = `
2519
+ query GetKustomOrder($orderId: String!) {
2520
+ Payment {
2521
+ GetKustomOrder(order_id: $orderId) {
2522
+ order_id
2523
+ status
2524
+ html_snippet
2525
+ purchase_country
2526
+ purchase_currency
2527
+ }
2528
+ }
2529
+ }
2530
+ `;
2531
+ async function createPaymentKustom(variables, options) {
2532
+ const json = await executeCartGraphQL(CREATE_PAYMENT_KUSTOM_MUTATION, variables, options);
2533
+ return json?.data?.Payment?.CreatePaymentKustom ?? null;
2534
+ }
2535
+ async function getKustomOrder(orderId, options) {
2536
+ const json = await executeCartGraphQL(GET_KUSTOM_ORDER_QUERY, { orderId }, options);
2537
+ return json?.data?.Payment?.GetKustomOrder ?? null;
2538
+ }
2539
+ function kustomCleanHref() {
2540
+ if (typeof window === "undefined" || !window.location) return "";
2541
+ return `${window.location.origin}${window.location.pathname}`;
2542
+ }
2543
+ function renderKustomSnippet(container, htmlSnippet) {
2544
+ container.innerHTML = htmlSnippet;
2545
+ const scripts = Array.from(container.querySelectorAll("script"));
2546
+ for (const oldScript of scripts) {
2547
+ const newScript = document.createElement("script");
2548
+ for (const attr of Array.from(oldScript.attributes)) {
2549
+ newScript.setAttribute(attr.name, attr.value);
2550
+ }
2551
+ newScript.text = oldScript.text;
2552
+ oldScript.parentNode?.replaceChild(newScript, oldScript);
2553
+ }
2554
+ }
2555
+
2556
+ // src/core/checkout/payments/qliro.ts
2557
+ var CREATE_PAYMENT_QLIRO_MUTATION = `
2558
+ mutation CreatePaymentQliro($checkoutId: String!, $countryCode: String!, $href: String!, $email: String) {
2559
+ Payment {
2560
+ CreatePaymentQliro(checkout_id: $checkoutId, country_code: $countryCode, href: $href, email: $email) {
2561
+ order_id
2562
+ status
2563
+ html_snippet
2564
+ purchase_country
2565
+ purchase_currency
2566
+ total_price
2567
+ }
2568
+ }
2569
+ }
2570
+ `;
2571
+ var GET_QLIRO_ORDER_QUERY = `
2572
+ query GetQliroOrder($checkoutId: String!) {
2573
+ Payment {
2574
+ GetQliroOrder(checkout_id: $checkoutId) {
2575
+ order_id
2576
+ status
2577
+ html_snippet
2578
+ purchase_country
2579
+ purchase_currency
2580
+ total_price
2581
+ }
2582
+ }
2583
+ }
2584
+ `;
2585
+ async function createPaymentQliro(variables, options) {
2586
+ const json = await executeCartGraphQL(CREATE_PAYMENT_QLIRO_MUTATION, variables, options);
2587
+ return json?.data?.Payment?.CreatePaymentQliro ?? null;
2588
+ }
2589
+ async function getQliroOrder(checkoutId, options) {
2590
+ const json = await executeCartGraphQL(GET_QLIRO_ORDER_QUERY, { checkoutId }, options);
2591
+ return json?.data?.Payment?.GetQliroOrder ?? null;
2592
+ }
2593
+
2504
2594
  // src/core/checkout/checkout-manager.ts
2505
2595
  function describeError(err) {
2506
2596
  if (err instanceof Error) return err.message;
@@ -3062,6 +3152,103 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
3062
3152
  const opts = await getCartGraphQLOptions(sponsorId ?? this.state?.sponsorId);
3063
3153
  return getVippsStatus({ checkoutId }, opts);
3064
3154
  }
3155
+ /**
3156
+ * Kustom (former Klarna Checkout) — create the KCO order via Vio Commerce
3157
+ * and render its html_snippet into `container`. The widget collects
3158
+ * address, shipping and payment by itself; the SDK renders nothing else.
3159
+ */
3160
+ async mountKustomCheckout(container, sponsorId) {
3161
+ const spId = sponsorId ?? this.state?.sponsorId;
3162
+ if (!spId) throw new Error("[CheckoutManager] no sponsor for Kustom");
3163
+ const cart = this.cartManager.getCart(spId);
3164
+ let cartId = cart?.cartId;
3165
+ if (!cartId) cartId = await this.cartManager.ensureCartId(spId);
3166
+ if (!cartId) {
3167
+ throw new Error(`[CheckoutManager] Failed to obtain cart_id for sponsor ${spId}`);
3168
+ }
3169
+ const opts = await getCartGraphQLOptions(spId);
3170
+ let checkoutId = this.state?.checkoutId;
3171
+ if (!checkoutId) {
3172
+ const checkoutRes = await createCheckout(cartId, opts);
3173
+ checkoutId = checkoutRes?.id;
3174
+ if (checkoutId && this.state) {
3175
+ this.state = { ...this.state, checkoutId };
3176
+ }
3177
+ }
3178
+ if (!checkoutId) {
3179
+ throw new Error("[CheckoutManager] no backend checkout for the Kustom order");
3180
+ }
3181
+ const href = kustomCleanHref();
3182
+ const order = await createPaymentKustom(
3183
+ {
3184
+ checkoutId,
3185
+ countryCode: getGlobalCountryCode(),
3186
+ href,
3187
+ email: this.state?.address?.email || void 0
3188
+ },
3189
+ opts
3190
+ );
3191
+ if (!order?.html_snippet) {
3192
+ throw new Error("Kustom order creation failed: missing html_snippet");
3193
+ }
3194
+ renderKustomSnippet(container, order.html_snippet);
3195
+ return order;
3196
+ }
3197
+ /** Re-read a Kustom order — used on the confirmation return trip. */
3198
+ async getKustomOrder(orderId, sponsorId) {
3199
+ const opts = await getCartGraphQLOptions(sponsorId ?? this.state?.sponsorId);
3200
+ return getKustomOrder(orderId, opts);
3201
+ }
3202
+ /** Render a Kustom html_snippet (e.g. the confirmation receipt) into a container. */
3203
+ renderKustomSnippet(container, htmlSnippet) {
3204
+ renderKustomSnippet(container, htmlSnippet);
3205
+ }
3206
+ /**
3207
+ * Qliro Checkout — create the order via Vio Commerce and render its
3208
+ * html_snippet into `container` (widget-does-everything, like Kustom).
3209
+ */
3210
+ async mountQliroCheckout(container, sponsorId) {
3211
+ const spId = sponsorId ?? this.state?.sponsorId;
3212
+ if (!spId) throw new Error("[CheckoutManager] no sponsor for Qliro");
3213
+ const cart = this.cartManager.getCart(spId);
3214
+ let cartId = cart?.cartId;
3215
+ if (!cartId) cartId = await this.cartManager.ensureCartId(spId);
3216
+ if (!cartId) {
3217
+ throw new Error(`[CheckoutManager] Failed to obtain cart_id for sponsor ${spId}`);
3218
+ }
3219
+ const opts = await getCartGraphQLOptions(spId);
3220
+ let checkoutId = this.state?.checkoutId;
3221
+ if (!checkoutId) {
3222
+ const checkoutRes = await createCheckout(cartId, opts);
3223
+ checkoutId = checkoutRes?.id;
3224
+ if (checkoutId && this.state) {
3225
+ this.state = { ...this.state, checkoutId };
3226
+ }
3227
+ }
3228
+ if (!checkoutId) {
3229
+ throw new Error("[CheckoutManager] no backend checkout for the Qliro order");
3230
+ }
3231
+ const href = kustomCleanHref();
3232
+ const order = await createPaymentQliro(
3233
+ {
3234
+ checkoutId,
3235
+ countryCode: getGlobalCountryCode(),
3236
+ href,
3237
+ email: this.state?.address?.email || void 0
3238
+ },
3239
+ opts
3240
+ );
3241
+ if (!order?.html_snippet) {
3242
+ throw new Error("Qliro order creation failed: missing html_snippet");
3243
+ }
3244
+ renderKustomSnippet(container, order.html_snippet);
3245
+ return order;
3246
+ }
3247
+ /** Re-read the Qliro order owned by a checkout — the confirmation trip. */
3248
+ async getQliroOrder(checkoutId, sponsorId) {
3249
+ const opts = await getCartGraphQLOptions(sponsorId ?? this.state?.sponsorId);
3250
+ return getQliroOrder(checkoutId, opts);
3251
+ }
3065
3252
  /* eslint-enable @typescript-eslint/no-explicit-any */
3066
3253
  setAddress(address) {
3067
3254
  if (!this.state) return;
@@ -3079,14 +3266,38 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
3079
3266
  );
3080
3267
  }
3081
3268
  // MARK: - Apple Pay (Stripe Payment Request)
3269
+ /**
3270
+ * The Stripe publishable key for a sponsor, taken from its own commerce
3271
+ * channel (`GetAvailablePaymentMethods` → Stripe → config.publishableKey).
3272
+ *
3273
+ * The channel is the right source: the key belongs to the brand's Stripe
3274
+ * account, so two brands on one page each get theirs, and a host never has
3275
+ * to configure it. `Vio.init({ stripePublishableKey })` still wins when set,
3276
+ * which keeps existing integrations working and allows an override.
3277
+ */
3278
+ async resolveStripePublishableKey(sponsorId) {
3279
+ const cfg = Configuration.isInitialized ? Configuration.get() : null;
3280
+ if (cfg?.stripePublishableKey) return cfg.stripePublishableKey;
3281
+ if (this.applePayPublishableKey) return this.applePayPublishableKey;
3282
+ try {
3283
+ const methods = await this.getAvailablePaymentMethods(sponsorId);
3284
+ const stripe = methods?.find((m) => String(m?.name ?? "").toLowerCase() === "stripe");
3285
+ const key = stripe?.config?.find((c) => c?.name === "publishableKey")?.value;
3286
+ if (typeof key === "string" && key.startsWith("pk_")) {
3287
+ this.applePayPublishableKey = key;
3288
+ return key;
3289
+ }
3290
+ } catch {
3291
+ }
3292
+ return "";
3293
+ }
3082
3294
  /**
3083
3295
  * Returns true if Apple Pay can be shown on this device + Stripe config.
3084
3296
  * Result is memoised — call `clearApplePayCache()` if config changes.
3085
3297
  */
3086
3298
  async isApplePayAvailable(country = "NO") {
3087
3299
  if (this.applePayAvailableCache !== null) return this.applePayAvailableCache;
3088
- const cfg = Configuration.isInitialized ? Configuration.get() : null;
3089
- const publishableKey = cfg?.stripePublishableKey ?? "";
3300
+ const publishableKey = await this.resolveStripePublishableKey(this.state?.sponsorId);
3090
3301
  if (!publishableKey || !this.state) {
3091
3302
  this.applePayAvailableCache = false;
3092
3303
  return false;
@@ -3115,8 +3326,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
3115
3326
  * `payment-error`. `available` is true only when Apple Pay will actually work.
3116
3327
  */
3117
3328
  async prepareApplePayFor(amount, currency, country = "NO") {
3118
- const cfg = Configuration.isInitialized ? Configuration.get() : null;
3119
- const publishableKey = this.applePayPublishableKey || cfg?.stripePublishableKey || "";
3329
+ const publishableKey = await this.resolveStripePublishableKey(this.state?.sponsorId);
3120
3330
  if (!publishableKey) return { available: false, show: async () => {
3121
3331
  } };
3122
3332
  const prepared = await prepareApplePay({
@@ -3177,8 +3387,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
3177
3387
  * called synchronously inside the tap (Apple's user-gesture rule).
3178
3388
  */
3179
3389
  async prepareApplePayExpress(amount, currency, country = "NO", sponsorId) {
3180
- const cfg = Configuration.isInitialized ? Configuration.get() : null;
3181
- const publishableKey = this.applePayPublishableKey || cfg?.stripePublishableKey || "";
3390
+ const publishableKey = await this.resolveStripePublishableKey(sponsorId ?? this.state?.sponsorId);
3182
3391
  if (!publishableKey) return { available: false, show: async () => null };
3183
3392
  const spId = sponsorId ?? this.state?.sponsorId ?? [...this.cartManager.getAllCarts().keys()][0];
3184
3393
  const prepared = await prepareApplePay({
@@ -3301,8 +3510,7 @@ var CheckoutManager = class _CheckoutManager extends EventTarget {
3301
3510
  async startApplePay(options = {}) {
3302
3511
  if (!this.state) throw new Error("[VioCheckout] no active checkout \u2014 call open() first");
3303
3512
  const spId = options.sponsorId ?? this.state.sponsorId;
3304
- const cfg = Configuration.isInitialized ? Configuration.get() : null;
3305
- const publishableKey = this.applePayPublishableKey || cfg?.stripePublishableKey || "";
3513
+ const publishableKey = await this.resolveStripePublishableKey(spId);
3306
3514
  if (!publishableKey) {
3307
3515
  throw new Error(
3308
3516
  "[VioCheckout] No Stripe publishable key configured. Pass `stripePublishableKey` to Vio.init({ ... })."
@@ -3872,6 +4080,8 @@ var AnalyticsManager = class extends EventTarget {
3872
4080
  this.retryAttempt = 0;
3873
4081
  this.retryNotBefore = 0;
3874
4082
  this.sessionId = null;
4083
+ /** Set via start({ sessionId }) — the host owns the session, we follow. */
4084
+ this.externalSessionId = null;
3875
4085
  this.sessionStartedAt = 0;
3876
4086
  /** Impression once-per-(session, component) guard; reset on session rotation. */
3877
4087
  this.impressedComponents = /* @__PURE__ */ new Set();
@@ -3893,6 +4103,7 @@ var AnalyticsManager = class extends EventTarget {
3893
4103
  debug: options.debug ?? this.options.debug,
3894
4104
  autoTrack: options.autoTrack ?? this.options.autoTrack
3895
4105
  };
4106
+ if (options.sessionId) this.externalSessionId = options.sessionId;
3896
4107
  if (this.started || !hasDom()) return;
3897
4108
  this.started = true;
3898
4109
  this.ensureSession();
@@ -4030,6 +4241,8 @@ var AnalyticsManager = class extends EventTarget {
4030
4241
  sponsor_id: ctx.sponsorId,
4031
4242
  activation_id: ctx.activationId,
4032
4243
  content_url: ctx.contentUrl ?? (typeof location !== "undefined" ? location.href : void 0),
4244
+ // The host's own content id — its join key back onto its reporting.
4245
+ content_id: ctx.contentId,
4033
4246
  // Deletion-proof reporting: sources have no trash bin — the title
4034
4247
  // snapshotted at event time keeps reports legible if content dies.
4035
4248
  content_title: ctx.contentTitle ?? (typeof document !== "undefined" && document.title ? document.title.slice(0, 255) : void 0),
@@ -4101,6 +4314,13 @@ var AnalyticsManager = class extends EventTarget {
4101
4314
  }
4102
4315
  }
4103
4316
  }
4317
+ if (this.externalSessionId) {
4318
+ if (this.sessionId !== this.externalSessionId) {
4319
+ this.sessionId = this.externalSessionId;
4320
+ this.sessionStartedAt = now;
4321
+ this.impressedComponents.clear();
4322
+ }
4323
+ }
4104
4324
  if (!this.sessionId) {
4105
4325
  this.sessionId = `s-${uuid()}`;
4106
4326
  this.sessionStartedAt = now;
@@ -4464,5 +4684,5 @@ var _vioGlobal = globalThis;
4464
4684
  var Vio = _vioGlobal.__VIO_FACADE__ ?? (_vioGlobal.__VIO_FACADE__ = new VioFacade());
4465
4685
 
4466
4686
  export { ADD_ITEM_MUTATION, AnalyticsManager, CREATE_CART_MUTATION, CREATE_CHECKOUT_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, SDK_VERSION, UPDATE_CHECKOUT_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, Vio, VioApi, VioApiError, __decorateClass, addItem, checkApplePayAvailability, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, executeCartGraphQL, formatPrice, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, primaryImageUrl, showApplePaySheet, updateCheckout, updateItem, updateShippingsBySupplier };
4467
- //# sourceMappingURL=chunk-7Q4MJ5NQ.js.map
4468
- //# sourceMappingURL=chunk-7Q4MJ5NQ.js.map
4687
+ //# sourceMappingURL=chunk-4ZEN4J7I.js.map
4688
+ //# sourceMappingURL=chunk-4ZEN4J7I.js.map