@vio-live/web-sdk 0.1.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.
@@ -0,0 +1,748 @@
1
+ import { GraphQLClient } from 'graphql-request';
2
+
3
+ /**
4
+ * Vio Configuration — singleton holding apiKey, environment, base URLs,
5
+ * and optional payment-vendor publishable keys.
6
+ *
7
+ * Mirrors `VioConfiguration.shared` in the iOS SDK. Initialised once via
8
+ * `Vio.init({ apiKey, ... })`; consumed via `Configuration.get()`.
9
+ *
10
+ * Secrets (apiKey) never come from inside the SDK — the consumer reads
11
+ * them from env vars / their config and passes them to `Vio.init`.
12
+ */
13
+ type Environment = 'development' | 'testing' | 'production';
14
+ interface VioConfig {
15
+ /** Vio API key for this client app (from the Vio dashboard). */
16
+ apiKey: string;
17
+ /** Target environment. Defaults to 'development'. */
18
+ environment?: Environment;
19
+ /** Override REST API base. Defaults are env-aware. */
20
+ apiBase?: string;
21
+ /** Override GraphQL base. Defaults are env-aware. */
22
+ graphQLBase?: string;
23
+ /**
24
+ * Stripe **publishable** key (`pk_test_xxx` or `pk_live_xxx`). Used for
25
+ * Apple Pay (via Payment Request) and Card flows. Public-safe — fine
26
+ * to expose in client bundles.
27
+ */
28
+ stripePublishableKey?: string;
29
+ /**
30
+ * Klarna **Client Identifier** for Express Checkout (KEC). Public-safe.
31
+ * From Merchant Portal → Payment settings → Client Identifiers. When set,
32
+ * the checkout shows the Klarna Express button; when absent it degrades
33
+ * to the plain method selector. Must match `klarnaEnvironment`.
34
+ */
35
+ klarnaClientId?: string;
36
+ /**
37
+ * Klarna environment for the Express button. `playground` = sandbox
38
+ * (test orders, no real money), `production` = live. Defaults to
39
+ * `playground` so dev/test never hits live Klarna by accident.
40
+ */
41
+ klarnaEnvironment?: 'playground' | 'production';
42
+ }
43
+ interface ResolvedConfig {
44
+ apiKey: string;
45
+ environment: Environment;
46
+ apiBase: string;
47
+ graphQLBase: string;
48
+ stripePublishableKey?: string;
49
+ klarnaClientId?: string;
50
+ klarnaEnvironment: 'playground' | 'production';
51
+ }
52
+ declare class ConfigurationSingleton {
53
+ private resolved;
54
+ init(input: VioConfig): void;
55
+ get(): ResolvedConfig;
56
+ get isInitialized(): boolean;
57
+ /** For tests only. */
58
+ reset(): void;
59
+ }
60
+ declare const Configuration: ConfigurationSingleton;
61
+
62
+ /**
63
+ * Vio types — Product / Sponsor / Bootstrap shapes.
64
+ *
65
+ * Product types mirror the Vio Commerce GraphQL schema.
66
+ * Sponsor / Bootstrap shapes mirror the iOS SDK's bootstrap response so
67
+ * we stay aligned cross-platform.
68
+ */
69
+ type ImageSize = 'thumbnail' | 'small' | 'medium' | 'large' | 'full';
70
+ interface ProductPrice {
71
+ amount: number;
72
+ currency_code: string;
73
+ compare_at?: number | null;
74
+ amount_incl_taxes?: number | null;
75
+ compare_at_incl_taxes?: number | null;
76
+ tax_amount?: number | null;
77
+ tax_rate?: number | null;
78
+ }
79
+ interface ProductImage {
80
+ id: string;
81
+ url: string;
82
+ width?: number | null;
83
+ height?: number | null;
84
+ order?: number | null;
85
+ }
86
+ interface ProductOption {
87
+ id: number;
88
+ name: string;
89
+ order: number;
90
+ values: string[];
91
+ }
92
+ interface ProductCategory {
93
+ id: number;
94
+ name: string;
95
+ }
96
+ interface ProductVariant {
97
+ id: number;
98
+ barcode?: string | null;
99
+ quantity?: number | null;
100
+ sku?: string | null;
101
+ title?: string | null;
102
+ price: ProductPrice;
103
+ images: ProductImage[];
104
+ }
105
+ interface Product {
106
+ id: number;
107
+ brand?: string | null;
108
+ title: string;
109
+ description?: string | null;
110
+ tags?: string | null;
111
+ sku: string;
112
+ quantity?: number | null;
113
+ price: ProductPrice;
114
+ variants: ProductVariant[];
115
+ barcode?: string | null;
116
+ options: ProductOption[];
117
+ categories?: ProductCategory[] | null;
118
+ images: ProductImage[];
119
+ }
120
+ /** Per-sponsor commerce config sourced from Vio bootstrap. */
121
+ interface SponsorCommerceBlock {
122
+ apiKey: string;
123
+ channelId?: string | null;
124
+ paymentMethods?: string[];
125
+ }
126
+ interface Sponsor {
127
+ id: number;
128
+ name: string;
129
+ description?: string | null;
130
+ avatarUrl?: string | null;
131
+ logoUrl?: string | null;
132
+ primaryColor?: string | null;
133
+ secondaryColor?: string | null;
134
+ commerce: SponsorCommerceBlock;
135
+ }
136
+ /**
137
+ * Response shape of `GET /v2/mobile/config` (and likely future `/v2/web/config`).
138
+ * Matches the iOS SDK's `SdkBootstrapResponse` model.
139
+ */
140
+ interface BootstrapResponse {
141
+ campaignId?: number;
142
+ primarySponsor?: Sponsor;
143
+ secondarySponsors?: Sponsor[];
144
+ market?: {
145
+ countryCode: string;
146
+ currencyCode: string;
147
+ };
148
+ }
149
+ /**
150
+ * A placement component returned by `/v2/mobile/campaigns/:id/components`.
151
+ * Used by `<vio-product-carousel campaign-id="...">` to know which products
152
+ * to render at a given slot.
153
+ */
154
+ interface PlacementComponent {
155
+ id: number;
156
+ componentType: string;
157
+ locationId: string;
158
+ sponsorId?: number;
159
+ config: {
160
+ productIds?: number[];
161
+ [key: string]: unknown;
162
+ };
163
+ }
164
+ /** Helper: extract a useful display price from a Product. */
165
+ declare function displayPrice(product: Product): string;
166
+ /** Format a numeric amount + currency for Norwegian style: "1 299 kr". */
167
+ declare function formatPrice(amount: number, currency: string): string;
168
+ /** Helper: pick the first image URL (variant first, then product). */
169
+ declare function primaryImageUrl(product: Product): string | undefined;
170
+
171
+ /**
172
+ * Vio REST API client — talks to `api-dev.vio.live` (or override).
173
+ *
174
+ * Endpoints (mirrors the iOS SDK's surface):
175
+ * GET /v2/mobile/config bootstrap (sponsors + market)
176
+ * GET /v2/mobile/campaigns/:id/components placement components (TBD)
177
+ * POST /v2/mobile/campaigns/:id/cart-intent cross-device cart-intent (TBD)
178
+ *
179
+ * Auth: `X-API-Key: <apiKey>` header (the top-level Vio apiKey).
180
+ *
181
+ * Note: until the backend exposes a dedicated `/v2/web/*` surface we
182
+ * reuse the `/v2/mobile/*` paths — the apiKey identifies the client_app
183
+ * and the response shape is platform-agnostic enough.
184
+ */
185
+
186
+ interface VioApiOptions {
187
+ /** REST API base URL, e.g. `https://api-dev.vio.live`. */
188
+ apiBase: string;
189
+ /** Top-level Vio apiKey for this client app. */
190
+ apiKey: string;
191
+ }
192
+ declare class VioApi {
193
+ private readonly apiBase;
194
+ private readonly apiKey;
195
+ constructor(options: VioApiOptions);
196
+ /**
197
+ * Bootstrap — fetches client app config (sponsors with commerce keys,
198
+ * default market, campaign id). Called once at SDK init.
199
+ */
200
+ bootstrap(): Promise<BootstrapResponse>;
201
+ /**
202
+ * Get placement components for a campaign. Used by the carousel auto-fetch
203
+ * mode (`<vio-product-carousel campaign-id="36" location="news-favorites">`).
204
+ */
205
+ getComponents(campaignId: number | string): Promise<PlacementComponent[]>;
206
+ private get;
207
+ }
208
+ declare class VioApiError extends Error {
209
+ readonly status: number;
210
+ readonly body: string;
211
+ readonly endpoint: string;
212
+ constructor(status: number, body: string, endpoint: string);
213
+ }
214
+ declare function createVioApi(options: VioApiOptions): VioApi;
215
+
216
+ /**
217
+ * Commerce GraphQL client — talks to Vio Commerce.
218
+ *
219
+ * Mirrors the iOS SDK's `SdkClient.channel.product` surface, but uses
220
+ * `graphql-request` (lightweight) instead of Apollo. Auth header: `Authorization: <apiKey>`
221
+ * (per-sponsor commerce apiKey, NOT the top-level Vio apiKey).
222
+ *
223
+ * Usage:
224
+ * const commerce = createCommerceClient({
225
+ * endpoint: 'https://graph-ql-dev.vio.live',
226
+ * apiKey: '<sponsor-commerce-apiKey>', // sponsor's commerce apiKey
227
+ * })
228
+ * const products = await commerce.channel.product.getByIds({
229
+ * product_ids: [408895, 408896],
230
+ * currency: 'NOK',
231
+ * image_size: 'large',
232
+ * })
233
+ */
234
+
235
+ interface CommerceClientOptions {
236
+ /** Vio Commerce GraphQL endpoint, e.g. `https://graph-ql-dev.vio.live`. */
237
+ endpoint: string;
238
+ /** Per-sponsor commerce apiKey (from bootstrap.primarySponsor.commerce.apiKey). */
239
+ apiKey: string;
240
+ }
241
+ interface GetProductsByIdsOptions {
242
+ product_ids: number[];
243
+ currency?: string | null;
244
+ image_size?: ImageSize | null;
245
+ useCache?: boolean;
246
+ shipping_country_code?: string | null;
247
+ }
248
+ declare class ChannelProduct {
249
+ private readonly client;
250
+ constructor(client: GraphQLClient);
251
+ /**
252
+ * Fetch a batch of products by their numeric ids.
253
+ * Returns an empty array if no ids are provided.
254
+ */
255
+ getByIds(options: GetProductsByIdsOptions): Promise<Product[]>;
256
+ }
257
+ declare class Channel {
258
+ readonly product: ChannelProduct;
259
+ constructor(client: GraphQLClient);
260
+ }
261
+ /** CommerceClient — namespaced facade, mirrors the iOS SdkClient. */
262
+ declare class CommerceClient {
263
+ readonly channel: Channel;
264
+ /** Underlying graphql-request client (escape hatch for custom queries). */
265
+ readonly raw: GraphQLClient;
266
+ constructor(options: CommerceClientOptions);
267
+ }
268
+ declare function createCommerceClient(options: CommerceClientOptions): CommerceClient;
269
+
270
+ /**
271
+ * Cart types — multi-sponsor line items.
272
+ *
273
+ * Mirrors the iOS SDK's `SponsorCart` + `CartLineItem` structure so the
274
+ * mental model stays consistent across platforms.
275
+ */
276
+ interface CartLineItem {
277
+ /** Unique local id for this line item (used for update/remove). */
278
+ id: string;
279
+ /** Vio Commerce product id. */
280
+ productId: number;
281
+ /** Sponsor (merchant) id this line item belongs to. */
282
+ sponsorId: number;
283
+ /** Optional variant id. */
284
+ variantId?: number;
285
+ /** Display brand (e.g. "COS"). */
286
+ brand: string;
287
+ /** Display product name. */
288
+ name: string;
289
+ /** Numeric unit price (inclusive of taxes when available). */
290
+ unitPrice: number;
291
+ /** Currency code (e.g. "NOK"). */
292
+ currency: string;
293
+ /** Display image URL. */
294
+ imageUrl: string;
295
+ /** Quantity. */
296
+ quantity: number;
297
+ }
298
+ interface SponsorCartState {
299
+ sponsorId: number;
300
+ sponsorName?: string;
301
+ items: CartLineItem[];
302
+ currency: string;
303
+ }
304
+
305
+ /**
306
+ * CartManager — multi-sponsor cart state.
307
+ *
308
+ * Mirrors iOS's `CartManager` + `cartsBySponsor`. Holds local state in
309
+ * memory and persists to localStorage. Reactive: dispatches a `change`
310
+ * CustomEvent that UI components subscribe to (Web Components react via
311
+ * `requestUpdate()`).
312
+ *
313
+ * Server-side cart sync (Vio Commerce GraphQL CreateCart / AddToCart
314
+ * mutations) is deferred to checkout time via the CheckoutManager —
315
+ * this manager is purely client-side state for now.
316
+ */
317
+
318
+ interface CartChangeDetail {
319
+ cartsBySponsor: Map<number, SponsorCartState>;
320
+ itemCount: number;
321
+ }
322
+ interface AddProductOptions {
323
+ product: Product;
324
+ sponsorId: number;
325
+ sponsorName?: string;
326
+ quantity?: number;
327
+ variantId?: number;
328
+ }
329
+ /** Minimal product shape — for callers who only have e.g. mock data, not a full Product. */
330
+ interface AddManualOptions {
331
+ productId: number;
332
+ sponsorId: number;
333
+ sponsorName?: string;
334
+ brand: string;
335
+ name: string;
336
+ unitPrice: number;
337
+ currency: string;
338
+ imageUrl: string;
339
+ quantity?: number;
340
+ variantId?: number;
341
+ }
342
+ declare class CartManager extends EventTarget {
343
+ private cartsBySponsor;
344
+ constructor();
345
+ /** Add a Product DTO to a sponsor's cart. Bumps quantity if already present. */
346
+ addProduct(opts: AddProductOptions): CartLineItem;
347
+ /** Add a manually-specified line item (no Product DTO). */
348
+ addManual(opts: AddManualOptions): CartLineItem;
349
+ updateQuantity(lineItemId: string, sponsorId: number, quantity: number): void;
350
+ removeItem(lineItemId: string, sponsorId: number): void;
351
+ clearSponsorCart(sponsorId: number): void;
352
+ clearAllCarts(): void;
353
+ getAllCarts(): Map<number, SponsorCartState>;
354
+ getCart(sponsorId: number): SponsorCartState | undefined;
355
+ get itemCount(): number;
356
+ subtotalForSponsor(sponsorId: number): number;
357
+ get totalAcrossSponsors(): number;
358
+ get primaryCurrency(): string;
359
+ formatTotal(): string;
360
+ private persist;
361
+ private loadFromStorage;
362
+ private emit;
363
+ }
364
+
365
+ /**
366
+ * Apple Pay on the Web — via Stripe Payment Request API.
367
+ *
368
+ * Architecture decision (matches iOS Vio SDK pattern):
369
+ * - One Stripe **publishable key** for the Vio platform (global, set
370
+ * via `Vio.init({ stripePublishableKey })`).
371
+ * - One **Stripe Connect account id** per sponsor — sourced from
372
+ * `Vio.bootstrap()` response. Without it, the payment lands on the
373
+ * platform account instead of the merchant.
374
+ *
375
+ * Apple Pay on the Web prerequisites (Stripe-managed for us):
376
+ * - Stripe Connect account is enabled for Apple Pay
377
+ * - Domain registration for Apple Pay (Stripe handles via Dashboard)
378
+ * - Safari + macOS/iOS device with Apple Pay configured
379
+ *
380
+ * In Chrome / non-Apple browsers `canMakePayment()` returns null, so the
381
+ * UI hides the Apple Pay button automatically.
382
+ */
383
+ interface ApplePayConfig {
384
+ /** Stripe platform publishable key (pk_live_xxx or pk_test_xxx). */
385
+ publishableKey: string;
386
+ /** Sponsor's Stripe Connect account (acct_xxx). Optional but recommended. */
387
+ connectedAccount?: string;
388
+ /** Amount in the smallest unit of the currency (e.g. øre for NOK, cents for USD). */
389
+ amount: number;
390
+ /** ISO currency code, lowercased internally for Stripe. */
391
+ currency: string;
392
+ /** Two-letter country code, e.g. "NO". */
393
+ country: string;
394
+ /** Label shown in the Apple Pay sheet (merchant or order name). */
395
+ label: string;
396
+ /** Whether to ask the user for payer name. */
397
+ requestPayerName?: boolean;
398
+ /** Whether to ask the user for payer email. */
399
+ requestPayerEmail?: boolean;
400
+ /** Whether to ask for shipping address. */
401
+ requestShipping?: boolean;
402
+ /**
403
+ * Shipping options shown natively in the Apple Pay sheet. `amount` is in the
404
+ * smallest unit (øre). When set, `requestShipping` is forced on and the sheet
405
+ * total = `amount` (items) + the selected option; switching options updates
406
+ * the total live (Apple Pay native shipping).
407
+ */
408
+ shippingOptions?: Array<{
409
+ id: string;
410
+ label: string;
411
+ detail?: string;
412
+ amount: number;
413
+ }>;
414
+ }
415
+ interface ApplePayResult {
416
+ /** Stripe PaymentMethod id (pm_xxx) — pass to backend to confirm the PaymentIntent. */
417
+ paymentMethodId: string;
418
+ payerName?: string;
419
+ payerEmail?: string;
420
+ payerPhone?: string;
421
+ shippingAddress?: {
422
+ line1?: string;
423
+ line2?: string;
424
+ city?: string;
425
+ postal_code?: string;
426
+ state?: string;
427
+ country?: string;
428
+ };
429
+ }
430
+ /**
431
+ * Check whether Apple Pay is available right now (Safari + supported device
432
+ * + Stripe configured + domain registered).
433
+ *
434
+ * Returns false on any failure path — never throws.
435
+ */
436
+ declare function checkApplePayAvailability(config: ApplePayConfig): Promise<boolean>;
437
+ /**
438
+ * Show the Apple Pay sheet. Resolves with the payment method id (`pm_xxx`)
439
+ * after the user authorises, or rejects on cancel / error.
440
+ *
441
+ * The backend must then confirm a Stripe PaymentIntent with this
442
+ * payment method id (server-side step, not handled here).
443
+ */
444
+ declare function showApplePaySheet(config: ApplePayConfig): Promise<ApplePayResult>;
445
+
446
+ /** One line in the express button's purchase data. Amounts in MINOR units. */
447
+ interface KlarnaLineItem {
448
+ name: string;
449
+ quantity: number;
450
+ /** Line total (unitPrice × quantity), minor units (e.g. øre for NOK). */
451
+ totalAmount: number;
452
+ /** Per-unit price, minor units. Optional. */
453
+ unitPrice?: number;
454
+ /** Merchant SKU / product reference. Optional. */
455
+ reference?: string;
456
+ /** Absolute image URL. Optional. */
457
+ imageUrl?: string;
458
+ }
459
+ /** Payment request handed to the KEC button. Amounts in MINOR units. */
460
+ interface KlarnaPaymentRequestData {
461
+ /** ISO currency code (e.g. "NOK"). */
462
+ currency: string;
463
+ /** Order total in minor units. */
464
+ amount: number;
465
+ /** Line items — shown in the Klarna sheet. */
466
+ supplementaryPurchaseData?: {
467
+ lineItems: KlarnaLineItem[];
468
+ };
469
+ }
470
+ interface KlarnaAuthorizeResult {
471
+ /** Authorization token — backend exchanges it for an order. */
472
+ authorizationToken: string;
473
+ /** Klarna may require a finalize step (multistep flows). */
474
+ finalizeRequired?: boolean;
475
+ /** Raw payload from the SDK, for debugging / forward-compat. */
476
+ raw?: unknown;
477
+ }
478
+ interface KlarnaButtonHandle {
479
+ unmount(): void;
480
+ }
481
+
482
+ interface KlarnaPaymentsCategory {
483
+ identifier: string;
484
+ name: string;
485
+ asset_urls?: {
486
+ descriptive?: string;
487
+ standard?: string;
488
+ };
489
+ }
490
+ interface KpLoadResult {
491
+ show_form?: boolean;
492
+ error?: unknown;
493
+ }
494
+ interface KpAuthorizeResult {
495
+ approved?: boolean;
496
+ show_form?: boolean;
497
+ authorization_token?: string;
498
+ finalize_required?: boolean;
499
+ error?: unknown;
500
+ }
501
+ interface KlarnaPaymentsApi {
502
+ init(opts: {
503
+ client_token: string;
504
+ }): void;
505
+ load(opts: {
506
+ container: string | HTMLElement;
507
+ payment_method_category?: string;
508
+ }, data: Record<string, unknown>, cb?: (res: KpLoadResult) => void): void;
509
+ authorize(opts: {
510
+ payment_method_category?: string;
511
+ auto_finalize?: boolean;
512
+ }, data: Record<string, unknown>, cb?: (res: KpAuthorizeResult) => void): void;
513
+ }
514
+ interface KlarnaGlobal {
515
+ Payments: KlarnaPaymentsApi;
516
+ }
517
+ declare global {
518
+ interface Window {
519
+ Klarna?: KlarnaGlobal;
520
+ klarnaAsyncCallback?: () => void;
521
+ }
522
+ }
523
+
524
+ /**
525
+ * Checkout types — multi-sponsor compatible.
526
+ *
527
+ * Each checkout is scoped to a single sponsor (one transaction = one
528
+ * merchant, same as iOS multi-sponsor model). Multiple sponsors → multiple
529
+ * sequential checkouts.
530
+ */
531
+ type PaymentMethod = 'apple-pay' | 'klarna' | 'vipps' | 'card';
532
+ interface CheckoutAddress {
533
+ firstName: string;
534
+ lastName: string;
535
+ email: string;
536
+ address: string;
537
+ postalCode: string;
538
+ city: string;
539
+ country?: string;
540
+ }
541
+ interface CheckoutState {
542
+ /** Sponsor id whose cart is being checked out. */
543
+ sponsorId: number;
544
+ /** Remote checkout id from Vio Commerce (set after CreateCheckout). */
545
+ remoteId?: string;
546
+ /** Snapshot of the delivery address. */
547
+ address?: CheckoutAddress;
548
+ /** Selected payment method. */
549
+ paymentMethod?: PaymentMethod;
550
+ /** Subtotal at open time (numeric). */
551
+ subtotal: number;
552
+ /** Currency code. */
553
+ currency: string;
554
+ }
555
+
556
+ /**
557
+ * CheckoutManager — orchestrates the checkout flow.
558
+ *
559
+ * Stable contract: open / setAddress / selectPaymentMethod / close.
560
+ * Per-vendor payment integrations plug into the corresponding method:
561
+ * - Apple Pay → `startApplePay()` (Stripe Payment Request, this iteration)
562
+ * - Klarna / Vipps / Card → land in subsequent iterations
563
+ *
564
+ * Dispatches `change` (state changes) and `payment-select` (user picked
565
+ * a method) and `payment-complete` (vendor sheet completed successfully).
566
+ */
567
+
568
+ interface CheckoutChangeDetail {
569
+ state: CheckoutState | null;
570
+ }
571
+ interface PaymentSelectDetail {
572
+ method: PaymentMethod;
573
+ state: CheckoutState;
574
+ }
575
+ interface PaymentCompleteDetail {
576
+ method: PaymentMethod;
577
+ state: CheckoutState;
578
+ result: ApplePayResult | KlarnaAuthorizeResult | unknown;
579
+ }
580
+ /** Handle for the Klarna Payments (classic widget) flow. */
581
+ interface KlarnaPaymentsHandle {
582
+ /** Categories offered by the session (pay_now / pay_later / pay_over_time). */
583
+ categories: KlarnaPaymentsCategory[];
584
+ /** Currently selected category. */
585
+ readonly selected: string;
586
+ /** (Re)load the widget for a category. */
587
+ load(category?: string): Promise<{
588
+ showForm: boolean;
589
+ }>;
590
+ /** Authorize the selected method and (on approval) create the order. */
591
+ authorize(): Promise<void>;
592
+ /** Tear down the mounted widget. */
593
+ unmount(): void;
594
+ }
595
+ declare class CheckoutManager extends EventTarget {
596
+ private readonly cartManager;
597
+ private state;
598
+ private applePayAvailableCache;
599
+ private klarnaAvailableCache;
600
+ private klarnaOrderInFlight;
601
+ constructor(cartManager: CartManager);
602
+ open(sponsorId: number): CheckoutState;
603
+ close(): void;
604
+ setAddress(address: CheckoutAddress): void;
605
+ selectPaymentMethod(method: PaymentMethod): void;
606
+ /**
607
+ * Returns true if Apple Pay can be shown on this device + Stripe config.
608
+ * Result is memoised — call `clearApplePayCache()` if config changes.
609
+ */
610
+ isApplePayAvailable(country?: string): Promise<boolean>;
611
+ clearApplePayCache(): void;
612
+ /**
613
+ * Prepare Apple Pay for the product-page express button (no active checkout
614
+ * needed). Pre-creates the Stripe PaymentRequest + resolves canMakePayment so
615
+ * the returned `show()` can fire synchronously inside the tap (Apple blocks
616
+ * the sheet if `show()` is reached after an await). `show()` resolves the
617
+ * sheet, then dispatches `payment-complete` (→ confirmation) or
618
+ * `payment-error`. `available` is true only when Apple Pay will actually work.
619
+ */
620
+ prepareApplePayFor(amount: number, currency: string, country?: string): Promise<{
621
+ available: boolean;
622
+ show: () => Promise<void>;
623
+ }>;
624
+ /**
625
+ * Prepare an Apple Pay express charge for an arbitrary amount (e.g. the whole
626
+ * cart) with NO active checkout. Unlike `prepareApplePayFor`, the returned
627
+ * `show()` RESOLVES with the result (or `null` on cancel/failure) and does
628
+ * NOT dispatch the global `payment-complete` — so no checkout overlay appears.
629
+ * The caller (the cart drawer) renders its own confirmation. `show()` must be
630
+ * called synchronously inside the tap (Apple's user-gesture rule).
631
+ */
632
+ prepareApplePayExpress(amount: number, currency: string, country?: string): Promise<{
633
+ available: boolean;
634
+ show: () => Promise<ApplePayResult | null>;
635
+ }>;
636
+ /**
637
+ * Launches the Apple Pay sheet. Resolves with the Stripe PaymentMethod
638
+ * id once the user authorises — the backend then confirms the
639
+ * PaymentIntent with that id to actually capture the funds.
640
+ */
641
+ startApplePay(options?: {
642
+ country?: string;
643
+ label?: string;
644
+ }): Promise<ApplePayResult>;
645
+ /**
646
+ * True if the Klarna Express button can be offered (clientId configured +
647
+ * SDK loads). Memoised per active checkout. Never throws.
648
+ */
649
+ isKlarnaExpressAvailable(): Promise<boolean>;
650
+ clearKlarnaCache(): void;
651
+ /**
652
+ * Build the Klarna payment request from the active cart — amounts in the
653
+ * currency's minor unit (øre/cents), one line item per cart line.
654
+ */
655
+ buildKlarnaPaymentRequest(): KlarnaPaymentRequestData;
656
+ /**
657
+ * Mount the Klarna Express button into `container`. On a successful
658
+ * authorization, fires `payment-complete` with the authorization token —
659
+ * the host (or vio-backend) then creates the Klarna order server-side.
660
+ *
661
+ * Returns the button handle so the UI can unmount on teardown.
662
+ */
663
+ mountKlarnaExpress(container: HTMLElement): Promise<KlarnaButtonHandle>;
664
+ /**
665
+ * Klarna Payments — classic widget flow (server client_token). Creates a
666
+ * session on vio-backend, then mounts Klarna's inline widget into
667
+ * `container`. Returns a handle to switch category and to authorize → which
668
+ * on approval creates the order via the same backend /orders route as KEC.
669
+ *
670
+ * Unlike `mountKlarnaExpress`, this needs no public `klarnaClientId` and no
671
+ * origin handshake — auth is the server-side API key.
672
+ */
673
+ mountKlarnaPayments(container: HTMLElement, opts?: {
674
+ withShipping?: boolean;
675
+ shippingId?: string;
676
+ }): Promise<KlarnaPaymentsHandle>;
677
+ /** True if the Klarna Payments widget lib can load (UI gate). */
678
+ klarnaPaymentsAvailable(): Promise<boolean>;
679
+ /** Cart snapshot + chosen shipping line/amount, for express purchases. */
680
+ private buildKlarnaInstantContext;
681
+ /**
682
+ * Express instant purchase — go straight to Klarna's own modal, no checkout
683
+ * overlay. Creates a session (with shipping options), loads the widget into a
684
+ * hidden container, then authorizes (which opens Klarna's confirm modal). On
685
+ * approval creates the order → `payment-complete` (host shows confirmation);
686
+ * on failure → `payment-error`. Call `open(sponsorId)` first.
687
+ */
688
+ startKlarnaInstant(): Promise<void>;
689
+ /**
690
+ * REDIRECT path: call once on app load. If a Klarna purchase was launched
691
+ * (pending context persisted) and we're back with a token — from the URL or
692
+ * the SDK's resumed `complete` event — finish creating the order + confirm.
693
+ */
694
+ resumeKlarnaReturn(): Promise<void>;
695
+ /** Snapshot of the active cart for redirect recovery (minor units). */
696
+ private buildKlarnaPendingContext;
697
+ /**
698
+ * POST the token + order lines to vio-backend (it holds the secret API key
699
+ * and creates the real Klarna order). On success → `payment-complete`; on
700
+ * failure → `payment-error`. Idempotent: clears the pending key so the
701
+ * popup and redirect paths can't double-fire.
702
+ */
703
+ private completeKlarnaOrder;
704
+ get currentState(): CheckoutState | null;
705
+ get items(): CartLineItem[];
706
+ /**
707
+ * Resolve the Stripe Connect account for the active sponsor — for now
708
+ * pulled from bootstrap cache if present. Returns undefined if not set
709
+ * (Stripe will route to the platform account in that case).
710
+ */
711
+ private findStripeConnectAccount;
712
+ private emit;
713
+ }
714
+
715
+ declare class VioFacade {
716
+ private apiInstance;
717
+ private commerceClients;
718
+ private bootstrapPromise;
719
+ private cachedBootstrap;
720
+ private cartManager;
721
+ private checkoutManager;
722
+ init(config: VioConfig): void;
723
+ get isInitialized(): boolean;
724
+ get config(): ResolvedConfig;
725
+ /** Multi-sponsor cart manager. Reactive — listen via addEventListener('change', ...). */
726
+ get cart(): CartManager;
727
+ /** Checkout flow manager. Subscribes to cart state via the CartManager. */
728
+ get checkout(): CheckoutManager;
729
+ /** Lazy VioApi for REST endpoints on `api-dev.vio.live`. */
730
+ get api(): VioApi;
731
+ /**
732
+ * Bootstrap — fetches client config and caches it. Dedupes in-flight
733
+ * concurrent requests.
734
+ */
735
+ bootstrap(): Promise<BootstrapResponse>;
736
+ get bootstrapCache(): BootstrapResponse | null;
737
+ /**
738
+ * Get a CommerceClient scoped to a specific sponsor (via bootstrap).
739
+ * Throws if bootstrap hasn't been called or the sponsor is unknown.
740
+ */
741
+ commerceFor(sponsorId: number): CommerceClient;
742
+ /** Get a CommerceClient using an explicit commerce apiKey (skip bootstrap). */
743
+ commerceWithKey(commerceApiKey: string): CommerceClient;
744
+ private findSponsor;
745
+ }
746
+ declare const Vio: VioFacade;
747
+
748
+ export { type AddManualOptions, type AddProductOptions, type ApplePayConfig, type ApplePayResult, type BootstrapResponse, type CartChangeDetail, type CartLineItem, CartManager, type CheckoutAddress, type CheckoutChangeDetail, CheckoutManager, type CheckoutState, CommerceClient, Configuration, type Environment, type ImageSize, type PaymentCompleteDetail, type PaymentMethod, type PaymentSelectDetail, type PlacementComponent, type Product, type ProductCategory, type ProductImage, type ProductOption, type ProductPrice, type ProductVariant, type ResolvedConfig, type Sponsor, type SponsorCartState, type SponsorCommerceBlock, Vio, VioApi, VioApiError, type VioConfig, checkApplePayAvailability, createCommerceClient, createVioApi, displayPrice, formatPrice, primaryImageUrl, showApplePaySheet };