@vio-live/web-sdk 0.2.0 → 0.4.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/README.md +29 -2
- package/dist/chunk-NP2KCM7X.js +3859 -0
- package/dist/chunk-NP2KCM7X.js.map +1 -0
- package/dist/chunk-PBQSHIID.js +3 -0
- package/dist/{chunk-GGM2AIK5.js.map → chunk-PBQSHIID.js.map} +1 -1
- package/dist/{chunk-7JSSYPRN.js → chunk-V5ZQG2H5.js} +1419 -169
- package/dist/chunk-V5ZQG2H5.js.map +1 -0
- package/dist/core/index.d.ts +314 -12
- package/dist/core/index.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.js +3 -2
- package/dist/react/index.js.map +1 -1
- package/dist/tokens-CvqQYURw.d.ts +555 -0
- package/dist/ui/index.d.ts +3 -83
- package/dist/ui/index.js +5 -132
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7JSSYPRN.js.map +0 -1
- package/dist/chunk-GGM2AIK5.js +0 -3
- package/dist/chunk-SOO2G6CF.js +0 -1618
- package/dist/chunk-SOO2G6CF.js.map +0 -1
- package/dist/vio-checkout-CrC5tvmh.d.ts +0 -300
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/configuration.ts","../src/core/api/vio.ts","../src/core/api/commerce.ts","../src/core/types.ts","../src/core/cart/cart-manager.ts","../src/core/checkout/payments/apple-pay.ts","../src/core/checkout/payments/klarna.ts","../src/core/checkout/payments/klarna-payments.ts","../src/core/checkout/checkout-manager.ts","../src/core/client.ts"],"names":[],"mappings":"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","file":"chunk-SOO2G6CF.js","sourcesContent":["/**\n * Vio Configuration — singleton holding apiKey, environment, base URLs,\n * and optional payment-vendor publishable keys.\n *\n * Mirrors `VioConfiguration.shared` in the iOS SDK. Initialised once via\n * `Vio.init({ apiKey, ... })`; consumed via `Configuration.get()`.\n *\n * Secrets (apiKey) never come from inside the SDK — the consumer reads\n * them from env vars / their config and passes them to `Vio.init`.\n */\n\nexport type Environment = 'development' | 'testing' | 'production'\n\nexport interface VioConfig {\n /** Vio API key for this client app (from the Vio dashboard). */\n apiKey: string\n /** Target environment. Defaults to 'development'. */\n environment?: Environment\n /** Override REST API base. Defaults are env-aware. */\n apiBase?: string\n /** Override GraphQL base. Defaults are env-aware. */\n graphQLBase?: string\n /**\n * Stripe **publishable** key (`pk_test_xxx` or `pk_live_xxx`). Used for\n * Apple Pay (via Payment Request) and Card flows. Public-safe — fine\n * to expose in client bundles.\n */\n stripePublishableKey?: string\n /**\n * Klarna **Client Identifier** for Express Checkout (KEC). Public-safe.\n * From Merchant Portal → Payment settings → Client Identifiers. When set,\n * the checkout shows the Klarna Express button; when absent it degrades\n * to the plain method selector. Must match `klarnaEnvironment`.\n */\n klarnaClientId?: string\n /**\n * Klarna environment for the Express button. `playground` = sandbox\n * (test orders, no real money), `production` = live. Defaults to\n * `playground` so dev/test never hits live Klarna by accident.\n */\n klarnaEnvironment?: 'playground' | 'production'\n}\n\nexport interface ResolvedConfig {\n apiKey: string\n environment: Environment\n apiBase: string\n graphQLBase: string\n stripePublishableKey?: string\n klarnaClientId?: string\n klarnaEnvironment: 'playground' | 'production'\n}\n\nconst DEFAULT_URLS: Record<Environment, { apiBase: string; graphQLBase: string }> = {\n development: {\n apiBase: 'https://api-dev.vio.live',\n graphQLBase: 'https://graph-ql-dev.vio.live',\n },\n testing: {\n apiBase: 'https://api-dev.vio.live',\n graphQLBase: 'https://graph-ql-dev.vio.live',\n },\n production: {\n apiBase: 'https://api.vio.live',\n graphQLBase: 'https://graph-ql.vio.live',\n },\n}\n\nclass ConfigurationSingleton {\n private resolved: ResolvedConfig | null = null\n\n init(input: VioConfig): void {\n if (!input.apiKey || typeof input.apiKey !== 'string') {\n throw new Error('[Vio] apiKey is required in Vio.init({ apiKey })')\n }\n const env: Environment = input.environment ?? 'development'\n const defaults = DEFAULT_URLS[env]\n this.resolved = {\n apiKey: input.apiKey,\n environment: env,\n apiBase: input.apiBase ?? defaults.apiBase,\n graphQLBase: input.graphQLBase ?? defaults.graphQLBase,\n stripePublishableKey: input.stripePublishableKey,\n klarnaClientId: input.klarnaClientId,\n // Sandbox by default — live Klarna must be opted into explicitly.\n klarnaEnvironment: input.klarnaEnvironment ?? 'playground',\n }\n if (typeof console !== 'undefined') {\n const masked =\n input.apiKey.length > 4\n ? '*'.repeat(Math.max(0, input.apiKey.length - 4)) + input.apiKey.slice(-4)\n : '****'\n console.info('[Vio] Initialized', {\n environment: env,\n apiBase: this.resolved.apiBase,\n apiKey: masked,\n stripeConfigured: !!input.stripePublishableKey,\n klarnaConfigured: !!input.klarnaClientId,\n klarnaEnvironment: this.resolved.klarnaEnvironment,\n })\n }\n }\n\n get(): ResolvedConfig {\n if (!this.resolved) {\n throw new Error(\n '[Vio] Not initialized. Call Vio.init({ apiKey }) before using the SDK.',\n )\n }\n return this.resolved\n }\n\n get isInitialized(): boolean {\n return this.resolved !== null\n }\n\n /** For tests only. */\n reset(): void {\n this.resolved = null\n }\n}\n\nexport const Configuration = /* @__PURE__ */ new ConfigurationSingleton()\n","/**\n * Vio REST API client — talks to `api-dev.vio.live` (or override).\n *\n * Endpoints (mirrors the iOS SDK's surface):\n * GET /v2/mobile/config bootstrap (sponsors + market)\n * GET /v2/mobile/campaigns/:id/components placement components (TBD)\n * POST /v2/mobile/campaigns/:id/cart-intent cross-device cart-intent (TBD)\n *\n * Auth: `X-API-Key: <apiKey>` header (the top-level Vio apiKey).\n *\n * Note: until the backend exposes a dedicated `/v2/web/*` surface we\n * reuse the `/v2/mobile/*` paths — the apiKey identifies the client_app\n * and the response shape is platform-agnostic enough.\n */\n\nimport type { BootstrapResponse, PlacementComponent } from '../types.js'\n\nexport interface VioApiOptions {\n /** REST API base URL, e.g. `https://api-dev.vio.live`. */\n apiBase: string\n /** Top-level Vio apiKey for this client app. */\n apiKey: string\n}\n\nexport class VioApi {\n private readonly apiBase: string\n private readonly apiKey: string\n\n constructor(options: VioApiOptions) {\n if (!options.apiBase) throw new Error('[VioApi] apiBase is required')\n if (!options.apiKey) throw new Error('[VioApi] apiKey is required')\n this.apiBase = options.apiBase.replace(/\\/+$/, '')\n this.apiKey = options.apiKey\n }\n\n /**\n * Bootstrap — fetches client app config (sponsors with commerce keys,\n * default market, campaign id). Called once at SDK init.\n */\n async bootstrap(): Promise<BootstrapResponse> {\n return this.get<BootstrapResponse>('/v2/mobile/config')\n }\n\n /**\n * Get placement components for a campaign. Used by the carousel auto-fetch\n * mode (`<vio-product-carousel campaign-id=\"36\" location=\"news-favorites\">`).\n */\n async getComponents(campaignId: number | string): Promise<PlacementComponent[]> {\n const path = `/v2/mobile/campaigns/${encodeURIComponent(String(campaignId))}/components`\n const res = await this.get<{ components: PlacementComponent[] } | PlacementComponent[]>(path)\n return Array.isArray(res) ? res : (res?.components ?? [])\n }\n\n // MARK: - HTTP plumbing\n\n private async get<T>(path: string): Promise<T> {\n const url = `${this.apiBase}${path}`\n const res = await fetch(url, {\n method: 'GET',\n headers: {\n 'X-API-Key': this.apiKey,\n Accept: 'application/json',\n },\n })\n if (!res.ok) {\n throw new VioApiError(res.status, await safeText(res), `GET ${path}`)\n }\n return (await res.json()) as T\n }\n}\n\nexport class VioApiError extends Error {\n constructor(\n public readonly status: number,\n public readonly body: string,\n public readonly endpoint: string,\n ) {\n super(`[VioApi] ${endpoint} → HTTP ${status}: ${body.slice(0, 200)}`)\n this.name = 'VioApiError'\n }\n}\n\nasync function safeText(res: Response): Promise<string> {\n try {\n return await res.text()\n } catch {\n return ''\n }\n}\n\nexport function createVioApi(options: VioApiOptions): VioApi {\n return new VioApi(options)\n}\n","/**\n * Commerce GraphQL client — talks to Vio Commerce.\n *\n * Mirrors the iOS SDK's `SdkClient.channel.product` surface, but uses\n * `graphql-request` (lightweight) instead of Apollo. Auth header: `Authorization: <apiKey>`\n * (per-sponsor commerce apiKey, NOT the top-level Vio apiKey).\n *\n * Usage:\n * const commerce = createCommerceClient({\n * endpoint: 'https://graph-ql-dev.vio.live',\n * apiKey: '<sponsor-commerce-apiKey>', // sponsor's commerce apiKey\n * })\n * const products = await commerce.channel.product.getByIds({\n * product_ids: [408895, 408896],\n * currency: 'NOK',\n * image_size: 'large',\n * })\n */\n\nimport { GraphQLClient } from 'graphql-request'\nimport type { ImageSize, Product } from '../types.js'\n\nexport interface CommerceClientOptions {\n /** Vio Commerce GraphQL endpoint, e.g. `https://graph-ql-dev.vio.live`. */\n endpoint: string\n /** Per-sponsor commerce apiKey (from bootstrap.primarySponsor.commerce.apiKey). */\n apiKey: string\n}\n\nconst GET_PRODUCTS_BY_IDS = /* GraphQL */ `\n query GetProductsByIds(\n $currency: String\n $imageSize: ImageSize\n $productIds: [Int!]\n $useCache: Boolean!\n $shippingCountryCode: String\n ) {\n Channel {\n GetProductsByIds(\n currency: $currency\n image_size: $imageSize\n product_ids: $productIds\n useCache: $useCache\n shipping_country_code: $shippingCountryCode\n ) {\n id\n brand\n title\n description\n tags\n sku\n quantity\n price {\n amount\n currency_code\n compare_at\n amount_incl_taxes\n compare_at_incl_taxes\n tax_amount\n tax_rate\n }\n variants {\n id\n barcode\n quantity\n sku\n title\n price {\n amount\n currency_code\n compare_at\n amount_incl_taxes\n compare_at_incl_taxes\n tax_amount\n tax_rate\n }\n images {\n id\n url\n width\n height\n order\n }\n }\n barcode\n options {\n id\n name\n order\n values\n }\n categories {\n id\n name\n }\n images {\n id\n url\n width\n height\n order\n }\n }\n }\n }\n`\n\nexport interface GetProductsByIdsOptions {\n product_ids: number[]\n currency?: string | null\n image_size?: ImageSize | null\n useCache?: boolean\n shipping_country_code?: string | null\n}\n\nclass ChannelProduct {\n constructor(private readonly client: GraphQLClient) {}\n\n /**\n * Fetch a batch of products by their numeric ids.\n * Returns an empty array if no ids are provided.\n */\n async getByIds(options: GetProductsByIdsOptions): Promise<Product[]> {\n if (!options.product_ids || options.product_ids.length === 0) return []\n\n const variables = {\n productIds: options.product_ids,\n currency: options.currency ?? null,\n imageSize: options.image_size ?? 'large',\n useCache: options.useCache ?? true,\n shippingCountryCode: options.shipping_country_code ?? null,\n }\n\n const data = await this.client.request<{\n Channel: { GetProductsByIds: Product[] }\n }>(GET_PRODUCTS_BY_IDS, variables)\n\n return data.Channel?.GetProductsByIds ?? []\n }\n}\n\nclass Channel {\n readonly product: ChannelProduct\n\n constructor(client: GraphQLClient) {\n this.product = new ChannelProduct(client)\n }\n}\n\n/** CommerceClient — namespaced facade, mirrors the iOS SdkClient. */\nexport class CommerceClient {\n readonly channel: Channel\n /** Underlying graphql-request client (escape hatch for custom queries). */\n readonly raw: GraphQLClient\n\n constructor(options: CommerceClientOptions) {\n if (!options.endpoint) throw new Error('[VioCommerce] endpoint is required')\n if (!options.apiKey) throw new Error('[VioCommerce] apiKey is required')\n\n this.raw = new GraphQLClient(options.endpoint, {\n headers: { Authorization: options.apiKey },\n })\n this.channel = new Channel(this.raw)\n }\n}\n\nexport function createCommerceClient(options: CommerceClientOptions): CommerceClient {\n return new CommerceClient(options)\n}\n","/**\n * Vio types — Product / Sponsor / Bootstrap shapes.\n *\n * Product types mirror the Vio Commerce GraphQL schema.\n * Sponsor / Bootstrap shapes mirror the iOS SDK's bootstrap response so\n * we stay aligned cross-platform.\n */\n\nexport type ImageSize = 'thumbnail' | 'small' | 'medium' | 'large' | 'full'\n\nexport interface ProductPrice {\n amount: number\n currency_code: string\n compare_at?: number | null\n amount_incl_taxes?: number | null\n compare_at_incl_taxes?: number | null\n tax_amount?: number | null\n tax_rate?: number | null\n}\n\nexport interface ProductImage {\n id: string\n url: string\n width?: number | null\n height?: number | null\n order?: number | null\n}\n\nexport interface ProductOption {\n id: number\n name: string\n order: number\n values: string[]\n}\n\nexport interface ProductCategory {\n id: number\n name: string\n}\n\nexport interface ProductVariant {\n id: number\n barcode?: string | null\n quantity?: number | null\n sku?: string | null\n title?: string | null\n price: ProductPrice\n images: ProductImage[]\n}\n\nexport interface Product {\n id: number\n brand?: string | null\n title: string\n description?: string | null\n tags?: string | null\n sku: string\n quantity?: number | null\n price: ProductPrice\n variants: ProductVariant[]\n barcode?: string | null\n options: ProductOption[]\n categories?: ProductCategory[] | null\n images: ProductImage[]\n}\n\n/** Per-sponsor commerce config sourced from Vio bootstrap. */\nexport interface SponsorCommerceBlock {\n apiKey: string\n channelId?: string | null\n paymentMethods?: string[]\n}\n\nexport interface Sponsor {\n id: number\n name: string\n description?: string | null\n avatarUrl?: string | null\n logoUrl?: string | null\n primaryColor?: string | null\n secondaryColor?: string | null\n commerce: SponsorCommerceBlock\n}\n\n/**\n * Response shape of `GET /v2/mobile/config` (and likely future `/v2/web/config`).\n * Matches the iOS SDK's `SdkBootstrapResponse` model.\n */\nexport interface BootstrapResponse {\n campaignId?: number\n primarySponsor?: Sponsor\n secondarySponsors?: Sponsor[]\n market?: {\n countryCode: string\n currencyCode: string\n }\n}\n\n/**\n * A placement component returned by `/v2/mobile/campaigns/:id/components`.\n * Used by `<vio-product-carousel campaign-id=\"...\">` to know which products\n * to render at a given slot.\n */\nexport interface PlacementComponent {\n id: number\n componentType: string\n locationId: string\n sponsorId?: number\n config: {\n productIds?: number[]\n [key: string]: unknown\n }\n}\n\n/** Helper: extract a useful display price from a Product. */\nexport function displayPrice(product: Product): string {\n const p = product.price\n const amount = p.amount_incl_taxes ?? p.amount\n return formatPrice(amount, p.currency_code)\n}\n\n/** Format a numeric amount + currency for Norwegian style: \"1 299 kr\". */\nexport function formatPrice(amount: number, currency: string): string {\n // Use Norwegian locale grouping (space as thousands separator).\n const formatted = amount\n .toLocaleString('no-NO', { minimumFractionDigits: 0, maximumFractionDigits: 2 })\n // Normalize non-breaking space to regular space for predictable rendering.\n .replace(/ /g, ' ')\n // Some currency codes display nicer lowercase: NOK → kr.\n const symbol = currency === 'NOK' ? 'kr' : currency\n return `${formatted} ${symbol}`\n}\n\n/** Helper: pick the first image URL (variant first, then product). */\nexport function primaryImageUrl(product: Product): string | undefined {\n const variantImage = product.variants[0]?.images[0]?.url\n if (variantImage) return variantImage\n return product.images[0]?.url\n}\n","/**\n * CartManager — multi-sponsor cart state.\n *\n * Mirrors iOS's `CartManager` + `cartsBySponsor`. Holds local state in\n * memory and persists to localStorage. Reactive: dispatches a `change`\n * CustomEvent that UI components subscribe to (Web Components react via\n * `requestUpdate()`).\n *\n * Server-side cart sync (Vio Commerce GraphQL CreateCart / AddToCart\n * mutations) is deferred to checkout time via the CheckoutManager —\n * this manager is purely client-side state for now.\n */\n\nimport { formatPrice, primaryImageUrl, type Product } from '../types.js'\nimport type { CartLineItem, SponsorCartState } from './types.js'\n\nconst STORAGE_KEY = 'vio.cart.v1'\n\nexport interface CartChangeDetail {\n cartsBySponsor: Map<number, SponsorCartState>\n itemCount: number\n}\n\nexport interface AddProductOptions {\n product: Product\n sponsorId: number\n sponsorName?: string\n quantity?: number\n variantId?: number\n}\n\n/** Minimal product shape — for callers who only have e.g. mock data, not a full Product. */\nexport interface AddManualOptions {\n productId: number\n sponsorId: number\n sponsorName?: string\n brand: string\n name: string\n unitPrice: number\n currency: string\n imageUrl: string\n quantity?: number\n variantId?: number\n}\n\nfunction lineId(): string {\n return 'li_' + Math.random().toString(36).slice(2, 10) + Date.now().toString(36)\n}\n\nexport class CartManager extends EventTarget {\n private cartsBySponsor: Map<number, SponsorCartState>\n\n constructor() {\n super()\n this.cartsBySponsor = this.loadFromStorage()\n }\n\n // MARK: - Mutations\n\n /** Add a Product DTO to a sponsor's cart. Bumps quantity if already present. */\n addProduct(opts: AddProductOptions): CartLineItem {\n const unitPrice = opts.product.price.amount_incl_taxes ?? opts.product.price.amount\n return this.addManual({\n productId: opts.product.id,\n sponsorId: opts.sponsorId,\n sponsorName: opts.sponsorName,\n brand: opts.product.brand ?? '',\n name: opts.product.title,\n unitPrice,\n currency: opts.product.price.currency_code,\n imageUrl: primaryImageUrl(opts.product) ?? '',\n quantity: opts.quantity,\n variantId: opts.variantId,\n })\n }\n\n /** Add a manually-specified line item (no Product DTO). */\n addManual(opts: AddManualOptions): CartLineItem {\n const qty = Math.max(1, opts.quantity ?? 1)\n let cart = this.cartsBySponsor.get(opts.sponsorId)\n if (!cart) {\n cart = {\n sponsorId: opts.sponsorId,\n sponsorName: opts.sponsorName,\n items: [],\n currency: opts.currency,\n }\n this.cartsBySponsor.set(opts.sponsorId, cart)\n } else if (opts.sponsorName && !cart.sponsorName) {\n cart.sponsorName = opts.sponsorName\n }\n\n const existing = cart.items.find(\n (i) => i.productId === opts.productId && i.variantId === opts.variantId,\n )\n if (existing) {\n existing.quantity += qty\n this.persist()\n this.emit()\n return existing\n }\n\n const item: CartLineItem = {\n id: lineId(),\n productId: opts.productId,\n sponsorId: opts.sponsorId,\n variantId: opts.variantId,\n brand: opts.brand,\n name: opts.name,\n unitPrice: opts.unitPrice,\n currency: opts.currency,\n imageUrl: opts.imageUrl,\n quantity: qty,\n }\n cart.items.push(item)\n this.persist()\n this.emit()\n return item\n }\n\n updateQuantity(lineItemId: string, sponsorId: number, quantity: number): void {\n const cart = this.cartsBySponsor.get(sponsorId)\n if (!cart) return\n const item = cart.items.find((i) => i.id === lineItemId)\n if (!item) return\n if (quantity <= 0) {\n cart.items = cart.items.filter((i) => i.id !== lineItemId)\n } else {\n item.quantity = quantity\n }\n if (cart.items.length === 0) this.cartsBySponsor.delete(sponsorId)\n this.persist()\n this.emit()\n }\n\n removeItem(lineItemId: string, sponsorId: number): void {\n this.updateQuantity(lineItemId, sponsorId, 0)\n }\n\n clearSponsorCart(sponsorId: number): void {\n if (this.cartsBySponsor.delete(sponsorId)) {\n this.persist()\n this.emit()\n }\n }\n\n clearAllCarts(): void {\n if (this.cartsBySponsor.size === 0) return\n this.cartsBySponsor.clear()\n this.persist()\n this.emit()\n }\n\n // MARK: - Read accessors\n\n getAllCarts(): Map<number, SponsorCartState> {\n return new Map(this.cartsBySponsor)\n }\n\n getCart(sponsorId: number): SponsorCartState | undefined {\n return this.cartsBySponsor.get(sponsorId)\n }\n\n get itemCount(): number {\n let count = 0\n for (const cart of this.cartsBySponsor.values()) {\n for (const item of cart.items) count += item.quantity\n }\n return count\n }\n\n subtotalForSponsor(sponsorId: number): number {\n const cart = this.cartsBySponsor.get(sponsorId)\n if (!cart) return 0\n return cart.items.reduce((sum, i) => sum + i.unitPrice * i.quantity, 0)\n }\n\n get totalAcrossSponsors(): number {\n let sum = 0\n for (const cart of this.cartsBySponsor.values()) {\n for (const item of cart.items) sum += item.unitPrice * item.quantity\n }\n return sum\n }\n\n get primaryCurrency(): string {\n for (const cart of this.cartsBySponsor.values()) return cart.currency\n return 'NOK'\n }\n\n formatTotal(): string {\n return formatPrice(this.totalAcrossSponsors, this.primaryCurrency)\n }\n\n // MARK: - Persistence\n\n private persist(): void {\n if (typeof localStorage === 'undefined') return\n try {\n const obj: Record<string, SponsorCartState> = {}\n for (const [k, v] of this.cartsBySponsor) obj[String(k)] = v\n localStorage.setItem(STORAGE_KEY, JSON.stringify(obj))\n } catch {\n // Ignore quota / privacy errors.\n }\n }\n\n private loadFromStorage(): Map<number, SponsorCartState> {\n if (typeof localStorage === 'undefined') return new Map()\n try {\n const raw = localStorage.getItem(STORAGE_KEY)\n if (!raw) return new Map()\n const obj = JSON.parse(raw) as Record<string, SponsorCartState>\n const map = new Map<number, SponsorCartState>()\n for (const [k, v] of Object.entries(obj)) {\n const id = parseInt(k, 10)\n if (!Number.isNaN(id) && v && Array.isArray(v.items)) map.set(id, v)\n }\n return map\n } catch {\n return new Map()\n }\n }\n\n private emit(): void {\n const detail: CartChangeDetail = {\n cartsBySponsor: this.getAllCarts(),\n itemCount: this.itemCount,\n }\n this.dispatchEvent(new CustomEvent<CartChangeDetail>('change', { detail }))\n }\n}\n","/**\n * Apple Pay on the Web — via Stripe Payment Request API.\n *\n * Architecture decision (matches iOS Vio SDK pattern):\n * - One Stripe **publishable key** for the Vio platform (global, set\n * via `Vio.init({ stripePublishableKey })`).\n * - One **Stripe Connect account id** per sponsor — sourced from\n * `Vio.bootstrap()` response. Without it, the payment lands on the\n * platform account instead of the merchant.\n *\n * Apple Pay on the Web prerequisites (Stripe-managed for us):\n * - Stripe Connect account is enabled for Apple Pay\n * - Domain registration for Apple Pay (Stripe handles via Dashboard)\n * - Safari + macOS/iOS device with Apple Pay configured\n *\n * In Chrome / non-Apple browsers `canMakePayment()` returns null, so the\n * UI hides the Apple Pay button automatically.\n */\n\nconst STRIPE_JS_URL = 'https://js.stripe.com/v3'\n\nexport interface ApplePayConfig {\n /** Stripe platform publishable key (pk_live_xxx or pk_test_xxx). */\n publishableKey: string\n /** Sponsor's Stripe Connect account (acct_xxx). Optional but recommended. */\n connectedAccount?: string\n /** Amount in the smallest unit of the currency (e.g. øre for NOK, cents for USD). */\n amount: number\n /** ISO currency code, lowercased internally for Stripe. */\n currency: string\n /** Two-letter country code, e.g. \"NO\". */\n country: string\n /** Label shown in the Apple Pay sheet (merchant or order name). */\n label: string\n /** Whether to ask the user for payer name. */\n requestPayerName?: boolean\n /** Whether to ask the user for payer email. */\n requestPayerEmail?: boolean\n /** Whether to ask for shipping address. */\n requestShipping?: boolean\n /**\n * Shipping options shown natively in the Apple Pay sheet. `amount` is in the\n * smallest unit (øre). When set, `requestShipping` is forced on and the sheet\n * total = `amount` (items) + the selected option; switching options updates\n * the total live (Apple Pay native shipping).\n */\n shippingOptions?: Array<{ id: string; label: string; detail?: string; amount: number }>\n}\n\nexport interface ApplePayResult {\n /** Stripe PaymentMethod id (pm_xxx) — pass to backend to confirm the PaymentIntent. */\n paymentMethodId: string\n payerName?: string\n payerEmail?: string\n payerPhone?: string\n shippingAddress?: {\n line1?: string\n line2?: string\n city?: string\n postal_code?: string\n state?: string\n country?: string\n }\n}\n\nlet stripeJsPromise: Promise<unknown> | null = null\n\n/** Dynamically load Stripe.js exactly once. */\nfunction loadStripeJs(): Promise<unknown> {\n if (stripeJsPromise) return stripeJsPromise\n if (typeof document === 'undefined') {\n return Promise.reject(new Error('[VioApplePay] Stripe.js requires a browser environment'))\n }\n stripeJsPromise = new Promise<unknown>((resolve, reject) => {\n const w = window as unknown as { Stripe?: unknown }\n if (w.Stripe) {\n resolve(w.Stripe)\n return\n }\n const existing = document.querySelector(\n `script[src^=\"${STRIPE_JS_URL}\"]`,\n ) as HTMLScriptElement | null\n if (existing) {\n existing.addEventListener('load', () => resolve(w.Stripe))\n existing.addEventListener('error', () =>\n reject(new Error('[VioApplePay] Failed to load Stripe.js')),\n )\n return\n }\n const script = document.createElement('script')\n script.src = STRIPE_JS_URL\n script.async = true\n script.addEventListener('load', () => resolve(w.Stripe))\n script.addEventListener('error', () =>\n reject(new Error('[VioApplePay] Failed to load Stripe.js')),\n )\n document.head.appendChild(script)\n })\n return stripeJsPromise\n}\n\ninterface StripeCanMakePaymentResult {\n applePay?: boolean\n googlePay?: boolean\n link?: boolean\n}\n\ninterface StripePaymentRequest {\n canMakePayment(): Promise<StripeCanMakePaymentResult | null>\n show(): void\n on(event: string, handler: (ev: unknown) => void): void\n}\n\ninterface StripeInstance {\n paymentRequest(options: Record<string, unknown>): StripePaymentRequest\n}\n\ntype StripeFactory = (\n publishableKey: string,\n options?: { stripeAccount?: string },\n) => StripeInstance\n\nasync function getStripe(config: ApplePayConfig): Promise<StripeInstance> {\n const Stripe = (await loadStripeJs()) as StripeFactory\n return Stripe(\n config.publishableKey,\n config.connectedAccount ? { stripeAccount: config.connectedAccount } : undefined,\n )\n}\n\nfunction buildRequestOptions(config: ApplePayConfig): Record<string, unknown> {\n const ship = config.shippingOptions\n // With shipping options, the sheet's total = items + the (first/selected) option.\n const preselectedShipping = ship && ship.length > 0 ? ship[0]!.amount : 0\n return {\n country: config.country,\n currency: config.currency.toLowerCase(),\n total: { label: config.label, amount: config.amount + preselectedShipping },\n requestPayerName: config.requestPayerName ?? true,\n requestPayerEmail: config.requestPayerEmail ?? true,\n requestShipping: ship && ship.length > 0 ? true : (config.requestShipping ?? false),\n ...(ship && ship.length > 0 ? { shippingOptions: ship } : {}),\n disableWallets: ['link', 'googlePay'],\n }\n}\n\n/**\n * Check whether Apple Pay is available right now (Safari + supported device\n * + Stripe configured + domain registered).\n *\n * Returns false on any failure path — never throws.\n */\nexport async function checkApplePayAvailability(config: ApplePayConfig): Promise<boolean> {\n if (typeof window === 'undefined') return false\n // Quick precheck — Apple Pay is only on Safari + supported macOS/iOS devices.\n if (typeof (window as unknown as { ApplePaySession?: unknown }).ApplePaySession === 'undefined') {\n return false\n }\n if (!config.publishableKey) return false\n try {\n const stripe = await getStripe(config)\n const pr = stripe.paymentRequest(buildRequestOptions(config))\n const result = await pr.canMakePayment()\n return !!result?.applePay\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioApplePay] availability check failed:', err)\n }\n return false\n }\n}\n\n/**\n * Show the Apple Pay sheet. Resolves with the payment method id (`pm_xxx`)\n * after the user authorises, or rejects on cancel / error.\n *\n * The backend must then confirm a Stripe PaymentIntent with this\n * payment method id (server-side step, not handled here).\n */\nexport async function showApplePaySheet(config: ApplePayConfig): Promise<ApplePayResult> {\n if (!config.publishableKey) {\n throw new Error('[VioApplePay] publishableKey is required')\n }\n const stripe = await getStripe(config)\n const pr = stripe.paymentRequest(buildRequestOptions(config))\n const canMake = await pr.canMakePayment()\n if (!canMake?.applePay) {\n throw new Error('[VioApplePay] Apple Pay is not available on this device')\n }\n return new Promise<ApplePayResult>((resolve, reject) => {\n let settled = false\n pr.on('paymentmethod', (raw: unknown) => {\n const ev = raw as {\n paymentMethod: { id: string }\n payerName?: string\n payerEmail?: string\n payerPhone?: string\n shippingAddress?: ApplePayResult['shippingAddress']\n complete: (status: 'success' | 'fail') => void\n }\n settled = true\n // We complete with 'success' optimistically. In a real flow the\n // backend confirms the PaymentIntent first, and only then we'd\n // call `ev.complete('success')` (or 'fail' on error).\n ev.complete('success')\n resolve({\n paymentMethodId: ev.paymentMethod.id,\n payerName: ev.payerName,\n payerEmail: ev.payerEmail,\n payerPhone: ev.payerPhone,\n shippingAddress: ev.shippingAddress,\n })\n })\n pr.on('cancel', () => {\n if (settled) return\n reject(new Error('[VioApplePay] User cancelled Apple Pay'))\n })\n pr.show()\n })\n}\n\nexport interface PreparedApplePay {\n /** True if Apple Pay can be shown (canMakePayment resolved with applePay). */\n available: boolean\n /**\n * Open the Apple Pay sheet. MUST be invoked synchronously from the click\n * handler — the async work (Stripe.js load + canMakePayment) already ran in\n * `prepareApplePay`, so this fires `pr.show()` inside the user gesture. Apple\n * blocks the sheet if `show()` is reached after an `await`.\n */\n show(): Promise<ApplePayResult>\n}\n\n/**\n * Pre-create the Apple Pay PaymentRequest and resolve `canMakePayment()` ahead\n * of the click. Express buttons should call this on load/render, then call the\n * returned `show()` synchronously on tap — preserving the user gesture that\n * Apple requires to open the sheet.\n */\nexport async function prepareApplePay(config: ApplePayConfig): Promise<PreparedApplePay> {\n const unavailable = (msg: string): PreparedApplePay => ({\n available: false,\n show: () => Promise.reject(new Error(msg)),\n })\n if (typeof window === 'undefined' || !config.publishableKey) {\n return unavailable('[VioApplePay] unavailable')\n }\n if (typeof (window as unknown as { ApplePaySession?: unknown }).ApplePaySession === 'undefined') {\n return unavailable('[VioApplePay] ApplePaySession not available')\n }\n try {\n const stripe = await getStripe(config)\n const pr = stripe.paymentRequest(buildRequestOptions(config))\n // Recompute the total live when the user switches shipping option in the\n // Apple Pay sheet: total = items (config.amount) + chosen option amount.\n if (config.shippingOptions && config.shippingOptions.length > 0) {\n pr.on('shippingoptionchange', (raw: unknown) => {\n const ev = raw as {\n shippingOption?: { id?: string }\n updateWith: (u: Record<string, unknown>) => void\n }\n const opt = config.shippingOptions?.find((o) => o.id === ev.shippingOption?.id)\n ev.updateWith({\n status: 'success',\n total: { label: config.label, amount: config.amount + (opt?.amount ?? 0) },\n })\n })\n }\n const result = await pr.canMakePayment()\n if (!result?.applePay) return unavailable('[VioApplePay] Apple Pay not available')\n return {\n available: true,\n show(): Promise<ApplePayResult> {\n return new Promise<ApplePayResult>((resolve, reject) => {\n let settled = false\n pr.on('paymentmethod', (raw: unknown) => {\n const ev = raw as {\n paymentMethod: { id: string }\n payerName?: string\n payerEmail?: string\n payerPhone?: string\n shippingAddress?: ApplePayResult['shippingAddress']\n complete: (status: 'success' | 'fail') => void\n }\n settled = true\n ev.complete('success')\n resolve({\n paymentMethodId: ev.paymentMethod.id,\n payerName: ev.payerName,\n payerEmail: ev.payerEmail,\n payerPhone: ev.payerPhone,\n shippingAddress: ev.shippingAddress,\n })\n })\n pr.on('cancel', () => {\n if (!settled) reject(new Error('[VioApplePay] User cancelled Apple Pay'))\n })\n pr.show() // synchronous — must run inside the click gesture\n })\n },\n }\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioApplePay] prepare failed:', err)\n }\n return unavailable('[VioApplePay] prepare failed')\n }\n}\n","/**\n * Klarna Express Checkout (KEC) — via the Klarna Web SDK v2.\n *\n * Frontend half of the flow (the only half that runs client-side):\n * 1. Load the Klarna Web SDK ESM module from Klarna's CDN.\n * 2. `KlarnaSDK({ clientId, products: ['PAYMENT'] })` → SDK instance.\n * 3. `Klarna.Payment.button({ paymentRequest, initiationMode })` → button.\n * 4. `button.mount(container)` renders the express button.\n * 5. User taps it → Klarna popup → on success the SDK yields an\n * **authorization token**.\n *\n * The authorization token is NOT an order. The merchant **backend** must\n * exchange it for an order against the Klarna Payments API\n * (`POST /payments/v1/authorizations/{token}/order`, Basic auth with the\n * server-side Klarna API key). That step needs secret credentials and is\n * intentionally out of this client module — we surface the token via\n * `onAuthorize` and let the host (or, later, vio-backend) create the order.\n *\n * Verified against Klarna Web SDK v2 docs (module URL, KlarnaSDK init,\n * Payment.button().mount(), authorization-token result). The exact\n * authorize *event name* varies by SDK minor version, so the subscription\n * below is defensive — it normalises across the documented shapes.\n *\n * Prerequisites (merchant-configured, like Stripe domain reg for Apple Pay):\n * - Klarna merchant account + a **Client Identifier** (Merchant Portal →\n * Payment settings → Client Identifiers).\n * - The integration domain registered under \"Allowed Origins\".\n * - A server-side Klarna API key for the order-creation step (backend).\n */\n\n/** Klarna Web SDK v2 ESM module (loaded from Klarna's CDN at runtime). */\nexport const KLARNA_SDK_URL = 'https://js.klarna.com/web-sdk/v2/klarna.mjs'\n\n/** One line in the express button's purchase data. Amounts in MINOR units. */\nexport interface KlarnaLineItem {\n name: string\n quantity: number\n /** Line total (unitPrice × quantity), minor units (e.g. øre for NOK). */\n totalAmount: number\n /** Per-unit price, minor units. Optional. */\n unitPrice?: number\n /** Merchant SKU / product reference. Optional. */\n reference?: string\n /** Absolute image URL. Optional. */\n imageUrl?: string\n}\n\n/** Payment request handed to the KEC button. Amounts in MINOR units. */\nexport interface KlarnaPaymentRequestData {\n /** ISO currency code (e.g. \"NOK\"). */\n currency: string\n /** Order total in minor units. */\n amount: number\n /** Line items — shown in the Klarna sheet. */\n supplementaryPurchaseData?: { lineItems: KlarnaLineItem[] }\n}\n\nexport interface KlarnaConfig {\n /** Klarna Client Identifier (public-safe — fine in client bundles). */\n clientId: string\n /** Optional BCP-47 locale, e.g. \"nb-NO\". */\n locale?: string\n /**\n * Klarna environment. `playground` = sandbox (test orders, \"TEST DRIVE\"\n * badge, no real money). `production` = live. Defaults to the SDK's own\n * default when omitted. The clientId must be generated for the matching\n * environment in the Klarna Merchant Portal.\n */\n environment?: 'playground' | 'production'\n}\n\nexport interface KlarnaAuthorizeResult {\n /** Authorization token — backend exchanges it for an order. */\n authorizationToken: string\n /** Klarna may require a finalize step (multistep flows). */\n finalizeRequired?: boolean\n /** Raw payload from the SDK, for debugging / forward-compat. */\n raw?: unknown\n}\n\nexport interface KlarnaButtonHandle {\n unmount(): void\n}\n\n// ── Minimal structural typings for the runtime-loaded SDK ────────────────\n// We don't ship Klarna's .d.ts; the SDK is fetched at runtime, so these are\n// just enough to call it type-safely.\n\ninterface KlarnaButtonInstance {\n mount(container: string | HTMLElement): KlarnaButtonInstance\n unmount(): KlarnaButtonInstance\n on(event: string, cb: (...args: unknown[]) => unknown): KlarnaButtonInstance\n}\n\ninterface KlarnaPaymentNamespace {\n button(config: Record<string, unknown>): KlarnaButtonInstance\n /**\n * Opens the Klarna flow. Takes a callback that returns the payment-request\n * data (or a Promise of it). Must be invoked synchronously from the\n * button's `click` handler so the popup keeps the user gesture. Resolves\n * with the authorization result once the user completes the popup.\n */\n initiate(resolvePaymentRequest: () => unknown): Promise<unknown>\n on?(event: string, cb: (...args: unknown[]) => unknown): unknown\n}\n\ninterface KlarnaSdkInstance {\n Payment: KlarnaPaymentNamespace\n}\n\ntype KlarnaSdkFactory = (config: Record<string, unknown>) => Promise<KlarnaSdkInstance>\n\n// Memoise the SDK instance per clientId so re-opening checkout reuses it.\nconst sdkCache = new Map<string, Promise<KlarnaSdkInstance>>()\n\nfunction loadKlarnaSdk(config: KlarnaConfig): Promise<KlarnaSdkInstance> {\n if (typeof window === 'undefined') {\n return Promise.reject(new Error('[VioKlarna] requires a browser environment'))\n }\n if (!config.clientId) {\n return Promise.reject(new Error('[VioKlarna] clientId is required'))\n }\n // Key the cache by clientId + environment so switching env re-inits.\n const cacheKey = `${config.clientId}:${config.environment ?? 'default'}`\n const cached = sdkCache.get(cacheKey)\n if (cached) return cached\n\n // Dynamic import of an absolute CDN URL. `@vite-ignore` stops the bundler\n // from trying to resolve/inline it — it stays a runtime fetch.\n const url = KLARNA_SDK_URL\n const promise = import(/* @vite-ignore */ url)\n .then((mod: { KlarnaSDK?: KlarnaSdkFactory; default?: KlarnaSdkFactory }) => {\n const factory = mod.KlarnaSDK ?? mod.default\n if (typeof factory !== 'function') {\n throw new Error('[VioKlarna] KlarnaSDK factory not found in module')\n }\n return factory({\n clientId: config.clientId,\n products: ['PAYMENT'],\n ...(config.locale ? { locale: config.locale } : {}),\n ...(config.environment ? { environment: config.environment } : {}),\n })\n })\n .catch((err) => {\n // Don't poison the cache on failure — allow a later retry.\n sdkCache.delete(cacheKey)\n throw err\n })\n sdkCache.set(cacheKey, promise)\n return promise\n}\n\n/**\n * True if Klarna Express can be offered right now (clientId set + SDK loads).\n * Never throws — returns false on any failure path (mirrors Apple Pay).\n */\nexport async function isKlarnaAvailable(config: KlarnaConfig): Promise<boolean> {\n if (typeof window === 'undefined' || !config.clientId) return false\n try {\n await loadKlarnaSdk(config)\n return true\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioKlarna] availability check failed:', err)\n }\n return false\n }\n}\n\n/** Recursively search a result object for an authorization token. */\nfunction findAuthToken(value: unknown, depth = 0): string | undefined {\n if (!value || depth > 4 || typeof value !== 'object') return undefined\n const o = value as Record<string, unknown>\n for (const key of ['authorizationToken', 'authorization_token', 'authToken']) {\n if (typeof o[key] === 'string' && (o[key] as string).length > 0) return o[key] as string\n }\n for (const k of Object.keys(o)) {\n const found = findAuthToken(o[k], depth + 1)\n if (found) return found\n }\n return undefined\n}\n\n/**\n * Build + mount the Klarna Express button into `container`.\n *\n * Flow (Klarna Web SDK v2): the button's `click` handler **synchronously**\n * calls `Klarna.Payment.initiate(cb)` — `cb` returns the payment-request\n * data. That call opens the Klarna popup (the synchronous call preserves the\n * user gesture). The returned Promise resolves with the authorization result\n * once the user completes the popup; we pull the authorization token out and\n * hand it to `onAuthorize`. The token is NOT an order — the backend creates\n * the order from it.\n */\nexport async function mountKlarnaExpressButton(opts: {\n config: KlarnaConfig\n container: HTMLElement\n paymentRequest: KlarnaPaymentRequestData\n /** URL Klarna returns to after a redirect-based completion. Required by KEC. */\n returnUrl?: string\n /**\n * sessionStorage key + payload to persist BEFORE launching. On a redirect\n * completion the page reloads (the initiate() promise is lost), so the\n * resume handler reads this back to recreate the order. Survives the\n * cross-origin redirect because sessionStorage is per-tab.\n */\n pendingKey?: string\n pendingContext?: unknown\n onAuthorize: (result: KlarnaAuthorizeResult) => void\n onError?: (err: unknown) => void\n}): Promise<KlarnaButtonHandle> {\n const sdk = await loadKlarnaSdk(opts.config)\n\n const button = sdk.Payment.button({\n id: 'vio-klarna-express',\n // `PAY` = one-time purchase (vs BUY/SUBSCRIBE). Must be an array.\n intents: ['PAY'],\n // initiationMode belongs on the BUTTON config (per Klarna Web SDK docs),\n // NOT inside the initiate() data — when set only in initiate() the SDK\n // falls back to its default (DEVICE_BEST → desktop popup), which opened\n // and closed without completing. Forcing REDIRECT here makes the click do\n // a full-page navigation to Klarna's hosted journey, returning via\n // `returnUrl` (recovered by resumeKlarnaReturn()).\n initiationMode: 'REDIRECT',\n })\n\n // Clean origin+path (no existing query/hash) so Klarna's appended result\n // params land on a predictable URL the resume handler can parse.\n const returnUrl =\n opts.returnUrl ??\n (typeof window !== 'undefined'\n ? window.location.origin + window.location.pathname\n : '')\n\n let settled = false\n button.on('click', () => {\n // Persist the pending order so a REDIRECT completion (page reloads, this\n // promise never resolves) can be recovered on the return page.\n if (opts.pendingKey && opts.pendingContext && typeof sessionStorage !== 'undefined') {\n try {\n sessionStorage.setItem(opts.pendingKey, JSON.stringify(opts.pendingContext))\n } catch {\n /* storage unavailable — popup mode still works via the promise */\n }\n }\n // initiate() MUST be called synchronously here — going async first would\n // drop the user-gesture and the browser would block the popup.\n const promise = sdk.Payment.initiate(() => ({\n currency: opts.paymentRequest.currency,\n paymentAmount: opts.paymentRequest.amount,\n intents: ['PAY'],\n locale: 'nb-NO',\n // REDIRECT = full-page navigation to Klarna's hosted journey, then back\n // to `returnUrl` with the result. We force this (vs DEVICE_BEST's desktop\n // popup) because the popup proved unreliable here — it opened and closed\n // without completing. The redirect flow has no popup-blocker / window-\n // messaging failure modes; the return is recovered via resumeKlarnaReturn().\n initiationMode: 'REDIRECT',\n returnUrl,\n ...(opts.paymentRequest.supplementaryPurchaseData\n ? { supplementaryPurchaseData: opts.paymentRequest.supplementaryPurchaseData }\n : {}),\n }))\n\n Promise.resolve(promise)\n .then((result) => {\n if (settled) return\n const token = findAuthToken(result)\n if (token) {\n settled = true\n opts.onAuthorize({ authorizationToken: token, raw: result })\n } else if (typeof console !== 'undefined') {\n // Resolved without a recognisable token — log so we can map the\n // shape. Don't confirm the order on an ambiguous resolve.\n console.warn('[VioKlarna] authorize resolved without a token:', result)\n }\n })\n .catch((err) => {\n // Reject = user cancelled or a validation/auth error. Not a success.\n opts.onError?.(err)\n })\n\n // Hand the same promise back to the SDK (its contract for the handler).\n return promise\n })\n\n button.mount(opts.container)\n\n return {\n unmount: () => {\n try {\n button.unmount()\n } catch {\n /* already gone */\n }\n },\n }\n}\n\n/**\n * Read a Klarna authorization token from the current URL's query string.\n * Klarna's redirect completion appends it; param name varies, so check the\n * known variants. Returns the token + the param name found (to clean later).\n */\nexport function readKlarnaTokenFromUrl(): { token: string; param: string } | null {\n if (typeof window === 'undefined') return null\n const params = new URLSearchParams(window.location.search)\n for (const name of [\n 'authorization_token',\n 'authorizationToken',\n 'klarna_authorization_token',\n 'vio_klarna_token',\n ]) {\n const v = params.get(name)\n if (v && v.length > 0 && v !== '{klarna.authorization_token}') {\n return { token: v, param: name }\n }\n }\n return null\n}\n\n/** Strip the given query params from the URL without reloading. */\nexport function cleanUrlParams(params: string[]): void {\n if (typeof window === 'undefined' || !window.history?.replaceState) return\n const url = new URL(window.location.href)\n let changed = false\n for (const p of params) {\n if (url.searchParams.has(p)) {\n url.searchParams.delete(p)\n changed = true\n }\n }\n if (changed) window.history.replaceState({}, '', url.toString())\n}\n\n/**\n * Subscribe to the SDK's namespace-level `complete`/`error` events. On a\n * REDIRECT return the SDK resumes its persisted session and fires `complete`\n * with the authorization token — this is how we recover the token when the\n * page reloaded and the initiate() promise was lost.\n *\n * Never throws; logs and resolves even if the SDK can't load.\n */\nexport async function listenForKlarnaCompletion(opts: {\n config: KlarnaConfig\n onComplete: (result: KlarnaAuthorizeResult) => void\n onError?: (err: unknown) => void\n}): Promise<void> {\n let sdk: KlarnaSdkInstance\n try {\n sdk = await loadKlarnaSdk(opts.config)\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioKlarna] resume: SDK load failed:', err)\n }\n return\n }\n let settled = false\n const onComplete = (...args: unknown[]) => {\n if (settled) return\n for (const a of args) {\n const token = findAuthToken(a)\n if (token) {\n settled = true\n opts.onComplete({ authorizationToken: token, raw: a })\n return\n }\n }\n }\n try {\n sdk.Payment.on?.('complete', onComplete)\n } catch {\n /* unsupported */\n }\n try {\n sdk.Payment.on?.('error', (...a: unknown[]) => opts.onError?.(a[0]))\n } catch {\n /* unsupported */\n }\n}\n","/**\n * Klarna Payments — classic widget flow (`kp/lib/v1/api.js`).\n *\n * This is the alternative to KEC (Web SDK v2 button + `initiate` redirect).\n * Instead of a public `clientId` + origin handshake (which 403'd on the\n * `klarnaevt` bridge from localhost), it uses a **server-minted client_token**:\n *\n * 1. Backend creates a Payments session → `client_token` + categories\n * (POST /v2/commerce/klarna/sessions, server-side Basic-auth API key).\n * 2. We load Klarna's widget **inline** (an iframe) into a container via\n * `Klarna.Payments.init({ client_token })` + `Klarna.Payments.load(...)`.\n * 3. The customer picks/fills a method; `Klarna.Payments.authorize(...)`\n * yields an `authorization_token`.\n * 4. Backend exchanges the token for a real order (existing /orders route).\n *\n * No redirect, no popup, no public clientId — so the origin/handshake failure\n * mode simply doesn't apply here.\n */\n\n/** Klarna Payments JS library (classic). Loaded via <script>, sets window.Klarna. */\nexport const KLARNA_KP_LIB_URL = 'https://x.klarnacdn.net/kp/lib/v1/api.js'\n\nexport interface KlarnaPaymentsCategory {\n identifier: string\n name: string\n asset_urls?: { descriptive?: string; standard?: string }\n}\n\n// ── Minimal runtime typings for the <script>-loaded global ────────────────\ninterface KpLoadResult {\n show_form?: boolean\n error?: unknown\n}\ninterface KpAuthorizeResult {\n approved?: boolean\n show_form?: boolean\n authorization_token?: string\n finalize_required?: boolean\n error?: unknown\n}\ninterface KlarnaPaymentsApi {\n init(opts: { client_token: string }): void\n load(\n opts: { container: string | HTMLElement; payment_method_category?: string },\n data: Record<string, unknown>,\n cb?: (res: KpLoadResult) => void,\n ): void\n authorize(\n opts: { payment_method_category?: string; auto_finalize?: boolean },\n data: Record<string, unknown>,\n cb?: (res: KpAuthorizeResult) => void,\n ): void\n}\ninterface KlarnaGlobal {\n Payments: KlarnaPaymentsApi\n}\n\ndeclare global {\n interface Window {\n Klarna?: KlarnaGlobal\n klarnaAsyncCallback?: () => void\n }\n}\n\nlet kpLoad: Promise<KlarnaGlobal> | null = null\n\n/** Load kp/lib/v1/api.js once; resolves when window.Klarna.Payments is ready. */\nfunction loadKpLib(): Promise<KlarnaGlobal> {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('[VioKlarnaKP] requires a browser environment'))\n }\n if (window.Klarna?.Payments) return Promise.resolve(window.Klarna)\n if (kpLoad) return kpLoad\n\n kpLoad = new Promise<KlarnaGlobal>((resolve, reject) => {\n const timer = setTimeout(\n () => reject(new Error('[VioKlarnaKP] kp/lib/v1/api.js load timed out')),\n 12000,\n )\n const ready = () => {\n clearTimeout(timer)\n if (window.Klarna?.Payments) resolve(window.Klarna)\n else reject(new Error('[VioKlarnaKP] Klarna global missing after ready'))\n }\n // Klarna invokes window.klarnaAsyncCallback once the lib is initialised.\n const prev = window.klarnaAsyncCallback\n window.klarnaAsyncCallback = () => {\n if (typeof prev === 'function') {\n try {\n prev()\n } catch {\n /* host callback threw — ignore */\n }\n }\n ready()\n }\n\n const existing = document.querySelector<HTMLScriptElement>(\n `script[src=\"${KLARNA_KP_LIB_URL}\"]`,\n )\n if (existing) {\n // Script already in the DOM (e.g. re-open). If Klarna is up, resolve now;\n // otherwise our klarnaAsyncCallback above will fire.\n if (window.Klarna?.Payments) ready()\n } else {\n const s = document.createElement('script')\n s.src = KLARNA_KP_LIB_URL\n s.async = true\n s.onerror = () => {\n clearTimeout(timer)\n kpLoad = null\n reject(new Error('[VioKlarnaKP] failed to load kp/lib/v1/api.js'))\n }\n document.head.appendChild(s)\n }\n }).catch((err) => {\n kpLoad = null // allow retry\n throw err\n })\n\n return kpLoad\n}\n\nexport interface KlarnaPaymentsWidgetInput {\n clientToken: string\n categories: KlarnaPaymentsCategory[]\n container: HTMLElement\n /** Category to load first. Defaults to the first available. */\n category?: string\n}\n\nexport interface KlarnaPaymentsWidget {\n /** Categories offered by the session (pay_now / pay_later / pay_over_time). */\n categories: KlarnaPaymentsCategory[]\n /** Currently selected payment_method_category. */\n selected: string\n /** (Re)load the widget for a category into the container. */\n load(category?: string): Promise<{ showForm: boolean }>\n /**\n * Authorize the selected category. Resolves with the authorization token,\n * rejects on decline/cancel/error. `data` is an optional order-data update\n * (the session already carries the lines; pass billing/extra if available).\n */\n authorize(data?: Record<string, unknown>): Promise<string>\n}\n\n/** True if the Klarna Payments lib can load in this environment. */\nexport async function isKlarnaPaymentsAvailable(): Promise<boolean> {\n if (typeof window === 'undefined') return false\n try {\n await loadKpLib()\n return true\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioKlarnaKP] availability check failed:', err)\n }\n return false\n }\n}\n\n/**\n * Init Klarna Payments with a server-minted client_token and mount the widget.\n * Returns a handle to (re)load categories and to authorize.\n */\nexport async function createKlarnaPaymentsWidget(\n input: KlarnaPaymentsWidgetInput,\n): Promise<KlarnaPaymentsWidget> {\n const Klarna = await loadKpLib()\n Klarna.Payments.init({ client_token: input.clientToken })\n\n let selected =\n input.category ?? input.categories[0]?.identifier ?? 'pay_later'\n\n return {\n categories: input.categories,\n get selected() {\n return selected\n },\n load(category?: string): Promise<{ showForm: boolean }> {\n if (category) selected = category\n return new Promise((resolve, reject) => {\n try {\n // 3-arg form per Klarna docs: (options, data, callback). The empty\n // data object is required — a 2-arg call risks the SDK treating the\n // callback as `data` and never invoking it.\n Klarna.Payments.load(\n { container: input.container, payment_method_category: selected },\n {},\n (res) => {\n if (res?.error) reject(res.error)\n else resolve({ showForm: res?.show_form !== false })\n },\n )\n } catch (err) {\n reject(err)\n }\n })\n },\n authorize(data?: Record<string, unknown>): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n try {\n Klarna.Payments.authorize(\n { payment_method_category: selected, auto_finalize: true },\n data ?? {},\n (res) => {\n if (res?.approved && res.authorization_token) {\n resolve(res.authorization_token)\n } else if (res?.error) {\n reject(res.error)\n } else if (res?.finalize_required) {\n reject(new Error('Klarna requires a finalize step (multistep)'))\n } else {\n // approved:false without an error == user cancelled / declined.\n reject(new Error('Klarna authorization was not approved'))\n }\n },\n )\n } catch (err) {\n reject(err)\n }\n })\n },\n }\n}\n","/**\n * CheckoutManager — orchestrates the checkout flow.\n *\n * Stable contract: open / setAddress / selectPaymentMethod / close.\n * Per-vendor payment integrations plug into the corresponding method:\n * - Apple Pay → `startApplePay()` (Stripe Payment Request, this iteration)\n * - Klarna / Vipps / Card → land in subsequent iterations\n *\n * Dispatches `change` (state changes) and `payment-select` (user picked\n * a method) and `payment-complete` (vendor sheet completed successfully).\n */\n\nimport type { CartLineItem } from '../cart/types.js'\nimport type { CartManager } from '../cart/cart-manager.js'\nimport { Configuration } from '../configuration.js'\nimport {\n checkApplePayAvailability,\n prepareApplePay,\n showApplePaySheet,\n type ApplePayResult,\n} from './payments/apple-pay.js'\nimport {\n cleanUrlParams,\n isKlarnaAvailable,\n listenForKlarnaCompletion,\n mountKlarnaExpressButton,\n readKlarnaTokenFromUrl,\n type KlarnaAuthorizeResult,\n type KlarnaButtonHandle,\n type KlarnaLineItem,\n type KlarnaPaymentRequestData,\n} from './payments/klarna.js'\nimport {\n createKlarnaPaymentsWidget,\n isKlarnaPaymentsAvailable,\n type KlarnaPaymentsCategory,\n} from './payments/klarna-payments.js'\n\n/**\n * Best-effort human-readable string for an unknown thrown/rejected value.\n * Klarna's SDK rejects with plain objects, so `String(err)` would collapse to\n * \"[object Object]\"; we pull a known message field or JSON-serialise so the\n * real reason stays visible.\n */\nfunction describeError(err: unknown): string {\n if (err instanceof Error) return err.message\n if (typeof err === 'string') return err\n if (err && typeof err === 'object') {\n const o = err as Record<string, unknown>\n for (const k of ['message', 'error', 'reason', 'description']) {\n if (typeof o[k] === 'string' && o[k]) return o[k] as string\n }\n try {\n return JSON.stringify(err)\n } catch {\n return String(err)\n }\n }\n return String(err)\n}\n\n/** sessionStorage key for a pending Klarna purchase (survives redirect). */\nconst KLARNA_PENDING_KEY = 'vio.klarna.pending.v1'\n\ninterface KlarnaPendingContext {\n sponsorId: number\n currency: string\n orderAmount: number\n orderLines: Array<{\n name: string\n quantity: number\n unit_price: number\n total_amount: number\n reference?: string\n /** Klarna line type, e.g. \"shipping_fee\". */\n type?: string\n }>\n}\n\n/** A shipping option offered in the checkout. `price` in minor units (øre). */\nexport interface KlarnaShippingOption {\n id: string\n method: string\n description: string\n price: number\n tax_amount: number\n tax_rate: number\n preselected: boolean\n}\n\n/**\n * Shipping options offered for express purchases. Amounts in minor units (øre).\n * The chosen one is added to the order total + as a `shipping_fee` line so the\n * Klarna order reconciles. (Klarna Payments doesn't render a shipping picker —\n * KCO/KSA would, but the account isn't provisioned — so the picker is ours.)\n */\nexport const KLARNA_SHIPPING_OPTIONS: KlarnaShippingOption[] = [\n {\n id: 'standard',\n method: 'Standard',\n description: '3–5 virkedager',\n price: 4900,\n tax_amount: 0,\n tax_rate: 0,\n preselected: true,\n },\n {\n id: 'express',\n method: 'Express',\n description: '1–2 virkedager',\n price: 9900,\n tax_amount: 0,\n tax_rate: 0,\n preselected: false,\n },\n]\nimport type { CheckoutAddress, CheckoutState, PaymentMethod } from './types.js'\n\nexport interface CheckoutChangeDetail {\n state: CheckoutState | null\n}\n\nexport interface PaymentSelectDetail {\n method: PaymentMethod\n state: CheckoutState\n}\n\nexport interface PaymentCompleteDetail {\n method: PaymentMethod\n state: CheckoutState\n result: ApplePayResult | KlarnaAuthorizeResult | unknown\n}\n\nexport interface PaymentErrorDetail {\n method: PaymentMethod\n error: string\n}\n\n/** Handle for the Klarna Payments (classic widget) flow. */\nexport interface KlarnaPaymentsHandle {\n /** Categories offered by the session (pay_now / pay_later / pay_over_time). */\n categories: KlarnaPaymentsCategory[]\n /** Currently selected category. */\n readonly selected: string\n /** (Re)load the widget for a category. */\n load(category?: string): Promise<{ showForm: boolean }>\n /** Authorize the selected method and (on approval) create the order. */\n authorize(): Promise<void>\n /** Tear down the mounted widget. */\n unmount(): void\n}\n\nexport class CheckoutManager extends EventTarget {\n private state: CheckoutState | null = null\n private applePayAvailableCache: boolean | null = null\n private klarnaAvailableCache: boolean | null = null\n private klarnaOrderInFlight = false\n\n constructor(private readonly cartManager: CartManager) {\n super()\n }\n\n open(sponsorId: number): CheckoutState {\n const cart = this.cartManager.getCart(sponsorId)\n if (!cart || cart.items.length === 0) {\n throw new Error(`[VioCheckout] sponsor ${sponsorId} has no cart items`)\n }\n this.state = {\n sponsorId,\n subtotal: this.cartManager.subtotalForSponsor(sponsorId),\n currency: cart.currency,\n }\n this.emit()\n return this.state\n }\n\n close(): void {\n this.state = null\n this.applePayAvailableCache = null\n this.klarnaAvailableCache = null\n this.emit()\n }\n\n setAddress(address: CheckoutAddress): void {\n if (!this.state) return\n // Immutable update — a fresh object reference so reactive UIs (Lit\n // `@state`, which compares by identity) actually re-render.\n this.state = { ...this.state, address }\n this.emit()\n }\n\n selectPaymentMethod(method: PaymentMethod): void {\n if (!this.state) return\n // New reference (see setAddress) so the selection re-renders.\n this.state = { ...this.state, paymentMethod: method }\n this.emit()\n this.dispatchEvent(\n new CustomEvent<PaymentSelectDetail>('payment-select', {\n detail: { method, state: this.state },\n }),\n )\n }\n\n // MARK: - Apple Pay (Stripe Payment Request)\n\n /**\n * Returns true if Apple Pay can be shown on this device + Stripe config.\n * Result is memoised — call `clearApplePayCache()` if config changes.\n */\n async isApplePayAvailable(country = 'NO'): Promise<boolean> {\n if (this.applePayAvailableCache !== null) return this.applePayAvailableCache\n const cfg = Configuration.isInitialized ? Configuration.get() : null\n const publishableKey = cfg?.stripePublishableKey ?? ''\n if (!publishableKey || !this.state) {\n this.applePayAvailableCache = false\n return false\n }\n const amount = toSmallestUnit(this.state.subtotal, this.state.currency)\n const available = await checkApplePayAvailability({\n publishableKey,\n connectedAccount: this.findStripeConnectAccount() ?? undefined,\n amount,\n currency: this.state.currency,\n country,\n label: 'Vio',\n })\n this.applePayAvailableCache = available\n return available\n }\n\n clearApplePayCache(): void {\n this.applePayAvailableCache = null\n }\n\n /**\n * Prepare Apple Pay for the product-page express button (no active checkout\n * needed). Pre-creates the Stripe PaymentRequest + resolves canMakePayment so\n * the returned `show()` can fire synchronously inside the tap (Apple blocks\n * the sheet if `show()` is reached after an await). `show()` resolves the\n * sheet, then dispatches `payment-complete` (→ confirmation) or\n * `payment-error`. `available` is true only when Apple Pay will actually work.\n */\n async prepareApplePayFor(\n amount: number,\n currency: string,\n country = 'NO',\n ): Promise<{ available: boolean; show: () => Promise<void> }> {\n const cfg = Configuration.isInitialized ? Configuration.get() : null\n if (!cfg?.stripePublishableKey) return { available: false, show: async () => {} }\n const prepared = await prepareApplePay({\n publishableKey: cfg.stripePublishableKey,\n amount: toSmallestUnit(amount, currency),\n currency,\n country,\n label: 'Vio',\n // Native Apple Pay shipping — same Standard/Express options as Klarna.\n shippingOptions: KLARNA_SHIPPING_OPTIONS.map((o) => ({\n id: o.id,\n label: o.method,\n detail: o.description,\n amount: o.price,\n })),\n })\n return {\n available: prepared.available,\n show: async (): Promise<void> => {\n try {\n const result = await prepared.show()\n this.selectPaymentMethod('apple-pay')\n const state: CheckoutState =\n this.state ?? { sponsorId: 0, subtotal: amount, currency }\n this.dispatchEvent(\n new CustomEvent<PaymentCompleteDetail>('payment-complete', {\n detail: { method: 'apple-pay', state, result },\n }),\n )\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioCheckout] Apple Pay express failed:', err)\n }\n this.dispatchEvent(\n new CustomEvent<PaymentErrorDetail>('payment-error', {\n detail: { method: 'apple-pay', error: describeError(err) },\n }),\n )\n }\n },\n }\n }\n\n /**\n * Prepare an Apple Pay express charge for an arbitrary amount (e.g. the whole\n * cart) with NO active checkout. Unlike `prepareApplePayFor`, the returned\n * `show()` RESOLVES with the result (or `null` on cancel/failure) and does\n * NOT dispatch the global `payment-complete` — so no checkout overlay appears.\n * The caller (the cart drawer) renders its own confirmation. `show()` must be\n * called synchronously inside the tap (Apple's user-gesture rule).\n */\n async prepareApplePayExpress(\n amount: number,\n currency: string,\n country = 'NO',\n ): Promise<{ available: boolean; show: () => Promise<ApplePayResult | null> }> {\n const cfg = Configuration.isInitialized ? Configuration.get() : null\n if (!cfg?.stripePublishableKey) return { available: false, show: async () => null }\n const prepared = await prepareApplePay({\n publishableKey: cfg.stripePublishableKey,\n amount: toSmallestUnit(amount, currency),\n currency,\n country,\n label: 'Vio',\n // Native Apple Pay shipping (same Standard/Express options as Klarna) —\n // selected inside the sheet, so it's not a separate checkout step.\n shippingOptions: KLARNA_SHIPPING_OPTIONS.map((o) => ({\n id: o.id,\n label: o.method,\n detail: o.description,\n amount: o.price,\n })),\n })\n return {\n available: prepared.available,\n show: async (): Promise<ApplePayResult | null> => {\n try {\n return await prepared.show()\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioCheckout] cart Apple Pay express failed:', err)\n }\n return null\n }\n },\n }\n }\n\n /**\n * Launches the Apple Pay sheet. Resolves with the Stripe PaymentMethod\n * id once the user authorises — the backend then confirms the\n * PaymentIntent with that id to actually capture the funds.\n */\n async startApplePay(options: {\n country?: string\n label?: string\n } = {}): Promise<ApplePayResult> {\n if (!this.state) throw new Error('[VioCheckout] no active checkout — call open() first')\n const cfg = Configuration.get()\n if (!cfg.stripePublishableKey) {\n throw new Error(\n '[VioCheckout] No Stripe publishable key configured. Pass `stripePublishableKey` to Vio.init({ ... }).',\n )\n }\n const amount = toSmallestUnit(this.state.subtotal, this.state.currency)\n const result = await showApplePaySheet({\n publishableKey: cfg.stripePublishableKey,\n connectedAccount: this.findStripeConnectAccount() ?? undefined,\n amount,\n currency: this.state.currency,\n country: options.country ?? 'NO',\n label: options.label ?? 'Vio',\n })\n this.selectPaymentMethod('apple-pay')\n this.dispatchEvent(\n new CustomEvent<PaymentCompleteDetail>('payment-complete', {\n detail: { method: 'apple-pay', state: this.state, result },\n }),\n )\n return result\n }\n\n // MARK: - Klarna Express Checkout (Klarna Web SDK v2)\n\n /**\n * True if the Klarna Express button can be offered (clientId configured +\n * SDK loads). Memoised per active checkout. Never throws.\n */\n async isKlarnaExpressAvailable(): Promise<boolean> {\n if (this.klarnaAvailableCache !== null) return this.klarnaAvailableCache\n const cfg = Configuration.isInitialized ? Configuration.get() : null\n const clientId = cfg?.klarnaClientId ?? ''\n if (!clientId || !this.state) {\n this.klarnaAvailableCache = false\n return false\n }\n const available = await isKlarnaAvailable({\n clientId,\n locale: 'nb-NO',\n environment: cfg?.klarnaEnvironment,\n })\n this.klarnaAvailableCache = available\n return available\n }\n\n clearKlarnaCache(): void {\n this.klarnaAvailableCache = null\n }\n\n /**\n * Build the Klarna payment request from the active cart — amounts in the\n * currency's minor unit (øre/cents), one line item per cart line.\n */\n buildKlarnaPaymentRequest(): KlarnaPaymentRequestData {\n if (!this.state) throw new Error('[VioCheckout] no active checkout — call open() first')\n const currency = this.state.currency\n const lineItems: KlarnaLineItem[] = this.items.map((item) => {\n const unitPrice = toSmallestUnit(item.unitPrice, currency)\n return {\n name: item.name || item.brand || 'Produkt',\n quantity: item.quantity,\n unitPrice,\n totalAmount: unitPrice * item.quantity,\n reference: String(item.productId),\n ...(item.imageUrl ? { imageUrl: item.imageUrl } : {}),\n }\n })\n return {\n currency,\n amount: toSmallestUnit(this.state.subtotal, currency),\n supplementaryPurchaseData: { lineItems },\n }\n }\n\n /**\n * Mount the Klarna Express button into `container`. On a successful\n * authorization, fires `payment-complete` with the authorization token —\n * the host (or vio-backend) then creates the Klarna order server-side.\n *\n * Returns the button handle so the UI can unmount on teardown.\n */\n async mountKlarnaExpress(container: HTMLElement): Promise<KlarnaButtonHandle> {\n if (!this.state) throw new Error('[VioCheckout] no active checkout — call open() first')\n const cfg = Configuration.get()\n if (!cfg.klarnaClientId) {\n throw new Error(\n '[VioCheckout] No Klarna client id configured. Pass `klarnaClientId` to Vio.init({ ... }).',\n )\n }\n const pendingContext = this.buildKlarnaPendingContext()\n return mountKlarnaExpressButton({\n config: {\n clientId: cfg.klarnaClientId,\n locale: 'nb-NO',\n environment: cfg.klarnaEnvironment,\n },\n container,\n paymentRequest: this.buildKlarnaPaymentRequest(),\n pendingKey: KLARNA_PENDING_KEY,\n pendingContext,\n // POPUP path: the initiate() promise resolves in-page with the token.\n onAuthorize: (result) => {\n void this.completeKlarnaOrder(result.authorizationToken, pendingContext, result)\n },\n onError: (err) => {\n if (typeof console !== 'undefined') {\n console.warn('[VioCheckout] Klarna Express cancelled/error:', err)\n }\n // Surface the error in the UI (not just the console). Klarna's reject\n // payload is often a plain object, so serialise it instead of letting\n // String(err) collapse to \"[object Object]\" — we need the real reason\n // (e.g. validation field, unsupported initiationMode, blocked origin)\n // visible on screen while we stabilise the flow.\n this.dispatchEvent(\n new CustomEvent<PaymentErrorDetail>('payment-error', {\n detail: { method: 'klarna', error: describeError(err) },\n }),\n )\n },\n })\n }\n\n /**\n * Klarna Payments — classic widget flow (server client_token). Creates a\n * session on vio-backend, then mounts Klarna's inline widget into\n * `container`. Returns a handle to switch category and to authorize → which\n * on approval creates the order via the same backend /orders route as KEC.\n *\n * Unlike `mountKlarnaExpress`, this needs no public `klarnaClientId` and no\n * origin handshake — auth is the server-side API key.\n */\n async mountKlarnaPayments(\n container: HTMLElement,\n opts?: { withShipping?: boolean; shippingId?: string },\n ): Promise<KlarnaPaymentsHandle> {\n if (!this.state) throw new Error('[VioCheckout] no active checkout — call open() first')\n const cfg = Configuration.get()\n // With shipping: add the CHOSEN shipping option as a shipping_fee line +\n // bump the total. (Klarna Payments doesn't render a picker; ours lives in\n // the checkout UI and re-mounts this widget with the new total on change.)\n const { ctx, shippingOptions } = opts?.withShipping\n ? this.buildKlarnaInstantContext(opts.shippingId)\n : { ctx: this.buildKlarnaPendingContext(), shippingOptions: undefined }\n\n // 1. Create the Payments session on the backend (it holds the API key).\n const res = await fetch(`${cfg.apiBase}/v2/commerce/klarna/sessions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-API-Key': cfg.apiKey },\n body: JSON.stringify({\n currency: ctx.currency,\n purchaseCountry: 'NO',\n locale: 'nb-NO',\n orderAmount: ctx.orderAmount,\n orderLines: ctx.orderLines,\n ...(shippingOptions ? { shippingOptions } : {}),\n }),\n })\n const json = (await res.json().catch(() => ({}))) as {\n error?: string\n clientToken?: string\n paymentMethodCategories?: KlarnaPaymentsCategory[]\n }\n if (!res.ok || !json.clientToken) {\n throw new Error(json?.error ?? `Klarna session failed (HTTP ${res.status})`)\n }\n\n // 2. Mount the inline widget and load the first category.\n const widget = await createKlarnaPaymentsWidget({\n clientToken: json.clientToken,\n categories: json.paymentMethodCategories ?? [],\n container,\n })\n await widget.load()\n\n return {\n categories: widget.categories,\n get selected() {\n return widget.selected\n },\n load: (category?: string) => widget.load(category),\n authorize: async (): Promise<void> => {\n try {\n // The session already carries the order (country/currency/lines);\n // Klarna collects customer details in its widget. Authorize with no\n // update payload to avoid any session/payload mismatch.\n const token = await widget.authorize()\n await this.completeKlarnaOrder(token, ctx, { authorizationToken: token })\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioCheckout] Klarna Payments authorize failed:', err)\n }\n this.dispatchEvent(\n new CustomEvent<PaymentErrorDetail>('payment-error', {\n detail: { method: 'klarna', error: describeError(err) },\n }),\n )\n }\n },\n unmount: () => {\n try {\n container.innerHTML = ''\n } catch {\n /* already gone */\n }\n },\n }\n }\n\n /** True if the Klarna Payments widget lib can load (UI gate). */\n async klarnaPaymentsAvailable(): Promise<boolean> {\n return isKlarnaPaymentsAvailable()\n }\n\n /** Cart snapshot + chosen shipping line/amount, for express purchases. */\n private buildKlarnaInstantContext(shippingId?: string): {\n ctx: KlarnaPendingContext\n shippingOptions: typeof KLARNA_SHIPPING_OPTIONS\n } {\n const base = this.buildKlarnaPendingContext()\n const shipping =\n (shippingId ? KLARNA_SHIPPING_OPTIONS.find((o) => o.id === shippingId) : undefined) ??\n KLARNA_SHIPPING_OPTIONS.find((o) => o.preselected) ??\n KLARNA_SHIPPING_OPTIONS[0]\n const orderLines = [...base.orderLines]\n if (shipping) {\n orderLines.push({\n name: `Frakt – ${shipping.method}`,\n quantity: 1,\n unit_price: shipping.price,\n total_amount: shipping.price,\n reference: `shipping:${shipping.id}`,\n type: 'shipping_fee',\n })\n }\n return {\n ctx: {\n ...base,\n orderLines,\n orderAmount: base.orderAmount + (shipping?.price ?? 0),\n },\n shippingOptions: KLARNA_SHIPPING_OPTIONS,\n }\n }\n\n /**\n * Express instant purchase — go straight to Klarna's own modal, no checkout\n * overlay. Creates a session (with shipping options), loads the widget into a\n * hidden container, then authorizes (which opens Klarna's confirm modal). On\n * approval creates the order → `payment-complete` (host shows confirmation);\n * on failure → `payment-error`. Call `open(sponsorId)` first.\n */\n async startKlarnaInstant(): Promise<void> {\n if (!this.state) throw new Error('[VioCheckout] no active checkout — call open() first')\n const cfg = Configuration.get()\n const { ctx, shippingOptions } = this.buildKlarnaInstantContext()\n\n // 1. Session on the backend (it holds the API key) — includes shipping.\n let clientToken: string\n let categories: KlarnaPaymentsCategory[]\n try {\n const res = await fetch(`${cfg.apiBase}/v2/commerce/klarna/sessions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-API-Key': cfg.apiKey },\n body: JSON.stringify({\n currency: ctx.currency,\n purchaseCountry: 'NO',\n locale: 'nb-NO',\n orderAmount: ctx.orderAmount,\n orderLines: ctx.orderLines,\n shippingOptions,\n }),\n })\n const json = (await res.json().catch(() => ({}))) as {\n error?: string\n clientToken?: string\n paymentMethodCategories?: KlarnaPaymentsCategory[]\n }\n if (!res.ok || !json.clientToken) {\n throw new Error(json?.error ?? `Klarna session failed (HTTP ${res.status})`)\n }\n clientToken = json.clientToken\n categories = json.paymentMethodCategories ?? []\n } catch (err) {\n this.dispatchEvent(\n new CustomEvent<PaymentErrorDetail>('payment-error', {\n detail: { method: 'klarna', error: describeError(err) },\n }),\n )\n return\n }\n\n // 2. Hidden container → load → authorize (opens Klarna's own modal).\n const container = document.createElement('div')\n container.setAttribute('aria-hidden', 'true')\n container.style.cssText =\n 'position:fixed;left:-9999px;top:0;width:1px;height:1px;overflow:hidden;'\n document.body.appendChild(container)\n try {\n const widget = await createKlarnaPaymentsWidget({ clientToken, categories, container })\n await widget.load()\n const token = await widget.authorize()\n await this.completeKlarnaOrder(token, ctx, { authorizationToken: token })\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.warn('[VioCheckout] Klarna instant failed:', err)\n }\n this.dispatchEvent(\n new CustomEvent<PaymentErrorDetail>('payment-error', {\n detail: { method: 'klarna', error: describeError(err) },\n }),\n )\n } finally {\n try {\n container.remove()\n } catch {\n /* already gone */\n }\n }\n }\n\n /**\n * REDIRECT path: call once on app load. If a Klarna purchase was launched\n * (pending context persisted) and we're back with a token — from the URL or\n * the SDK's resumed `complete` event — finish creating the order + confirm.\n */\n async resumeKlarnaReturn(): Promise<void> {\n if (typeof sessionStorage === 'undefined') return\n const raw = sessionStorage.getItem(KLARNA_PENDING_KEY)\n if (!raw) return\n let pending: KlarnaPendingContext\n try {\n pending = JSON.parse(raw) as KlarnaPendingContext\n } catch {\n sessionStorage.removeItem(KLARNA_PENDING_KEY)\n return\n }\n\n // 1) Token already in the URL (most redirect flows append it).\n const fromUrl = readKlarnaTokenFromUrl()\n if (fromUrl) {\n cleanUrlParams([fromUrl.param])\n await this.completeKlarnaOrder(fromUrl.token, pending, { authorizationToken: fromUrl.token })\n return\n }\n\n // No recognised token param — log what Klarna actually returned so the\n // param name can be mapped if the SDK `complete` event doesn't fire.\n if (typeof window !== 'undefined' && typeof console !== 'undefined' && window.location.search) {\n console.warn(\n '[VioCheckout] Klarna return: no known token param. URL was:',\n window.location.search,\n )\n }\n\n // 2) Otherwise let the SDK resume its session and fire `complete`.\n const cfg = Configuration.isInitialized ? Configuration.get() : null\n if (!cfg?.klarnaClientId) return\n await listenForKlarnaCompletion({\n config: { clientId: cfg.klarnaClientId, locale: 'nb-NO', environment: cfg.klarnaEnvironment },\n onComplete: (result) => {\n void this.completeKlarnaOrder(result.authorizationToken, pending, result)\n },\n onError: (err) => {\n if (typeof console !== 'undefined') {\n console.warn('[VioCheckout] Klarna resume error:', err)\n }\n },\n })\n }\n\n /** Snapshot of the active cart for redirect recovery (minor units). */\n private buildKlarnaPendingContext(): KlarnaPendingContext {\n if (!this.state) throw new Error('[VioCheckout] no active checkout')\n const currency = this.state.currency\n return {\n sponsorId: this.state.sponsorId,\n currency,\n orderAmount: toSmallestUnit(this.state.subtotal, currency),\n orderLines: this.items.map((item) => {\n const unitPrice = toSmallestUnit(item.unitPrice, currency)\n return {\n name: item.name || item.brand || 'Produkt',\n quantity: item.quantity,\n unit_price: unitPrice,\n total_amount: unitPrice * item.quantity,\n reference: String(item.productId),\n }\n }),\n }\n }\n\n /**\n * POST the token + order lines to vio-backend (it holds the secret API key\n * and creates the real Klarna order). On success → `payment-complete`; on\n * failure → `payment-error`. Idempotent: clears the pending key so the\n * popup and redirect paths can't double-fire.\n */\n private async completeKlarnaOrder(\n authorizationToken: string,\n ctx: KlarnaPendingContext,\n result: KlarnaAuthorizeResult,\n ): Promise<void> {\n if (typeof sessionStorage !== 'undefined') {\n // Idempotency guard — first caller wins.\n if (this.klarnaOrderInFlight) return\n this.klarnaOrderInFlight = true\n sessionStorage.removeItem(KLARNA_PENDING_KEY)\n }\n const cfg = Configuration.get()\n try {\n const res = await fetch(`${cfg.apiBase}/v2/commerce/klarna/orders`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-API-Key': cfg.apiKey },\n body: JSON.stringify({\n authorizationToken,\n purchaseCountry: 'NO',\n currency: ctx.currency,\n locale: 'nb-NO',\n orderAmount: ctx.orderAmount,\n orderLines: ctx.orderLines,\n }),\n })\n const json = (await res.json().catch(() => ({}))) as { error?: string; orderId?: string }\n if (!res.ok) throw new Error(json?.error ?? `Klarna order failed (HTTP ${res.status})`)\n\n // Synthesize a checkout state for the confirmation if the live one was\n // lost to a redirect reload.\n const state: CheckoutState =\n this.state ?? { sponsorId: ctx.sponsorId, subtotal: ctx.orderAmount, currency: ctx.currency }\n this.dispatchEvent(\n new CustomEvent<PaymentCompleteDetail>('payment-complete', {\n detail: {\n method: 'klarna',\n state,\n // chargedTotal in MAJOR units (incl. shipping for express) for the\n // confirmation screen. ctx.orderAmount is minor (øre) → /100.\n result: { ...result, order: json, chargedTotal: ctx.orderAmount / 100 },\n },\n }),\n )\n } catch (err) {\n if (typeof console !== 'undefined') {\n console.error('[VioCheckout] Klarna order creation failed:', err)\n }\n this.dispatchEvent(\n new CustomEvent<PaymentErrorDetail>('payment-error', {\n detail: { method: 'klarna', error: err instanceof Error ? err.message : String(err) },\n }),\n )\n } finally {\n this.klarnaOrderInFlight = false\n }\n }\n\n // MARK: - Accessors\n\n get currentState(): CheckoutState | null {\n return this.state\n }\n\n get items(): CartLineItem[] {\n if (!this.state) return []\n return this.cartManager.getCart(this.state.sponsorId)?.items ?? []\n }\n\n // MARK: - Internals\n\n /**\n * Resolve the Stripe Connect account for the active sponsor — for now\n * pulled from bootstrap cache if present. Returns undefined if not set\n * (Stripe will route to the platform account in that case).\n */\n private findStripeConnectAccount(): string | undefined {\n // Placeholder hook — when bootstrap exposes per-sponsor stripeAccount\n // we'll wire it here. For now returns undefined.\n return undefined\n }\n\n private emit(): void {\n this.dispatchEvent(\n new CustomEvent<CheckoutChangeDetail>('change', { detail: { state: this.state } }),\n )\n }\n}\n\n/**\n * Stripe expects amounts in the smallest currency unit. NOK/SEK/DKK/EUR/USD\n * are all hundredths (øre, öre, øre, cents, cents). JPY is the exception\n * (no fractional unit).\n */\nfunction toSmallestUnit(amount: number, currency: string): number {\n const zeroDecimal = new Set(['JPY', 'KRW', 'VND'])\n if (zeroDecimal.has(currency.toUpperCase())) return Math.round(amount)\n return Math.round(amount * 100)\n}\n","/**\n * Vio — public SDK entry point + facade.\n *\n * Usage:\n * import { Vio } from 'vio'\n * Vio.init({ apiKey: 'xxx' }) // backend-bound calls require this\n * await Vio.bootstrap() // GET /v2/mobile/config\n *\n * // Client-side primitives — no init needed:\n * Vio.cart.addProduct({ product, sponsorId: 3 })\n * Vio.checkout.open(3)\n *\n * // Backend-bound:\n * const products = await Vio.commerceFor(3).channel.product.getByIds({\n * product_ids: [408895],\n * })\n */\n\nimport { Configuration, type VioConfig } from './configuration.js'\nimport { createVioApi, type VioApi } from './api/vio.js'\nimport { createCommerceClient, type CommerceClient } from './api/commerce.js'\nimport { CartManager } from './cart/cart-manager.js'\nimport { CheckoutManager } from './checkout/checkout-manager.js'\nimport type { BootstrapResponse, Sponsor } from './types.js'\n\nclass VioFacade {\n private apiInstance: VioApi | null = null\n private commerceClients = new Map<number, CommerceClient>()\n private bootstrapPromise: Promise<BootstrapResponse> | null = null\n private cachedBootstrap: BootstrapResponse | null = null\n\n // Client-side managers — created lazily on first access. They don't\n // need Vio.init() to work (state is purely local).\n private cartManager: CartManager | null = null\n private checkoutManager: CheckoutManager | null = null\n\n init(config: VioConfig): void {\n Configuration.init(config)\n // Reset cached backend instances so a re-init picks up the new config.\n this.apiInstance = null\n this.commerceClients.clear()\n this.bootstrapPromise = null\n this.cachedBootstrap = null\n // NOTE: cart / checkout managers are NOT reset — user cart state is\n // independent of SDK re-config.\n }\n\n get isInitialized(): boolean { return Configuration.isInitialized }\n get config() { return Configuration.get() }\n\n // MARK: - Client-side managers (no init required)\n\n /** Multi-sponsor cart manager. Reactive — listen via addEventListener('change', ...). */\n get cart(): CartManager {\n if (!this.cartManager) this.cartManager = new CartManager()\n return this.cartManager\n }\n\n /** Checkout flow manager. Subscribes to cart state via the CartManager. */\n get checkout(): CheckoutManager {\n if (!this.checkoutManager) this.checkoutManager = new CheckoutManager(this.cart)\n return this.checkoutManager\n }\n\n // MARK: - Backend-bound\n\n /** Lazy VioApi for REST endpoints on `api-dev.vio.live`. */\n get api(): VioApi {\n if (!this.apiInstance) {\n const cfg = Configuration.get()\n this.apiInstance = createVioApi({ apiBase: cfg.apiBase, apiKey: cfg.apiKey })\n }\n return this.apiInstance\n }\n\n /**\n * Bootstrap — fetches client config and caches it. Dedupes in-flight\n * concurrent requests.\n */\n async bootstrap(): Promise<BootstrapResponse> {\n if (this.cachedBootstrap) return this.cachedBootstrap\n if (this.bootstrapPromise) return this.bootstrapPromise\n this.bootstrapPromise = this.api\n .bootstrap()\n .then((res) => {\n this.cachedBootstrap = res\n return res\n })\n .finally(() => {\n this.bootstrapPromise = null\n })\n return this.bootstrapPromise\n }\n\n get bootstrapCache(): BootstrapResponse | null {\n return this.cachedBootstrap\n }\n\n /**\n * Get a CommerceClient scoped to a specific sponsor (via bootstrap).\n * Throws if bootstrap hasn't been called or the sponsor is unknown.\n */\n commerceFor(sponsorId: number): CommerceClient {\n const existing = this.commerceClients.get(sponsorId)\n if (existing) return existing\n const sponsor = this.findSponsor(sponsorId)\n if (!sponsor) {\n throw new Error(\n `[Vio] Sponsor ${sponsorId} not found in bootstrap. Call Vio.bootstrap() first or pass commerce-key directly.`,\n )\n }\n const cfg = Configuration.get()\n const client = createCommerceClient({ endpoint: cfg.graphQLBase, apiKey: sponsor.commerce.apiKey })\n this.commerceClients.set(sponsorId, client)\n return client\n }\n\n /** Get a CommerceClient using an explicit commerce apiKey (skip bootstrap). */\n commerceWithKey(commerceApiKey: string): CommerceClient {\n const cfg = Configuration.get()\n return createCommerceClient({ endpoint: cfg.graphQLBase, apiKey: commerceApiKey })\n }\n\n private findSponsor(sponsorId: number): Sponsor | undefined {\n const boot = this.cachedBootstrap\n if (!boot) return undefined\n if (boot.primarySponsor?.id === sponsorId) return boot.primarySponsor\n return boot.secondarySponsors?.find((s) => s.id === sponsorId)\n }\n}\n\n// @__PURE__ lets bundlers drop the singleton when a consumer imports only\n// tree-shakeable helpers (e.g. `formatPrice`) from `@vio-live/web-sdk/core`.\n// The constructor only sets fields (managers are created lazily), so eliding\n// an unused `Vio` has no observable effect.\nexport const Vio = /* @__PURE__ */ new VioFacade()\n"]}
|
|
@@ -1,300 +0,0 @@
|
|
|
1
|
-
import * as lit_html from 'lit-html';
|
|
2
|
-
import * as lit from 'lit';
|
|
3
|
-
import { LitElement } from 'lit';
|
|
4
|
-
|
|
5
|
-
declare class VioProduct extends LitElement {
|
|
6
|
-
/** Brand label shown at the top (uppercase, gray, small). */
|
|
7
|
-
brand: string;
|
|
8
|
-
/** Product display name. Two-line truncation. */
|
|
9
|
-
name: string;
|
|
10
|
-
/** Pre-formatted price string (e.g. "990 kr"). Bold. */
|
|
11
|
-
price: string;
|
|
12
|
-
/** Retailer / sponsor name shown at the bottom (uppercase, gray). */
|
|
13
|
-
retailer: string;
|
|
14
|
-
/** Product image URL. Square aspect, gray bg if missing. */
|
|
15
|
-
imageUrl: string;
|
|
16
|
-
/** Vio product id, propagated to click event. */
|
|
17
|
-
productId: string;
|
|
18
|
-
/** Vio sponsor id, propagated to click event. */
|
|
19
|
-
sponsorId: string;
|
|
20
|
-
/** Whether the product has selectable variants — the quick-add button then
|
|
21
|
-
* opens the detail to pick one instead of adding directly. */
|
|
22
|
-
hasVariants: boolean;
|
|
23
|
-
/** True when this product currently sits in the cart (persistent mark). */
|
|
24
|
-
private inCart;
|
|
25
|
-
/** Total units of this product in the cart (shown as a count when > 1). */
|
|
26
|
-
private cartQty;
|
|
27
|
-
/** Transient flag driving the add "pop" animation. */
|
|
28
|
-
private justAdded;
|
|
29
|
-
private boundCartChange;
|
|
30
|
-
static styles: lit.CSSResult;
|
|
31
|
-
connectedCallback(): void;
|
|
32
|
-
disconnectedCallback(): void;
|
|
33
|
-
updated(changed: Map<string, unknown>): void;
|
|
34
|
-
/** Reflect whether (and how many units of) this product sit in the cart. */
|
|
35
|
-
private updateInCart;
|
|
36
|
-
private onClick;
|
|
37
|
-
private onKeydown;
|
|
38
|
-
/** Quick add-to-cart. If the product has selectable variants, open the detail
|
|
39
|
-
* to pick one instead (the host can't choose for the user). Otherwise emit
|
|
40
|
-
* `vio:product-add` so the host adds it (bumping quantity on repeat taps). */
|
|
41
|
-
private onAdd;
|
|
42
|
-
render(): lit_html.TemplateResult<1>;
|
|
43
|
-
}
|
|
44
|
-
declare global {
|
|
45
|
-
interface HTMLElementTagNameMap {
|
|
46
|
-
'vio-product': VioProduct;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
declare class VioProductCarousel extends LitElement {
|
|
51
|
-
/** Small uppercase label in accent color (e.g. "REDAKSJONENS FAVORITTER"). */
|
|
52
|
-
label: string;
|
|
53
|
-
/** Big serif heading (e.g. "Shop Favorittene"). */
|
|
54
|
-
heading: string;
|
|
55
|
-
/** Inline gray disclaimer next to the heading (e.g. "annonselenker"). */
|
|
56
|
-
disclaimer: string;
|
|
57
|
-
/** URL for the "Se alle" link. Hidden if empty. */
|
|
58
|
-
seeAllHref: string;
|
|
59
|
-
/** Label for the see-all link. Defaults to Norwegian. */
|
|
60
|
-
seeAllLabel: string;
|
|
61
|
-
/** Auto-fetch mode: comma-separated product ids (e.g. "408895,408896"). */
|
|
62
|
-
productIds: string;
|
|
63
|
-
/** Auto-fetch mode option A: explicit per-sponsor commerce apiKey. */
|
|
64
|
-
commerceKey: string;
|
|
65
|
-
/** Auto-fetch mode option B: sponsor id looked up via Vio.bootstrap. */
|
|
66
|
-
sponsorId: number;
|
|
67
|
-
/**
|
|
68
|
-
* Multi-sponsor mode: `"sponsorId:productId,sponsorId:productId,…"`. Each
|
|
69
|
-
* pair resolves its own commerce client via `Vio.commerceFor(sponsorId)`;
|
|
70
|
-
* fetches run in parallel and results are merged preserving input order.
|
|
71
|
-
* Each rendered <vio-product> carries the per-item sponsor-id so taps go
|
|
72
|
-
* to <vio-product-detail> with the right commerce context.
|
|
73
|
-
*
|
|
74
|
-
* Takes precedence over `product-ids` if both are set.
|
|
75
|
-
*/
|
|
76
|
-
productRefs: string;
|
|
77
|
-
/** Currency for product prices. */
|
|
78
|
-
currency: string;
|
|
79
|
-
private scroller;
|
|
80
|
-
private fetched;
|
|
81
|
-
private isLoading;
|
|
82
|
-
private fetchError;
|
|
83
|
-
static styles: lit.CSSResult;
|
|
84
|
-
connectedCallback(): void;
|
|
85
|
-
updated(changed: Map<string, unknown>): void;
|
|
86
|
-
private autoFetch;
|
|
87
|
-
private parseRefs;
|
|
88
|
-
private scrollByDirection;
|
|
89
|
-
private renderScrollerContent;
|
|
90
|
-
render(): lit_html.TemplateResult<1>;
|
|
91
|
-
}
|
|
92
|
-
declare global {
|
|
93
|
-
interface HTMLElementTagNameMap {
|
|
94
|
-
'vio-product-carousel': VioProductCarousel;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
declare class VioProductDetail extends LitElement {
|
|
99
|
-
open: boolean;
|
|
100
|
-
productId: string;
|
|
101
|
-
sponsorId: number;
|
|
102
|
-
/** Subscribe to `vio:product-click` on the document and auto-open. */
|
|
103
|
-
autoOpen: boolean;
|
|
104
|
-
currency: string;
|
|
105
|
-
private product;
|
|
106
|
-
private isLoading;
|
|
107
|
-
private fetchError;
|
|
108
|
-
private selectedOptions;
|
|
109
|
-
private quantity;
|
|
110
|
-
private activeImageIndex;
|
|
111
|
-
private adding;
|
|
112
|
-
/** Apple Pay actually usable (real Stripe + registered domain) — set on load. */
|
|
113
|
-
private applePayOk;
|
|
114
|
-
/** Pre-prepared Apple Pay handle — show() fires synchronously on tap. */
|
|
115
|
-
private applePayHandle;
|
|
116
|
-
private boundProductClick;
|
|
117
|
-
static styles: lit.CSSResult;
|
|
118
|
-
connectedCallback(): void;
|
|
119
|
-
disconnectedCallback(): void;
|
|
120
|
-
show(): void;
|
|
121
|
-
close(): void;
|
|
122
|
-
private fetchProduct;
|
|
123
|
-
/** Resolve the active variant from the selected option values. */
|
|
124
|
-
private selectedVariant;
|
|
125
|
-
private get unitPrice();
|
|
126
|
-
private get compareAt();
|
|
127
|
-
private get availableQuantity();
|
|
128
|
-
private stockLabel;
|
|
129
|
-
private selectOption;
|
|
130
|
-
private allImages;
|
|
131
|
-
private get activeImage();
|
|
132
|
-
/** Add the current product + selected variant + qty to the cart. Returns the variant id used. */
|
|
133
|
-
private addCurrentToCart;
|
|
134
|
-
private addToCart;
|
|
135
|
-
/**
|
|
136
|
-
* Express buy: add to cart, then open the checkout overlay with Klarna
|
|
137
|
-
* preselected. The host app handles `vio:checkout-open` (same event the cart
|
|
138
|
-
* uses) — the `paymentMethod` hint tells it to preselect Klarna so its widget
|
|
139
|
-
* loads immediately. Reuses the working Klarna Payments flow (no express SDK).
|
|
140
|
-
*/
|
|
141
|
-
private buyWithKlarna;
|
|
142
|
-
/**
|
|
143
|
-
* Express buy with Apple Pay. Runs synchronously inside the click so the
|
|
144
|
-
* Apple Pay sheet keeps the user gesture: add to cart → open checkout (sets
|
|
145
|
-
* state) → launch the sheet. On authorize, `payment-complete` drives the
|
|
146
|
-
* confirmation drawer (same path as the in-checkout Apple Pay button).
|
|
147
|
-
*/
|
|
148
|
-
private buyWithApplePay;
|
|
149
|
-
render(): lit_html.TemplateResult<1>;
|
|
150
|
-
private renderBody;
|
|
151
|
-
private renderOptionPickers;
|
|
152
|
-
/** Best-effort HTML strip for description. */
|
|
153
|
-
private stripHtml;
|
|
154
|
-
}
|
|
155
|
-
declare global {
|
|
156
|
-
interface HTMLElementTagNameMap {
|
|
157
|
-
'vio-product-detail': VioProductDetail;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
declare class VioCart extends LitElement {
|
|
162
|
-
/** Drawer visibility. Reflects to attribute for `:host([open])`. */
|
|
163
|
-
open: boolean;
|
|
164
|
-
heading: string;
|
|
165
|
-
emptyLabel: string;
|
|
166
|
-
subtotalLabel: string;
|
|
167
|
-
private carts;
|
|
168
|
-
private itemCount;
|
|
169
|
-
/** True when Apple Pay is usable (Safari + device + Stripe configured). */
|
|
170
|
-
private applePayAvailable;
|
|
171
|
-
/** Set after an Apple Pay express purchase — switches the drawer to the
|
|
172
|
-
* confirmation screen (so the rest of the cart/checkout is not shown). */
|
|
173
|
-
private confirmedOrder;
|
|
174
|
-
/** Pre-resolved Apple Pay handle; `show()` fires the sheet synchronously. */
|
|
175
|
-
private applePayHandle;
|
|
176
|
-
/** Cart total Apple Pay was last prepared for (avoids redundant prep). */
|
|
177
|
-
private preparedTotal;
|
|
178
|
-
private boundOnCartChange;
|
|
179
|
-
static styles: lit.CSSResult;
|
|
180
|
-
connectedCallback(): void;
|
|
181
|
-
disconnectedCallback(): void;
|
|
182
|
-
close(): void;
|
|
183
|
-
show(): void;
|
|
184
|
-
updated(changed: Map<string, unknown>): void;
|
|
185
|
-
/** Pre-resolve the Apple Pay sheet for the current cart total. */
|
|
186
|
-
private refreshApplePay;
|
|
187
|
-
/** Apple Pay express — pay the whole cart, then show the confirmation. */
|
|
188
|
-
private onApplePay;
|
|
189
|
-
private buildConfirmation;
|
|
190
|
-
private closeConfirmation;
|
|
191
|
-
/** Klarna express — opens the side-drawer Klarna checkout for the whole cart,
|
|
192
|
-
* skipping the address form (leveringsadresse) and method picker
|
|
193
|
-
* (betalingsmetode). The host's checkout-open handler closes this cart and
|
|
194
|
-
* opens <vio-checkout> in express mode with Klarna preselected. */
|
|
195
|
-
private onKlarnaExpress;
|
|
196
|
-
private get totalAcrossSponsors();
|
|
197
|
-
private get primaryCurrency();
|
|
198
|
-
private onIncrement;
|
|
199
|
-
private onDecrement;
|
|
200
|
-
private onRemove;
|
|
201
|
-
render(): lit_html.TemplateResult<1>;
|
|
202
|
-
private renderConfirmation;
|
|
203
|
-
}
|
|
204
|
-
declare global {
|
|
205
|
-
interface HTMLElementTagNameMap {
|
|
206
|
-
'vio-cart': VioCart;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
declare class VioCheckout extends LitElement {
|
|
211
|
-
open: boolean;
|
|
212
|
-
heading: string;
|
|
213
|
-
shippingLabel: string;
|
|
214
|
-
/** Express mode — render only the Klarna widget (no address form / method grid). */
|
|
215
|
-
express: boolean;
|
|
216
|
-
private checkoutState;
|
|
217
|
-
private items;
|
|
218
|
-
private applePayAvailable;
|
|
219
|
-
private applePayInProgress;
|
|
220
|
-
private klarnaAvailable;
|
|
221
|
-
private orderConfirmed;
|
|
222
|
-
private confirmedMethod;
|
|
223
|
-
private paymentError;
|
|
224
|
-
/** Snapshot of the placed order, for the confirmation screen. */
|
|
225
|
-
private confirmedOrder;
|
|
226
|
-
/** Active Klarna Payments widget handle + the subtotal it was mounted for. */
|
|
227
|
-
private klarnaHandle;
|
|
228
|
-
private klarnaMountedAmount;
|
|
229
|
-
private klarnaMountedShipping;
|
|
230
|
-
private klarnaMounting;
|
|
231
|
-
/** Categories offered by the active Klarna session + the selected one. */
|
|
232
|
-
private klarnaCategories;
|
|
233
|
-
private klarnaSelectedCat;
|
|
234
|
-
private klarnaAuthorizing;
|
|
235
|
-
/** Chosen shipping option id (express flow) — drives the Klarna order total. */
|
|
236
|
-
private selectedShipping;
|
|
237
|
-
private form;
|
|
238
|
-
private boundOnCheckoutChange;
|
|
239
|
-
private boundOnPaymentComplete;
|
|
240
|
-
private boundOnPaymentError;
|
|
241
|
-
static styles: lit.CSSResult;
|
|
242
|
-
connectedCallback(): void;
|
|
243
|
-
disconnectedCallback(): void;
|
|
244
|
-
updated(): void;
|
|
245
|
-
close(): void;
|
|
246
|
-
show(): void;
|
|
247
|
-
private refreshApplePay;
|
|
248
|
-
private refreshKlarna;
|
|
249
|
-
/** Mount (or re-mount on amount change) the Klarna Payments widget. */
|
|
250
|
-
private mountKlarnaIfNeeded;
|
|
251
|
-
private unmountKlarna;
|
|
252
|
-
/** Selected shipping option (express flow). */
|
|
253
|
-
private get shippingOption();
|
|
254
|
-
/** Pick a shipping option → re-mounts the Klarna widget with the new total. */
|
|
255
|
-
private onSelectShipping;
|
|
256
|
-
/** Switch the Klarna widget to a different payment_method_category. */
|
|
257
|
-
private onKlarnaCategory;
|
|
258
|
-
/** Authorize the selected Klarna method → backend creates the order. */
|
|
259
|
-
private onKlarnaAuthorize;
|
|
260
|
-
private onFieldChange;
|
|
261
|
-
private onApplePay;
|
|
262
|
-
private onPay;
|
|
263
|
-
/**
|
|
264
|
-
* Complete the order for the selected method (Vipps / Card / plain Klarna).
|
|
265
|
-
* Apple Pay and Klarna Express finish inside their own sheet/popup, so they
|
|
266
|
-
* never reach here. No real PSP is wired for Vipps/Card in this iteration —
|
|
267
|
-
* the capture happens backend-side in the full flow — so this confirms the
|
|
268
|
-
* order state-only and shows the confirmation screen.
|
|
269
|
-
*/
|
|
270
|
-
private onCompleteOrder;
|
|
271
|
-
/**
|
|
272
|
-
* Shared order confirmation — reached from both the plain "Betal" CTA
|
|
273
|
-
* (Vipps/Card/Klarna) and the Klarna Express authorize callback. Shows
|
|
274
|
-
* the confirmation screen, emits `vio:payment-success`, and clears the
|
|
275
|
-
* paid sponsor's cart so the badge + drawer reflect the purchase.
|
|
276
|
-
*/
|
|
277
|
-
private confirmOrder;
|
|
278
|
-
private methodLabel;
|
|
279
|
-
/** True for methods that complete via a separate sheet/widget, not the CTA. */
|
|
280
|
-
private isExpressMethod;
|
|
281
|
-
private orderTotal;
|
|
282
|
-
/** Shipping cost (major units) applied in express mode, else 0. */
|
|
283
|
-
private shippingMajor;
|
|
284
|
-
/** Total to charge — items + shipping (express). */
|
|
285
|
-
private payTotalLabel;
|
|
286
|
-
render(): lit_html.TemplateResult<1>;
|
|
287
|
-
private renderConfirmation;
|
|
288
|
-
/** Klarna Payments widget panel: shipping + category chips + widget + pay button. */
|
|
289
|
-
private renderKlarnaPanel;
|
|
290
|
-
/** Express layout — only the Klarna widget + a compact order summary. */
|
|
291
|
-
private renderKlarnaExpress;
|
|
292
|
-
private renderCheckoutBody;
|
|
293
|
-
}
|
|
294
|
-
declare global {
|
|
295
|
-
interface HTMLElementTagNameMap {
|
|
296
|
-
'vio-checkout': VioCheckout;
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export { VioCart as V, VioCheckout as a, VioProduct as b, VioProductCarousel as c, VioProductDetail as d };
|