@vio-live/web-sdk 0.11.1 → 0.21.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.
@@ -150,14 +150,60 @@ interface Sponsor {
150
150
  secondaryColor?: string | null;
151
151
  commerce: SponsorCommerceBlock;
152
152
  }
153
+ /**
154
+ * `campaign` of `GET /v2/mobile/config`: the head of the surface's default
155
+ * campaign (the one `primarySponsor` / `secondarySponsors` belong to).
156
+ */
157
+ interface BootstrapCampaign {
158
+ id: number;
159
+ name: string;
160
+ logo?: string | null;
161
+ isActive?: boolean;
162
+ isPaused?: boolean;
163
+ startDate?: string | null;
164
+ endDate?: string | null;
165
+ }
166
+ /** Campaign status as the backend computes it (`[startsAt, endsAt)`). */
167
+ type BootstrapCampaignStatus = 'scheduled' | 'active' | 'paused' | 'ended';
168
+ /** A slot assignment of a campaign on this surface (`campaigns[].slots[]`). */
169
+ interface BootstrapSlot {
170
+ name: string;
171
+ platform?: string | null;
172
+ startDate?: string | null;
173
+ endDate?: string | null;
174
+ }
175
+ /**
176
+ * One entry of `campaigns[]`: every active campaign of the surface, with its
177
+ * own sponsors — a sponsor may live only in a non-default campaign.
178
+ */
179
+ interface BootstrapCampaignEntry extends BootstrapCampaign {
180
+ isDefault?: boolean;
181
+ status?: BootstrapCampaignStatus;
182
+ primarySponsor?: Sponsor | null;
183
+ secondarySponsors?: Sponsor[];
184
+ slots?: BootstrapSlot[];
185
+ }
153
186
  /**
154
187
  * Response shape of `GET /v2/mobile/config` (and likely future `/v2/web/config`).
155
188
  * Matches the iOS SDK's `SdkBootstrapResponse` model.
189
+ *
190
+ * `campaign` + `primarySponsor` + `secondarySponsors` describe the surface's
191
+ * default campaign; `campaigns[]` lists every active one. There is no
192
+ * top-level `campaignId` — the id lives in `campaign.id`.
156
193
  */
157
194
  interface BootstrapResponse {
158
- campaignId?: number;
195
+ endpoints?: {
196
+ webSocketBase?: string;
197
+ commerceGraphQL?: string;
198
+ };
199
+ campaign?: BootstrapCampaign;
159
200
  primarySponsor?: Sponsor;
160
201
  secondarySponsors?: Sponsor[];
202
+ features?: {
203
+ shoppable?: boolean;
204
+ lineup?: boolean;
205
+ };
206
+ campaigns?: BootstrapCampaignEntry[];
161
207
  market?: {
162
208
  countryCode: string;
163
209
  currencyCode: string;
@@ -196,7 +242,7 @@ declare function formatPrice(amount: number, currency?: string): string;
196
242
  declare function primaryImageUrl(product: Product): string | undefined;
197
243
 
198
244
  /**
199
- * Vio REST API client — talks to `api-dev.vio.live` (or override).
245
+ * Vio REST API client — talks to `api-staging.vio.live` (or override).
200
246
  *
201
247
  * Endpoints (mirrors the iOS SDK's surface):
202
248
  * GET /v2/mobile/config bootstrap (sponsors + market)
@@ -211,7 +257,7 @@ declare function primaryImageUrl(product: Product): string | undefined;
211
257
  */
212
258
 
213
259
  interface VioApiOptions {
214
- /** REST API base URL, e.g. `https://api-dev.vio.live`. */
260
+ /** REST API base URL, e.g. `https://api-staging.vio.live`. */
215
261
  apiBase: string;
216
262
  /** Top-level Vio apiKey for this client app. */
217
263
  apiKey: string;
@@ -280,6 +326,16 @@ declare class ChannelProduct {
280
326
  * Returns an empty array if no ids are provided.
281
327
  */
282
328
  getByIds(options: GetProductsByIdsOptions): Promise<Product[]>;
329
+ /**
330
+ * The seller's Company name for one product, or null (none set, or an API
331
+ * that does not have the field yet). Never throws.
332
+ *
333
+ * Never from the cache, on purpose: graphql caches product answers by
334
+ * path whatever fields the query asked, so this narrow query, written to
335
+ * the cache, would hand the next full product query a product with no
336
+ * price and no images. `useCache: false` neither reads nor writes it.
337
+ */
338
+ getSellerCompany(productId: number): Promise<string | null>;
283
339
  }
284
340
  declare class Channel {
285
341
  readonly product: ChannelProduct;
@@ -470,6 +526,176 @@ declare class CartManager extends EventTarget {
470
526
  private emit;
471
527
  }
472
528
 
529
+ /**
530
+ * Vipps MobilePay Payment Adapter — GraphQL Integration & Types.
531
+ *
532
+ * Vipps payment integration uses 2 GraphQL operations:
533
+ *
534
+ * 1. `CreatePaymentVipps` mutation:
535
+ * Initiates a Vipps payment session for a checkout and returns `payment_url`.
536
+ *
537
+ * 2. `GetVippsStatus` query:
538
+ * Queries Vipps payment state directly for a checkout (`state`).
539
+ */
540
+
541
+ /**
542
+ * GraphQL mutation to create a Vipps payment session.
543
+ */
544
+ declare const CREATE_PAYMENT_VIPPS_MUTATION = "\nmutation CreatePaymentVipps($checkoutId: String!, $email: String, $returnUrl: String!, $express: Boolean) {\n Payment {\n CreatePaymentVipps(checkout_id: $checkoutId, email: $email, return_url: $returnUrl, express: $express) {\n payment_url\n reference\n express\n reason\n }\n }\n}\n";
545
+ /**
546
+ * GraphQL query to fetch current Vipps payment status.
547
+ */
548
+ declare const GET_VIPPS_STATUS_QUERY = "\nquery GetVippsStatus($checkoutId: String!) {\n Payment {\n GetVippsStatus(checkout_id: $checkoutId) {\n state\n duplicate_of\n }\n }\n}\n";
549
+ interface CreatePaymentVippsVariables extends Record<string, unknown> {
550
+ checkoutId: string;
551
+ /** Optional since Express: Vipps hands the email back with the payment. */
552
+ email?: string;
553
+ returnUrl: string;
554
+ /**
555
+ * `true` asks for Express — address and delivery chosen inside the Vipps
556
+ * app. When the cart cannot have it, no payment is created and the answer
557
+ * says `express: false` with the reason; the caller then opens the
558
+ * ordinary checkout.
559
+ */
560
+ express?: boolean;
561
+ }
562
+ interface CreatePaymentVippsResponse {
563
+ /** Absent when Express was asked for and refused. */
564
+ payment_url?: string;
565
+ /** The reference the seller reads in its Vipps portal. */
566
+ reference?: string;
567
+ express?: boolean;
568
+ reason?: string;
569
+ }
570
+ interface GetVippsStatusVariables extends Record<string, unknown> {
571
+ checkoutId: string;
572
+ }
573
+ interface VippsStatusResult {
574
+ state: string;
575
+ /** Set when this checkout was closed as a duplicate: the checkout that paid the cart. */
576
+ duplicate_of?: string | null;
577
+ }
578
+ type VippsPaymentState = 'CREATED' | 'INITIATED' | 'AUTHORIZED' | 'TERMINATED' | 'EXPIRED' | string;
579
+ /**
580
+ * Executes the `CreatePaymentVipps` GraphQL mutation.
581
+ */
582
+ declare function createPaymentVipps(variables: CreatePaymentVippsVariables | Record<string, unknown>, options?: CartQueryOptions): Promise<CreatePaymentVippsResponse | null>;
583
+ /**
584
+ * Executes the `GetVippsStatus` GraphQL query.
585
+ */
586
+ declare function getVippsStatus(variables: GetVippsStatusVariables | Record<string, unknown>, options?: CartQueryOptions): Promise<VippsStatusResult | null>;
587
+
588
+ declare const CREATE_CART_MUTATION = "\nmutation CreateCart($customerSessionId: String!, $currency: String!, $shippingCountry: String) {\n Cart {\n CreateCart(customer_session_id: $customerSessionId, currency: $currency, shipping_country: $shippingCountry) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
589
+ declare const ADD_ITEM_MUTATION = "\nmutation AddItem($cartId: String!, $lineItems: [LineItemInput!]!) {\n Cart {\n AddItem(cart_id: $cartId, line_items: $lineItems) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
590
+ declare const DELETE_ITEM_MUTATION = "\nmutation DeleteItem($cartId: String!, $cartItemId: String!) {\n Cart {\n DeleteItem(cart_id: $cartId, cart_item_id: $cartItemId) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
591
+ declare const UPDATE_ITEM_MUTATION = "\nmutation UpdateItem($cartId: String!, $cartItemId: String!, $shippingId: String, $qty: Int) {\n Cart {\n UpdateItem(cart_id: $cartId, cart_item_id: $cartItemId, shipping_id: $shippingId, qty: $qty) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
592
+ declare const GET_CART_QUERY = "\nquery GetCart($cartId: String!) {\n Cart {\n GetCart(cart_id: $cartId) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
593
+ declare const GET_LINE_ITEMS_BY_SUPPLIER_QUERY = "\nquery GetLineItemsBySupplier($cartId: String!) {\n Cart {\n GetLineItemsBySupplier(cart_id: $cartId) {\n supplier {\n id\n name\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n }\n }\n}\n";
594
+ declare const UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION = "\nmutation UpdateShippingsBySupplier($cartId: String!, $data: [DataUpdateShippingsBySupplier!]!) {\n Cart {\n UpdateShippingsBySupplier(cart_id: $cartId, data: $data) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
595
+ declare const CREATE_CHECKOUT_MUTATION = "\nmutation CreateCheckout($cartId: String!) {\n Checkout {\n CreateCheckout(cart_id: $cartId) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
596
+ declare const UPDATE_CHECKOUT_MUTATION = "\nmutation UpdateCheckout($checkoutId: String!, $status: String, $successUrl: String, $email: String, $cancelUrl: String, $paymentMethod: String, $shippingAddress: AddressArgs, $billingAddress: AddressArgs, $buyerAcceptsPurchaseConditions: Boolean, $buyerAcceptsTermsConditions: Boolean) {\n Checkout {\n UpdateCheckout(checkout_id: $checkoutId, status: $status, success_url: $successUrl, email: $email, cancel_url: $cancelUrl, payment_method: $paymentMethod, shipping_address: $shippingAddress, billing_address: $billingAddress, buyer_accepts_purchase_conditions: $buyerAcceptsPurchaseConditions, buyer_accepts_terms_conditions: $buyerAcceptsTermsConditions) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
597
+ declare const GET_CHECKOUT_QUERY = "\nquery GetCheckout($checkoutId: String!) {\n Checkout {\n GetCheckout(checkout_id: $checkoutId) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n duplicate_of\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
598
+ declare const GET_AVAILABLE_PAYMENT_METHODS_QUERY = "\nquery Config {\n Payment {\n GetAvailablePaymentMethods {\n config {\n name\n type\n value\n }\n name\n }\n }\n}\n";
599
+ /** Transport options for a cart/checkout GraphQL call. */
600
+ interface CartQueryOptions {
601
+ endpoint?: string;
602
+ apiKey?: string;
603
+ /** Sponsor commerce key — goes in the Authorization header. */
604
+ commerceKey?: string;
605
+ /** True when the commerce key came from a resolved sponsor (bootstrap).
606
+ * False = we fell back to the host apiKey — writes like CreateCart should
607
+ * NOT proceed with the wrong key (the cart would be orphaned). */
608
+ sponsorResolved?: boolean;
609
+ }
610
+ /**
611
+ * Resolve endpoint + keys for cart GraphQL calls. Awaits Vio.bootstrap() once
612
+ * if it hasn't run yet (the sponsor commerce keys come from bootstrap), then
613
+ * uses the sponsor's commerce apiKey (via the Vio facade on globalThis,
614
+ * avoiding an import cycle); falls back to the host apiKey.
615
+ */
616
+ declare function getCartGraphQLOptions(sponsorId?: number): Promise<CartQueryOptions>;
617
+ /** Stable per-browser customer session id (backend CreateCart requires one). */
618
+ declare function getCustomerSessionId(): string;
619
+ interface GraphQLEnvelope {
620
+ data?: Record<string, Record<string, unknown>>;
621
+ errors?: Array<{
622
+ message?: string;
623
+ }>;
624
+ }
625
+ /** Execute a GraphQL query/mutation against the configured commerce endpoint.
626
+ * Callers that skip `getCartGraphQLOptions()` (or pass a bare sponsorId) get
627
+ * it resolved here instead of silently sending an unauthenticated request. */
628
+ declare function executeCartGraphQL(query: string, variables: Record<string, unknown>, options?: CartQueryOptions | number | undefined): Promise<GraphQLEnvelope>;
629
+ declare function createCart(customerSessionId: string, currency: string, shippingCountry?: string | null, options?: CartQueryOptions): Promise<any>;
630
+ declare function addItem(cartId: string, lineItems: unknown[], options?: CartQueryOptions): Promise<any>;
631
+ declare function deleteItem(cartId: string, cartItemId: string, options?: CartQueryOptions): Promise<any>;
632
+ declare function updateItem(cartId: string, cartItemId: string, shippingId?: string | null, qty?: number | null, options?: CartQueryOptions): Promise<any>;
633
+ declare function getCart(cartId: string, options?: CartQueryOptions): Promise<any>;
634
+ declare function getLineItemsBySupplier(cartId: string, options?: CartQueryOptions): Promise<any>;
635
+ declare function updateShippingsBySupplier(cartId: string, data: unknown[], options?: CartQueryOptions): Promise<any>;
636
+ declare function createCheckout(cartId: string, options?: CartQueryOptions): Promise<any>;
637
+ declare function updateCheckout(variables: Record<string, unknown>, options?: CartQueryOptions): Promise<any>;
638
+ declare function getCheckout(checkoutId: string, options?: CartQueryOptions): Promise<any>;
639
+ declare function getAvailablePaymentMethods(options?: CartQueryOptions): Promise<any>;
640
+ declare const CREATE_PAYMENT_STRIPE_MUTATION = "\nmutation CreatePaymentStripe($checkoutId: String!, $successUrl: String!, $paymentMethod: String!, $email: String!) {\n Payment {\n CreatePaymentStripe(checkout_id: $checkoutId, success_url: $successUrl, payment_method: $paymentMethod, email: $email) {\n order_id\n checkout_url\n }\n }\n}\n";
641
+ declare function createPaymentStripe(variables: Record<string, unknown>, options?: CartQueryOptions): Promise<any>;
642
+
643
+ /**
644
+ * Stripe on our own page — the Payment Element, no redirect.
645
+ *
646
+ * The older web flow minted a Stripe Payment Link and sent the shopper to a
647
+ * page hosted by Stripe. This one keeps them here (Angelo, 2026-09-24):
648
+ *
649
+ * 1. Vio Commerce creates a PaymentIntent for the checkout
650
+ * (`Payment { CreatePaymentIntentStripe }`) and answers with its client
651
+ * secret AND the publishable key of the account that minted it — the
652
+ * seller's when they brought both keys, ours otherwise. The two are
653
+ * halves of one account: the browser confirms with the key what the
654
+ * server minted with the secret one.
655
+ * 2. Stripe's Payment Element is mounted in a LIGHT-DOM container, the way
656
+ * the other embedded widgets are. Card fields are Stripe's own iframes,
657
+ * so card data never touches this SDK or our servers.
658
+ * 3. `confirm()` pays. A 3-D Secure challenge opens in Stripe's own modal
659
+ * over the page: `redirect: 'if_required'` keeps the shopper here for
660
+ * cards, and still redirects for a method that has no other way.
661
+ * 4. The Commerce order is NOT born here. Stripe's `payment_intent.succeeded`
662
+ * webhook creates it, verified server-side; the checkout is polled for
663
+ * its status afterwards, exactly as the redirect return does.
664
+ */
665
+
666
+ /** What the backend hands over to pay a checkout on our page. */
667
+ interface StripeIntent {
668
+ /** `pi_..._secret_...`: what the browser confirms. */
669
+ client_secret: string;
670
+ /** The key of the SAME account that minted the secret. */
671
+ publishable_key: string;
672
+ customer?: string;
673
+ /**
674
+ * Stripe Connect (ADR-0022): the seller's connected account, where the
675
+ * intent lives. The browser must name it or Stripe answers "no such
676
+ * payment_intent". Absent for every seller not on Connect.
677
+ */
678
+ stripe_account?: string;
679
+ }
680
+ /** What `confirm()` answers. The browser's word is never the order. */
681
+ type StripeConfirmOutcome = {
682
+ status: 'succeeded';
683
+ paymentIntentId?: string;
684
+ }
685
+ /** Authorised but not settled yet, or Stripe redirected and will return. */
686
+ | {
687
+ status: 'pending';
688
+ paymentIntentId?: string;
689
+ } | {
690
+ status: 'failed';
691
+ message?: string;
692
+ code?: string;
693
+ };
694
+ interface StripeElementHandle {
695
+ confirm(): Promise<StripeConfirmOutcome>;
696
+ unmount(): void;
697
+ }
698
+
473
699
  /**
474
700
  * Apple Pay on the Web — via Stripe Payment Request API.
475
701
  *
@@ -640,105 +866,6 @@ declare global {
640
866
  }
641
867
  }
642
868
 
643
- /**
644
- * Vipps MobilePay Payment Adapter — GraphQL Integration & Types.
645
- *
646
- * Vipps payment integration uses 2 GraphQL operations:
647
- *
648
- * 1. `CreatePaymentVipps` mutation:
649
- * Initiates a Vipps payment session for a checkout and returns `payment_url`.
650
- *
651
- * 2. `GetVippsStatus` query:
652
- * Queries Vipps payment state directly for a checkout (`state`).
653
- */
654
-
655
- /**
656
- * GraphQL mutation to create a Vipps payment session.
657
- */
658
- declare const CREATE_PAYMENT_VIPPS_MUTATION = "\nmutation CreatePaymentVipps($checkoutId: String!, $email: String!, $returnUrl: String!) {\n Payment {\n CreatePaymentVipps(checkout_id: $checkoutId, email: $email, return_url: $returnUrl) {\n payment_url\n }\n }\n}\n";
659
- /**
660
- * GraphQL query to fetch current Vipps payment status.
661
- */
662
- declare const GET_VIPPS_STATUS_QUERY = "\nquery GetVippsStatus($checkoutId: String!) {\n Payment {\n GetVippsStatus(checkout_id: $checkoutId) {\n state\n }\n }\n}\n";
663
- interface CreatePaymentVippsVariables extends Record<string, unknown> {
664
- checkoutId: string;
665
- email: string;
666
- returnUrl: string;
667
- }
668
- interface CreatePaymentVippsResponse {
669
- payment_url: string;
670
- }
671
- interface GetVippsStatusVariables extends Record<string, unknown> {
672
- checkoutId: string;
673
- }
674
- interface VippsStatusResult {
675
- state: string;
676
- }
677
- type VippsPaymentState = 'CREATED' | 'INITIATED' | 'AUTHORIZED' | 'TERMINATED' | 'EXPIRED' | string;
678
- /**
679
- * Executes the `CreatePaymentVipps` GraphQL mutation.
680
- */
681
- declare function createPaymentVipps(variables: CreatePaymentVippsVariables | Record<string, unknown>, options?: CartQueryOptions): Promise<CreatePaymentVippsResponse | null>;
682
- /**
683
- * Executes the `GetVippsStatus` GraphQL query.
684
- */
685
- declare function getVippsStatus(variables: GetVippsStatusVariables | Record<string, unknown>, options?: CartQueryOptions): Promise<VippsStatusResult | null>;
686
-
687
- declare const CREATE_CART_MUTATION = "\nmutation CreateCart($customerSessionId: String!, $currency: String!, $shippingCountry: String) {\n Cart {\n CreateCart(customer_session_id: $customerSessionId, currency: $currency, shipping_country: $shippingCountry) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
688
- declare const ADD_ITEM_MUTATION = "\nmutation AddItem($cartId: String!, $lineItems: [LineItemInput!]!) {\n Cart {\n AddItem(cart_id: $cartId, line_items: $lineItems) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
689
- declare const DELETE_ITEM_MUTATION = "\nmutation DeleteItem($cartId: String!, $cartItemId: String!) {\n Cart {\n DeleteItem(cart_id: $cartId, cart_item_id: $cartItemId) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
690
- declare const UPDATE_ITEM_MUTATION = "\nmutation UpdateItem($cartId: String!, $cartItemId: String!, $shippingId: String, $qty: Int) {\n Cart {\n UpdateItem(cart_id: $cartId, cart_item_id: $cartItemId, shipping_id: $shippingId, qty: $qty) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
691
- declare const GET_CART_QUERY = "\nquery GetCart($cartId: String!) {\n Cart {\n GetCart(cart_id: $cartId) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
692
- declare const GET_LINE_ITEMS_BY_SUPPLIER_QUERY = "\nquery GetLineItemsBySupplier($cartId: String!) {\n Cart {\n GetLineItemsBySupplier(cart_id: $cartId) {\n supplier {\n id\n name\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n }\n }\n}\n";
693
- declare const UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION = "\nmutation UpdateShippingsBySupplier($cartId: String!, $data: [DataUpdateShippingsBySupplier!]!) {\n Cart {\n UpdateShippingsBySupplier(cart_id: $cartId, data: $data) {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n }\n}\n";
694
- declare const CREATE_CHECKOUT_MUTATION = "\nmutation CreateCheckout($cartId: String!) {\n Checkout {\n CreateCheckout(cart_id: $cartId) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
695
- declare const UPDATE_CHECKOUT_MUTATION = "\nmutation UpdateCheckout($checkoutId: String!, $status: String, $successUrl: String, $email: String, $cancelUrl: String, $paymentMethod: String, $shippingAddress: AddressArgs, $billingAddress: AddressArgs, $buyerAcceptsPurchaseConditions: Boolean, $buyerAcceptsTermsConditions: Boolean) {\n Checkout {\n UpdateCheckout(checkout_id: $checkoutId, status: $status, success_url: $successUrl, email: $email, cancel_url: $cancelUrl, payment_method: $paymentMethod, shipping_address: $shippingAddress, billing_address: $billingAddress, buyer_accepts_purchase_conditions: $buyerAcceptsPurchaseConditions, buyer_accepts_terms_conditions: $buyerAcceptsTermsConditions) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
696
- declare const GET_CHECKOUT_QUERY = "\nquery GetCheckout($checkoutId: String!) {\n Checkout {\n GetCheckout(checkout_id: $checkoutId) {\n buyer_accepts_purchase_conditions\n buyer_accepts_terms_conditions\n created_at\n updated_at\n id\n deleted_at\n success_url\n cancel_url\n payment_method\n email\n status\n checkout_url\n origin_payment_id\n billing_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n shipping_address {\n id\n first_name\n last_name\n phone_code\n phone\n company\n address1\n address2\n city\n province\n province_code\n country\n country_code\n zip\n }\n available_payment_methods {\n name\n }\n discount_code\n cart {\n cart_id\n customer_session_id\n shipping_country\n line_items {\n id\n supplier\n image {\n id\n url\n width\n height\n }\n sku\n barcode\n brand\n product_id\n title\n variant_id\n variant_title\n variant {\n option\n value\n }\n quantity\n price {\n amount\n currency_code\n discount\n compare_at\n compare_at_incl_taxes\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n shipping {\n id\n name\n description\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n available_shippings {\n id\n name\n description\n country_code\n price {\n amount\n currency_code\n amount_incl_taxes\n tax_amount\n tax_rate\n }\n }\n }\n subtotal\n shipping\n currency\n available_shipping_countries\n }\n totals {\n currency_code\n subtotal\n shipping\n total\n taxes\n tax_rate\n discounts\n }\n }\n }\n}\n";
697
- declare const GET_AVAILABLE_PAYMENT_METHODS_QUERY = "\nquery Config {\n Payment {\n GetAvailablePaymentMethods {\n config {\n name\n type\n value\n }\n name\n }\n }\n}\n";
698
- /** Transport options for a cart/checkout GraphQL call. */
699
- interface CartQueryOptions {
700
- endpoint?: string;
701
- apiKey?: string;
702
- /** Sponsor commerce key — goes in the Authorization header. */
703
- commerceKey?: string;
704
- /** True when the commerce key came from a resolved sponsor (bootstrap).
705
- * False = we fell back to the host apiKey — writes like CreateCart should
706
- * NOT proceed with the wrong key (the cart would be orphaned). */
707
- sponsorResolved?: boolean;
708
- }
709
- /**
710
- * Resolve endpoint + keys for cart GraphQL calls. Awaits Vio.bootstrap() once
711
- * if it hasn't run yet (the sponsor commerce keys come from bootstrap), then
712
- * uses the sponsor's commerce apiKey (via the Vio facade on globalThis,
713
- * avoiding an import cycle); falls back to the host apiKey.
714
- */
715
- declare function getCartGraphQLOptions(sponsorId?: number): Promise<CartQueryOptions>;
716
- /** Stable per-browser customer session id (backend CreateCart requires one). */
717
- declare function getCustomerSessionId(): string;
718
- interface GraphQLEnvelope {
719
- data?: Record<string, Record<string, unknown>>;
720
- errors?: Array<{
721
- message?: string;
722
- }>;
723
- }
724
- /** Execute a GraphQL query/mutation against the configured commerce endpoint.
725
- * Callers that skip `getCartGraphQLOptions()` (or pass a bare sponsorId) get
726
- * it resolved here instead of silently sending an unauthenticated request. */
727
- declare function executeCartGraphQL(query: string, variables: Record<string, unknown>, options?: CartQueryOptions | number | undefined): Promise<GraphQLEnvelope>;
728
- declare function createCart(customerSessionId: string, currency: string, shippingCountry?: string | null, options?: CartQueryOptions): Promise<any>;
729
- declare function addItem(cartId: string, lineItems: unknown[], options?: CartQueryOptions): Promise<any>;
730
- declare function deleteItem(cartId: string, cartItemId: string, options?: CartQueryOptions): Promise<any>;
731
- declare function updateItem(cartId: string, cartItemId: string, shippingId?: string | null, qty?: number | null, options?: CartQueryOptions): Promise<any>;
732
- declare function getCart(cartId: string, options?: CartQueryOptions): Promise<any>;
733
- declare function getLineItemsBySupplier(cartId: string, options?: CartQueryOptions): Promise<any>;
734
- declare function updateShippingsBySupplier(cartId: string, data: unknown[], options?: CartQueryOptions): Promise<any>;
735
- declare function createCheckout(cartId: string, options?: CartQueryOptions): Promise<any>;
736
- declare function updateCheckout(variables: Record<string, unknown>, options?: CartQueryOptions): Promise<any>;
737
- declare function getCheckout(checkoutId: string, options?: CartQueryOptions): Promise<any>;
738
- declare function getAvailablePaymentMethods(options?: CartQueryOptions): Promise<any>;
739
- declare const CREATE_PAYMENT_STRIPE_MUTATION = "\nmutation CreatePaymentStripe($checkoutId: String!, $successUrl: String!, $paymentMethod: String!, $email: String!) {\n Payment {\n CreatePaymentStripe(checkout_id: $checkoutId, success_url: $successUrl, payment_method: $paymentMethod, email: $email) {\n order_id\n checkout_url\n }\n }\n}\n";
740
- declare function createPaymentStripe(variables: Record<string, unknown>, options?: CartQueryOptions): Promise<any>;
741
-
742
869
  /**
743
870
  * Kustom (former Klarna Checkout) — embedded KCO v3 checkout.
744
871
  *
@@ -747,26 +874,64 @@ declare function createPaymentStripe(variables: Record<string, unknown>, options
747
874
  *
748
875
  * 1. Vio Commerce creates the order (`Payment { CreatePaymentKustom }`,
749
876
  * authed with the sponsor's commerce API key; the seller's own
750
- * kco_*_api_* key lives server-side, per seller, never here).
751
- * 2. The response's `html_snippet` is injected into a container — it
752
- * renders Kustom's iframe, which collects address, shipping AND payment
753
- * by itself (the widget does everything; no Vio address form).
754
- * 3. On completion Kustom redirects to the confirmation URL
755
- * (`?order_id=…&payment_processor=KUSTOM`), where the SDK re-reads the
756
- * order (`Payment { GetKustomOrder }`) and renders its confirmation
757
- * snippet — KCO's own receipt.
877
+ * kco_*_api_* key lives server-side, per seller, never here). One order
878
+ * per checkout: asking again while it is open UPDATES it.
879
+ * 2. The response's `html_snippet` is injected into a LIGHT-DOM container
880
+ * — it renders Kustom's iframe, which collects address, shipping AND
881
+ * payment by itself (the widget does everything; no Vio address form).
882
+ * 3. While it is open, the widget talks through `window._klarnaCheckout`:
883
+ * we suspend it around a cart change (`Payment { SyncPaymentKustom }`),
884
+ * and listen to its totals so our summary never disagrees with it.
885
+ * 4. On completion Kustom redirects to the confirmation URL
886
+ * (`?order_id=…&payment_processor=KUSTOM&checkout_id=…`), where the SDK
887
+ * re-reads the order (`Payment { GetKustomOrder }`) — the backend
888
+ * completes it right there — and renders Kustom's own receipt.
758
889
  *
759
- * The Commerce order itself is created server-side by Kustom's push webhook
760
- * (shopcart /checkout/payment/kustom/ok) — the browser never confirms money.
890
+ * The Commerce order is created server-side, from what Kustom says it
891
+ * charged (Order Management), whether the shopper comes back or not (the
892
+ * push) — the browser never confirms money.
761
893
  */
762
894
 
763
- /** KCO order fields the SDK consumes (the full order is much larger). */
895
+ /** A Kustom order as shopcart normalizes it (never Kustom's raw order). */
764
896
  interface KustomOrder {
765
897
  order_id: string;
898
+ /** `checkout_incomplete` | `checkout_complete`, lower-cased by the backend. */
766
899
  status: string;
767
900
  html_snippet: string;
768
901
  purchase_country?: string;
769
902
  purchase_currency?: string;
903
+ checkout_id?: string;
904
+ environment?: string;
905
+ /** Goods + the shipping shown or charged, decimal. */
906
+ total_price?: number;
907
+ shipping_name?: string;
908
+ shipping_price?: number;
909
+ /** Whether the Vio Commerce order exists (after completion). */
910
+ order_created?: boolean;
911
+ /** Kustom's short shopper-facing reference (after completion). */
912
+ reference?: string;
913
+ }
914
+ interface KustomShippingChange {
915
+ id?: string;
916
+ name?: string;
917
+ description?: string;
918
+ /** Minor units, as the widget reports them. */
919
+ price?: number;
920
+ tax_amount?: number;
921
+ tax_rate?: number;
922
+ }
923
+ interface KustomListenerHandlers {
924
+ /** The iframe rendered. */
925
+ onLoad?: (data: any) => void;
926
+ /** The order total the widget shows, in MINOR units. */
927
+ onOrderTotalChange?: (orderTotalMinor: number) => void;
928
+ /** The shopper picked a rate inside the widget. */
929
+ onShippingOptionChange?: (option: KustomShippingChange) => void;
930
+ /** The shopper could not pay (declined credit…): show another way. */
931
+ onCannotComplete?: () => void;
932
+ onNetworkError?: () => void;
933
+ /** The shopper is about to leave for the confirmation page. */
934
+ onRedirectInitiated?: () => void;
770
935
  }
771
936
 
772
937
  /**
@@ -872,6 +1037,179 @@ interface WalleyOrder {
872
1037
  total_price?: number;
873
1038
  }
874
1039
 
1040
+ /**
1041
+ * Nexi Checkout (formerly Nets Easy) — embedded checkout via Vio Commerce.
1042
+ *
1043
+ * Fourth embedded provider, same category as Kustom/Qliro/Walley: the widget
1044
+ * collects email, phone, addresses AND payment. Two things set it apart and
1045
+ * shape this module:
1046
+ *
1047
+ * 1. There is no html_snippet. `Payment { CreatePaymentNexi }` creates the
1048
+ * payment server-side (the seller's SECRET key never leaves shopcart)
1049
+ * and returns the paymentId plus the PUBLIC checkout key; the browser
1050
+ * loads Nexi's `checkout.js` and mounts `new Dibs.Checkout({…})` in a
1051
+ * LIGHT-DOM container — Nexi refuses a container inside a shadow root
1052
+ * or another iframe.
1053
+ * 2. Nexi has no shipping picker. The payment is created with
1054
+ * `merchantHandlesShippingCost`, so Nexi holds its pay button until we
1055
+ * price the address the shopper typed: on `address-changed` the widget
1056
+ * is frozen, `Payment { UpdateNexiShipping }` re-prices for that country
1057
+ * and pushes the SHIPPING line, and the widget is thawed.
1058
+ *
1059
+ * Completion arrives as the `payment-completed` event — Nexi neither
1060
+ * redirects nor renders a receipt of its own, so the component shows Vio's
1061
+ * confirmation. Some methods inside Nexi (Vipps, Swish, MobilePay) leave the
1062
+ * page and come back to the SAME url with `?paymentId=…` appended; the
1063
+ * pending session is remembered in sessionStorage so the widget can be
1064
+ * re-mounted on that paymentId and finish.
1065
+ *
1066
+ * The Commerce order itself is created server-side by Nexi's webhook
1067
+ * (shopcart /checkout/payment/nexi/ok) — the browser never confirms money.
1068
+ */
1069
+
1070
+ /** Normalized Nexi payment (shopcart maps the Payment API). */
1071
+ interface NexiOrder {
1072
+ /** Nexi paymentId (32 hex). */
1073
+ order_id: string;
1074
+ /** Created | Reserved | Charged | Cancelled | Terminated | Unknown. */
1075
+ status: string;
1076
+ /** Public checkout key for Dibs.Checkout. */
1077
+ checkout_key: string;
1078
+ /** checkout.js of the seller's environment (test or live). */
1079
+ checkout_js_url: string;
1080
+ purchase_country?: string;
1081
+ purchase_currency?: string;
1082
+ total_price?: number;
1083
+ /**
1084
+ * Shipping to show next to the widget: the purchase country's rates while
1085
+ * no address is known (`reason: AWAITING_ADDRESS`, nothing charged), or what
1086
+ * the payment carries once one was priced (a resumed widget does not
1087
+ * announce its address again).
1088
+ */
1089
+ shipping?: NexiShippingUpdate | null;
1090
+ /** How it was paid ("Visa", "Vipps"…) — once Nexi has the details. */
1091
+ payment_method?: string | null;
1092
+ /** Last four digits of the card. */
1093
+ card_last4?: string | null;
1094
+ /** Where the receipt goes. */
1095
+ email?: string | null;
1096
+ }
1097
+ interface NexiShippingUpdate {
1098
+ ok: boolean;
1099
+ /**
1100
+ * When !ok: NO_SHIPPING — Vio does not ship to that country; or
1101
+ * AWAITING_ADDRESS — nothing charged yet, `options` are the purchase
1102
+ * country's rates and `shipping_id` the suggested one.
1103
+ */
1104
+ reason?: string;
1105
+ order_id: string;
1106
+ total_price?: number;
1107
+ shipping_name?: string;
1108
+ shipping_price?: number;
1109
+ /** The rate on the payment now. */
1110
+ shipping_id?: string;
1111
+ /**
1112
+ * Every rate the shopper may pick for this address, best first. Nexi has
1113
+ * no shipping picker of its own, so the checkout shows these.
1114
+ */
1115
+ options?: NexiShippingOption[];
1116
+ /** The address it was priced for (alpha-2 country). */
1117
+ country?: string;
1118
+ postal_code?: string;
1119
+ /** market — the checkout's country, priced at creation; consumer — the shopper's address. */
1120
+ address_source?: 'market' | 'consumer' | null;
1121
+ /** Whether this call changed the amount on the payment. */
1122
+ changed?: boolean | null;
1123
+ /**
1124
+ * Client-side only: set when the amount changed as the shopper pressed pay,
1125
+ * so the payment was stopped and the widget reloaded.
1126
+ */
1127
+ repriced_at_pay?: boolean;
1128
+ }
1129
+ interface NexiShippingOption {
1130
+ id: string;
1131
+ name: string;
1132
+ /** Incl. VAT, decimal. */
1133
+ price: number;
1134
+ }
1135
+
1136
+ /**
1137
+ * Adyen — payment via Vio Commerce, rendered with Adyen's own Drop-in.
1138
+ *
1139
+ * Adyen is NOT an embedded checkout like Kustom/Qliro/Walley/Nexi: Drop-in
1140
+ * lists payment methods (cards, Vipps, Klarna, Swish…) and charges, and that
1141
+ * is all. It collects no email, address or shipping, so it belongs with the
1142
+ * FORM-FIRST methods (Stripe, Klarna Payments): the shopper fills Vio's form
1143
+ * and picks Vio's shipping first, and only then is there a session. Three
1144
+ * things shape this module:
1145
+ *
1146
+ * 1. A session is an immutable PHOTO of the purchase. `Payment {
1147
+ * CreatePaymentAdyen }` creates it server-side (the seller's API key
1148
+ * never leaves shopcart) from the saved checkout, with the final amount,
1149
+ * and returns the session plus the PUBLIC client key. It is never
1150
+ * updated: after any change the caller discards it and creates another.
1151
+ * At "Pay", `ConfirmAdyenPayment` only VERIFIES (lesson 2026-09-17: the
1152
+ * amount does not change while the PSP charges).
1153
+ * 2. Adyen Web is loaded from Adyen's CDN, version-pinned and with
1154
+ * Subresource Integrity — never bundled: it weighs more than this whole
1155
+ * SDK, and publisher pages must only pay for it when Adyen is used.
1156
+ * Drop-in is real DOM styled by a real stylesheet (not an iframe), so it
1157
+ * mounts in the LIGHT DOM and its stylesheet goes in `document.head`.
1158
+ * 3. Vipps, Klarna, Trustly and redirect-3DS leave the page and come back
1159
+ * to `return_url` with `redirectResult` appended. The return is
1160
+ * finalised on the SERVER (`GetAdyenPayment(redirect_result)`), and the
1161
+ * return URL names the checkout, so nothing depends on this tab's
1162
+ * storage — a shopper sent from an in-app browser to Safari still lands
1163
+ * on a confirmation. Nothing is resumed from storage on a plain open,
1164
+ * which is how Nexi once opened one cart's payment on another (0.12.2).
1165
+ *
1166
+ * The page's origin must be in the "Allowed origins" of the credential whose
1167
+ * client key is used, or Adyen refuses to render — see `AdyenOriginError`.
1168
+ *
1169
+ * The Commerce order itself is created server-side by Adyen's webhook —
1170
+ * the browser never confirms money.
1171
+ */
1172
+
1173
+ /** What `CreatePaymentAdyen` answers: everything Drop-in is created with. */
1174
+ interface AdyenSession {
1175
+ order_id: string;
1176
+ session_id: string;
1177
+ session_data: string;
1178
+ client_key: string;
1179
+ environment: 'test' | 'live' | string;
1180
+ country_code: string;
1181
+ /** As ADYEN names it: Norwegian is `no-NO` (`nb-NO` renders in English). */
1182
+ shopper_locale: string;
1183
+ purchase_currency: string;
1184
+ /** Minor units — Drop-in's Pay button. */
1185
+ amount: number;
1186
+ /** Major units, shipping included. */
1187
+ total_price: number;
1188
+ shipping_name?: string | null;
1189
+ shipping_price?: number | null;
1190
+ expires_at?: string | null;
1191
+ }
1192
+ type AdyenOutcome = 'authorised' | 'pending' | 'refused' | 'cancelled' | 'error' | 'unknown';
1193
+ /** Outcome of the session a checkout owns, as Adyen reported it. */
1194
+ interface AdyenPayment {
1195
+ order_id: string;
1196
+ status: AdyenOutcome | string;
1197
+ result_code?: string | null;
1198
+ psp_reference?: string | null;
1199
+ payment_method?: string | null;
1200
+ purchase_country?: string | null;
1201
+ purchase_currency?: string | null;
1202
+ total_price?: number | null;
1203
+ shipping_name?: string | null;
1204
+ shipping_price?: number | null;
1205
+ email?: string | null;
1206
+ order_created: boolean;
1207
+ }
1208
+ interface AdyenResult {
1209
+ resultCode?: string;
1210
+ sessionResult?: string;
1211
+ }
1212
+
875
1213
  /**
876
1214
  * Checkout types — multi-sponsor compatible.
877
1215
  *
@@ -879,7 +1217,7 @@ interface WalleyOrder {
879
1217
  * merchant, same as iOS multi-sponsor model). Multiple sponsors → multiple
880
1218
  * sequential checkouts.
881
1219
  */
882
- type PaymentMethod = 'apple-pay' | 'klarna' | 'vipps' | 'card' | 'stripe' | 'kustom' | 'qliro' | 'walley';
1220
+ type PaymentMethod = 'apple-pay' | 'klarna' | 'vipps' | 'card' | 'stripe' | 'kustom' | 'qliro' | 'walley' | 'nexi' | 'adyen';
883
1221
  interface CheckoutAddress {
884
1222
  firstName: string;
885
1223
  lastName: string;
@@ -910,6 +1248,12 @@ interface CheckoutState {
910
1248
  sessionId?: string;
911
1249
  /** Klarna Payments client token (native GraphQL flow). */
912
1250
  clientToken?: string;
1251
+ /**
1252
+ * Which `open()` this state belongs to — a new number every time a checkout
1253
+ * is opened, kept by every later update. An embedded widget belongs to the
1254
+ * session it was mounted in: a new session means a new order.
1255
+ */
1256
+ session?: number;
913
1257
  }
914
1258
 
915
1259
  /**
@@ -975,18 +1319,39 @@ interface KlarnaPaymentsHandle {
975
1319
  declare class CheckoutManager extends EventTarget {
976
1320
  private readonly cartManager;
977
1321
  private state;
1322
+ /** Counts `open()` calls — see CheckoutState.session. */
1323
+ private sessionSeq;
978
1324
  private applePayAvailableCache;
979
1325
  /** Gateway hints learned from CreatePaymentApplePay (per session). The
980
1326
  * backend's gateway_merchant_id may be a publishable key (pk_…) or a Stripe
981
1327
  * Connect account (acct_…) — stored defensively by prefix. */
982
1328
  private applePayPublishableKey;
983
1329
  private applePayConnectedAccount;
1330
+ /** Stripe Connect account of the channel, from its Stripe config. */
1331
+ private stripeConnectAccount;
984
1332
  private klarnaAvailableCache;
985
1333
  /** Live q1 listeners while a Qliro widget is mounted. */
986
1334
  private qliroController;
1335
+ /** Live Dibs.Checkout handle while a Nexi widget is mounted. */
1336
+ private nexiHandle;
1337
+ /** Live Drop-in while an Adyen session is mounted. */
1338
+ private adyenHandle;
1339
+ private stripeHandle;
1340
+ /**
1341
+ * The rate the shopper wants. Before an address it is only remembered (the
1342
+ * suggested one, or their pick); every re-pricing asks for it, and the
1343
+ * backend charges it if it reaches the address.
1344
+ */
1345
+ private nexiPreferredShipping;
1346
+ /** The rates offered before an address was typed. */
1347
+ private nexiShippingPreview;
1348
+ /** What the last `address-changed` was priced with — a picked rate re-prices the same address. */
1349
+ private nexiShippingContext;
987
1350
  private klarnaOrderInFlight;
988
1351
  /** Last backend shippings fetched (per-supplier), for UI reuse. */
989
1352
  private lastFetchedShippings;
1353
+ /** See `lastShippingsResolved`. */
1354
+ private shippingsResolved;
990
1355
  /** Per-sponsor payment methods cache + in-flight dedupe. */
991
1356
  private paymentMethodsCache;
992
1357
  private paymentMethodsPromises;
@@ -998,6 +1363,12 @@ declare class CheckoutManager extends EventTarget {
998
1363
  /** Update the backend checkout (terms are re-asserted unless overridden). */
999
1364
  updateCheckout(variables: Record<string, unknown>, sponsorId?: number): Promise<any>;
1000
1365
  getCheckout(checkoutId: string, sponsorId?: number): Promise<any>;
1366
+ /**
1367
+ * The Vio order number (#4497) a checkout became, or null: not born yet,
1368
+ * or an API that does not say it. Never throws — it is a line on a
1369
+ * receipt, and a receipt does not fail for it.
1370
+ */
1371
+ getOrderNumber(checkoutId: string, sponsorId?: number): Promise<number | null>;
1001
1372
  /**
1002
1373
  * Payment methods enabled for the sponsor (backend-configured). Memoised per
1003
1374
  * sponsor with in-flight dedupe — several UI components ask on every open.
@@ -1014,6 +1385,13 @@ declare class CheckoutManager extends EventTarget {
1014
1385
  * this at all.
1015
1386
  */
1016
1387
  fetchAvailableShippings(sponsorId?: number): Promise<KlarnaShippingOption[]>;
1388
+ /**
1389
+ * Whether the last `fetchAvailableShippings` got an answer from the backend,
1390
+ * possibly an empty one, rather than failing or finding no cart. The two
1391
+ * return the same empty list, and only an answer means the cart has
1392
+ * nothing it can ship with.
1393
+ */
1394
+ get lastShippingsResolved(): boolean;
1017
1395
  /** Set the chosen shipping per supplier on the backend cart. */
1018
1396
  updateShippingsBySupplier(data: Array<{
1019
1397
  shipping_id: string;
@@ -1034,21 +1412,51 @@ declare class CheckoutManager extends EventTarget {
1034
1412
  */
1035
1413
  startStripePayment(sponsorId?: number, formData?: unknown): Promise<any>;
1036
1414
  /**
1037
- * Vipps payment link: same flow as Stripe — CreatePaymentVipps → redirect to
1038
- * payment_url.
1415
+ * Vipps: create the payment via Vio Commerce and redirect to Vipps'
1416
+ * landing page (on a phone it opens the app; on a desktop it offers to
1417
+ * send the payment to the phone).
1418
+ *
1419
+ * `express: true` asks for Vipps Express — address and delivery chosen
1420
+ * inside the app, the email handed back with the payment — which is what
1421
+ * the Vipps buttons on the product and the cart ask for. When the cart
1422
+ * cannot have it (several suppliers, digital goods, no rate for the
1423
+ * country) the backend creates NO payment and answers `express: false`
1424
+ * with the reason; this resolves with that answer, without redirecting,
1425
+ * so the caller can open the ordinary checkout instead. Without the flag
1426
+ * the backend decides: Express while the cart has no delivery yet, a
1427
+ * plain payment once the shopper chose one in our form.
1428
+ */
1429
+ startVippsPayment(sponsorId?: number, formData?: unknown, options?: {
1430
+ express?: boolean;
1431
+ }): Promise<any>;
1432
+ /**
1433
+ * The Vipps Express button: the shopper taps it and the app opens with
1434
+ * address and delivery already there. Resolves with `{ express: false,
1435
+ * reason }` — and nothing redirected — when this cart cannot have it.
1039
1436
  */
1040
- startVippsPayment(sponsorId?: number, formData?: unknown): Promise<any>;
1437
+ startVippsExpress(sponsorId?: number): Promise<any>;
1041
1438
  /** Vipps' own payment state for the checkout — see getVippsStatus in
1042
1439
  * cart-queries.ts for why this exists instead of trusting GetCheckout. */
1043
1440
  getVippsStatus(checkoutId: string, sponsorId?: number): Promise<{
1044
1441
  state?: string;
1442
+ duplicate_of?: string | null;
1045
1443
  } | null>;
1046
1444
  /**
1047
1445
  * Kustom (former Klarna Checkout) — create the KCO order via Vio Commerce
1048
1446
  * and render its html_snippet into `container`. The widget collects
1049
1447
  * address, shipping and payment by itself; the SDK renders nothing else.
1050
1448
  */
1051
- mountKustomCheckout(container: HTMLElement, sponsorId?: number): Promise<KustomOrder>;
1449
+ mountKustomCheckout(container: HTMLElement, sponsorId?: number, handlers?: KustomListenerHandlers): Promise<KustomOrder>;
1450
+ private kustomController;
1451
+ /** Disarm the widget's listeners with the widget they belong to. */
1452
+ destroyKustomListeners(): void;
1453
+ /**
1454
+ * The cart changed under an open Kustom widget: lock it, push the cart
1455
+ * into the SAME order, and let the widget refresh itself. Kustom's own
1456
+ * rule — never a new order for a cart change. The widget auto-resumes
1457
+ * after 10 s if the sync never comes back.
1458
+ */
1459
+ syncKustomOrder(sponsorId?: number): Promise<KustomOrder | null>;
1052
1460
  /** Re-read a Kustom order — used on the confirmation return trip. */
1053
1461
  getKustomOrder(orderId: string, sponsorId?: number): Promise<KustomOrder | null>;
1054
1462
  /** Render a Kustom html_snippet (e.g. the confirmation receipt) into a container. */
@@ -1084,8 +1492,123 @@ declare class CheckoutManager extends EventTarget {
1084
1492
  mountWalleyCheckout(container: HTMLElement, sponsorId?: number, onPurchaseCompleted?: (order: WalleyOrder) => void): Promise<WalleyOrder>;
1085
1493
  /** Re-read the Walley session owned by a checkout — the confirmation trip. */
1086
1494
  getWalleyOrder(checkoutId: string, sponsorId?: number): Promise<WalleyOrder | null>;
1495
+ /**
1496
+ * Mount the Nexi embedded checkout — Nexi's own JS SDK, not a snippet.
1497
+ *
1498
+ * `onCompleted` fires on Nexi's `payment-completed` (no redirect: Nexi
1499
+ * renders no receipt, the component shows Vio's confirmation). Shipping is
1500
+ * Vio's: Nexi holds its pay button until `address-changed` has been
1501
+ * re-priced through `UpdateNexiShipping` — the widget is frozen meanwhile
1502
+ * and `onShipping` reports the outcome (NO_SHIPPING keeps it held).
1503
+ *
1504
+ * A session interrupted by a third-party redirect inside Nexi (Vipps,
1505
+ * Swish, MobilePay) is remembered in sessionStorage and resumed on the
1506
+ * same paymentId instead of creating a new payment — only when `resume`
1507
+ * names it. Every other opening creates a payment for the cart as it is.
1508
+ */
1509
+ mountNexiCheckout(container: HTMLElement, sponsorId?: number, handlers?: {
1510
+ onCompleted?: (order: NexiOrder) => void;
1511
+ onShipping?: (result: NexiShippingUpdate | null, error?: unknown) => void;
1512
+ },
1513
+ /**
1514
+ * Set ONLY when the page came back from a redirect inside Nexi
1515
+ * (Vipps/Swish/MobilePay) with `?paymentId=`: resume that payment.
1516
+ */
1517
+ resume?: {
1518
+ paymentId: string;
1519
+ }): Promise<NexiOrder>;
1520
+ /**
1521
+ * The shopper picked another rate from the `options` Nexi's last
1522
+ * re-pricing returned: charge that one instead. Nexi has no shipping picker,
1523
+ * so the checkout shows the rates and calls this. A no-op until an address
1524
+ * has been typed in the widget.
1525
+ */
1526
+ pickNexiShipping(shippingId: string): Promise<void>;
1527
+ /**
1528
+ * `pay-initialized` → confirm the shipping for the address Nexi will ship
1529
+ * to → `payment-order-finalized`.
1530
+ *
1531
+ * The payment already carries a shipping (set at creation, re-priced on
1532
+ * every address and pick), so normally nothing changes and Nexi charges.
1533
+ * When the shopper's address was never announced — Nexi fills it in for a
1534
+ * shopper it recognises — the backend reads it from the payment. If that
1535
+ * changes the amount, the payment is STOPPED and the widget reloaded: an
1536
+ * amount that changes while Nexi charges is what failed on 2026-09-16/17
1537
+ * (payments 085277846ae44f7498ae94e112435d63, f6116e6d68294a88927d35b05d907f10).
1538
+ */
1539
+ private finalizeNexiPayment;
1540
+ /** address-changed → freeze → UpdateNexiShipping → thaw. */
1541
+ private repriceNexiShipping;
1542
+ /** Release the Dibs.Checkout listeners with the widget they belong to. */
1543
+ destroyNexi(): void;
1544
+ /** Re-read the Nexi payment owned by a checkout. */
1545
+ getNexiOrder(checkoutId: string, sponsorId?: number): Promise<NexiOrder | null>;
1546
+ /**
1547
+ * Adyen: FORM-FIRST. Saves the shopper's form and shipping pick on the
1548
+ * checkout (Adyen collects neither), creates a session with that final
1549
+ * amount and mounts Adyen's Drop-in on it. A session is never updated —
1550
+ * after ANY change the caller destroys this mount and calls again.
1551
+ *
1552
+ * At "Pay" the backend only confirms that the session still pays for the
1553
+ * checkout; when it does not, Adyen is stopped and `onReplaced` tells the
1554
+ * caller to remount. Completion is asked of Adyen through the backend
1555
+ * (`GetAdyenPayment`) — the browser's own result is never the answer.
1556
+ */
1557
+ mountAdyenCheckout(container: HTMLElement, sponsorId: number | undefined, formData: unknown, callbacks: {
1558
+ onCompleted: (payment: AdyenPayment | null, session: AdyenSession) => void;
1559
+ onFailed: (result: AdyenResult, session: AdyenSession) => void;
1560
+ /** The session no longer pays for the checkout (reason from the backend). */
1561
+ onReplaced: (reason: string) => void;
1562
+ onError?: (error: unknown) => void;
1563
+ }): Promise<AdyenSession>;
1564
+ /** Unmount Drop-in. Safe to call when nothing is mounted. */
1565
+ destroyAdyen(): void;
1566
+ /**
1567
+ * Outcome of the Adyen session a checkout owns. With `redirectResult` (the
1568
+ * return from Vipps, Klarna, Trustly or a redirect-3DS) the redirect is
1569
+ * finalised on the server.
1570
+ */
1571
+ getAdyenPayment(checkoutId: string, proof?: {
1572
+ sessionResult?: string;
1573
+ redirectResult?: string;
1574
+ }, sponsorId?: number): Promise<AdyenPayment | null>;
1087
1575
  setAddress(address: CheckoutAddress): void;
1088
1576
  selectPaymentMethod(method: PaymentMethod): void;
1577
+ /**
1578
+ * Which Stripe flow this channel offers: `native` pays on our own page,
1579
+ * `link` sends the shopper to a page hosted by Stripe. The channel's two
1580
+ * toggles decide it and the answer travels in the method's config
1581
+ * (api-microservice, `stripe-offer.ts`). A channel that predates that
1582
+ * field answers `link`, which is what every client did before.
1583
+ */
1584
+ /**
1585
+ * Does this channel's Vipps offer Express — the buy-now buttons that open
1586
+ * the app with address and delivery? Vio Commerce announces it as
1587
+ * `config.express` on the Vipps method, the way Stripe announces `mode`;
1588
+ * the seller switches it on its Vipps row. Unknown means yes: Express is
1589
+ * the default, and the backend refuses it with a reason if it cannot.
1590
+ */
1591
+ getVippsExpressEnabled(sponsorId?: number): Promise<boolean>;
1592
+ getStripeMode(sponsorId?: number): Promise<'native' | 'link'>;
1593
+ /**
1594
+ * Stripe's Payment Element, mounted on our own page for a checkout that is
1595
+ * ready to be paid. Creating it mints a PaymentIntent, so it happens when
1596
+ * the shopper asks for the payment step, never while they type.
1597
+ *
1598
+ * The order is not born here: `confirm()` only says what Stripe told the
1599
+ * browser. The `payment_intent.succeeded` webhook creates it server-side,
1600
+ * and the caller then reads the checkout to see it land.
1601
+ */
1602
+ mountStripeCheckout(container: HTMLElement, sponsorId: number | undefined, formData: unknown, callbacks?: {
1603
+ onReady?: () => void;
1604
+ onLoadError?: (message: string) => void;
1605
+ }): Promise<{
1606
+ handle: StripeElementHandle;
1607
+ intent: StripeIntent;
1608
+ checkoutId: string;
1609
+ }>;
1610
+ /** Unmount the Payment Element. Safe when nothing is mounted. */
1611
+ destroyStripe(): void;
1089
1612
  /**
1090
1613
  * The Stripe publishable key for a sponsor, taken from its own commerce
1091
1614
  * channel (`GetAvailablePaymentMethods` → Stripe → config.publishableKey).
@@ -1217,6 +1740,8 @@ declare class CheckoutManager extends EventTarget {
1217
1740
  * (Stripe will route to the platform account in that case).
1218
1741
  */
1219
1742
  private findStripeConnectAccount;
1743
+ /** The sponsor's connected account, read fresh from its channel config. */
1744
+ private resolveStripeConnectAccount;
1220
1745
  private emit;
1221
1746
  }
1222
1747
 
@@ -1250,6 +1775,7 @@ declare class CheckoutManager extends EventTarget {
1250
1775
  * the publisher-facing feature; NOT part of the Vio pipeline)
1251
1776
  * 3. `vio:analytics` DOM event — always when started (inspector/bridges)
1252
1777
  */
1778
+
1253
1779
  declare const ANALYTICS_EVENT_NAMES: readonly ["view_item_list", "select_item", "view_item", "add_to_cart", "remove_from_cart", "view_cart", "begin_checkout", "purchase", "component_impression", "component_click", "ad_impression", "ad_click", "poll_impression", "contest_impression", "session_start", "session_end", "checkout_error", "sdk_error"];
1254
1780
  type AnalyticsEventName = (typeof ANALYTICS_EVENT_NAMES)[number];
1255
1781
  /** Camel-case for DX; mapped to the snake_case wire format at build time. */
@@ -1406,6 +1932,60 @@ declare class AnalyticsManager extends EventTarget {
1406
1932
  private cartCommerce;
1407
1933
  private findLine;
1408
1934
  }
1935
+ /**
1936
+ * The `campaign_id` of an event. In order: the context's explicit id; the
1937
+ * active campaign of `campaigns[]` the event's sponsor takes part in, as its
1938
+ * primary or one of its secondaries — when it is in several, the surface's
1939
+ * default campaign if it is one of them, else the first one the backend
1940
+ * lists; the default campaign (`campaign.id`). `/v2/mobile/config` has no
1941
+ * top-level `campaignId` — reading one is why every event used to leave
1942
+ * with `campaign_id: 0` and the campaigns screen stayed empty.
1943
+ *
1944
+ * A malformed `campaigns[]` (not an array, a null entry) never breaks
1945
+ * `track()`: it falls back to `campaign.id`.
1946
+ */
1947
+ declare function resolveCampaignId(ctx: Pick<AnalyticsContext, 'campaignId' | 'sponsorId'>, boot: Pick<BootstrapResponse, 'campaign' | 'campaigns'> | null | undefined): number | undefined;
1948
+ /**
1949
+ * `detail` of `vio:payment-success` as the checkout emits it. Four paths,
1950
+ * three shapes: a redirect return (`orderId` = Vio's checkout id), the
1951
+ * confirmation drawer and a provider's own receipt (`result` from the
1952
+ * provider or the backend, plus Vio's `checkoutId`), and Apple Pay express
1953
+ * from the cart (`result` with the backend's `confirmation`, no sponsor).
1954
+ */
1955
+ interface PaymentSuccessDetail {
1956
+ method?: string;
1957
+ sponsorId?: number | string;
1958
+ /** Redirect return: Vio's checkout id (the name predates `checkoutId`). */
1959
+ orderId?: string | number;
1960
+ /** Vio's checkout id — from the checkout state or the return URL. */
1961
+ checkoutId?: string | number;
1962
+ result?: PaymentSuccessResult | null;
1963
+ }
1964
+ /**
1965
+ * What the checkout attaches as `result`. Only `confirmation` carries a Vio
1966
+ * id: the order `ConfirmPaymentApplePay` created. `order.orderId` / `orderId`
1967
+ * are the PROVIDER's references (Qliro's, Walley's — the checkout itself
1968
+ * shows them as `providerRef`), and `chargedTotal` includes shipping on some
1969
+ * methods only. Analytics reads none of those.
1970
+ */
1971
+ interface PaymentSuccessResult {
1972
+ confirmation?: {
1973
+ orderId?: string | number | null;
1974
+ status?: string;
1975
+ } | null;
1976
+ [key: string]: unknown;
1977
+ }
1978
+ /**
1979
+ * The `order_id` of a `purchase`: ALWAYS a Vio id, never a provider's
1980
+ * reference. Normalized across every emitter: `orderId` (redirect return) →
1981
+ * `result.confirmation.orderId` (Apple Pay) → `checkoutId`. `value` and
1982
+ * `currency` are deliberately NOT read from the result: on every path they
1983
+ * come from the cart snapshot (sum of the items, no shipping), so revenue
1984
+ * stays comparable across payment methods — the charged total will arrive
1985
+ * through the server-side `order_paid` event. With nothing to say it
1986
+ * returns `{}`, so the cart snapshot keeps its keys.
1987
+ */
1988
+ declare function purchaseFromPaymentSuccess(d: PaymentSuccessDetail): Pick<AnalyticsCommerce, 'orderId'>;
1409
1989
 
1410
1990
  declare class VioFacade {
1411
1991
  private apiInstance;
@@ -1415,6 +1995,10 @@ declare class VioFacade {
1415
1995
  /** Last bootstrap failure — short backoff so cart mutations don't hammer a
1416
1996
  * dead endpoint on every call. */
1417
1997
  private bootstrapFailedAt;
1998
+ /** Bumped by every init(). A bootstrap started under an older configuration
1999
+ * (another key or environment) is still in flight after a re-init; its answer
2000
+ * belongs to that configuration and must not land in this one. */
2001
+ private generation;
1418
2002
  private cartManager;
1419
2003
  private checkoutManager;
1420
2004
  private analyticsManager;
@@ -1430,11 +2014,16 @@ declare class VioFacade {
1430
2014
  * listeners are installed) until an explicit `Vio.analytics.start()`.
1431
2015
  */
1432
2016
  get analytics(): AnalyticsManager;
1433
- /** Lazy VioApi for REST endpoints on `api-dev.vio.live`. */
2017
+ /** Lazy VioApi for REST endpoints on `api-staging.vio.live`. */
1434
2018
  get api(): VioApi;
1435
2019
  /**
1436
2020
  * Bootstrap — fetches client config and caches it. Dedupes in-flight
1437
2021
  * concurrent requests.
2022
+ *
2023
+ * A request that was started before the last init() (Vev starts with the key
2024
+ * the browser remembers, then the page's own key arrives) answers for a key
2025
+ * that is gone: it neither fills the cache nor arms the failure backoff, and
2026
+ * whoever awaited it gets the current configuration's bootstrap instead.
1438
2027
  */
1439
2028
  bootstrap(): Promise<BootstrapResponse>;
1440
2029
  get bootstrapCache(): BootstrapResponse | null;
@@ -1456,6 +2045,33 @@ declare const Vio: VioFacade;
1456
2045
  *
1457
2046
  * RELEASE CHECKLIST: bump together with package.json (see CONTRIBUTING).
1458
2047
  */
1459
- declare const SDK_VERSION = "0.11.1";
2048
+ declare const SDK_VERSION = "0.21.0";
2049
+
2050
+ /**
2051
+ * Vipps MobilePay's own button, the way the design guidelines ask for it.
2052
+ *
2053
+ * Vipps publishes a web component (`<vipps-mobilepay-button>`) that draws
2054
+ * the on-brand button and nothing else: it does not start the payment, we
2055
+ * do, on its click. Using it means no logo of ours to keep in step with the
2056
+ * brand rules (ePayment checklist, "Follow the design guidelines",
2057
+ * 2026-10-06). The script is loaded once, on demand, from Vipps' CDN; when
2058
+ * it does not arrive in time — blocked, offline — callers draw the plain
2059
+ * orange button they always had.
2060
+ */
2061
+ declare const VIPPS_BUTTON_SCRIPT = "https://cdn.vippsmobilepay.com/js/button/button.js";
2062
+ declare const VIPPS_BUTTON_TAG = "vipps-mobilepay-button";
2063
+ /**
2064
+ * Resolves true once Vipps' button element is defined, false when its script
2065
+ * failed to load (or, with `timeoutMs`, did not answer in time). Callers draw
2066
+ * their own button meanwhile and swap it for Vipps' when this resolves — the
2067
+ * CDN takes a few seconds on a slow line, and nobody should wait for it.
2068
+ */
2069
+ declare function ensureVippsButton(timeoutMs?: number): Promise<boolean>;
2070
+ /** The attributes of the official button as Vio uses it (React hosts spread these). */
2071
+ declare function vippsButtonAttributes(verb?: 'buy' | 'pay' | 'express' | 'continue', opts?: {
2072
+ stretched?: boolean;
2073
+ compact?: boolean;
2074
+ language?: string;
2075
+ }): Record<string, string>;
1460
2076
 
1461
- export { ADD_ITEM_MUTATION, type AddManualOptions, type AddProductOptions, type AnalyticsCommerce, type AnalyticsContext, type AnalyticsEventName, type AnalyticsItemInput, AnalyticsManager, type AnalyticsStartOptions, type ApplePayConfig, type ApplePayResult, type BootstrapResponse, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, type CartChangeDetail, type CartLineItem, CartManager, type CartQueryOptions, type CheckoutAddress, type CheckoutChangeDetail, CheckoutManager, type CheckoutState, CommerceClient, Configuration, type CreatePaymentVippsResponse, type CreatePaymentVippsVariables, DELETE_ITEM_MUTATION, type Environment, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, type GetVippsStatusVariables, type ImageSize, type PaymentCompleteDetail, type PaymentMethod, type PaymentSelectDetail, type PlacementComponent, type Product, type ProductCategory, type ProductImage, type ProductOption, type ProductPrice, type ProductVariant, type ResolvedConfig, SDK_VERSION, type Sponsor, type SponsorCartState, type SponsorCommerceBlock, type TrackOptions, UPDATE_CHECKOUT_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, Vio, VioApi, VioApiError, type VioConfig, type VippsPaymentState, type VippsStatusResult, addItem, checkApplePayAvailability, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, executeCartGraphQL, formatPrice, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, primaryImageUrl, showApplePaySheet, updateCheckout, updateItem, updateShippingsBySupplier };
2077
+ export { ADD_ITEM_MUTATION, type AddManualOptions, type AddProductOptions, type AnalyticsCommerce, type AnalyticsContext, type AnalyticsEventName, type AnalyticsItemInput, AnalyticsManager, type AnalyticsStartOptions, type ApplePayConfig, type ApplePayResult, type BootstrapCampaign, type BootstrapCampaignEntry, type BootstrapCampaignStatus, type BootstrapResponse, type BootstrapSlot, CREATE_CART_MUTATION, CREATE_CHECKOUT_MUTATION, CREATE_PAYMENT_STRIPE_MUTATION, CREATE_PAYMENT_VIPPS_MUTATION, type CartChangeDetail, type CartLineItem, CartManager, type CartQueryOptions, type CheckoutAddress, type CheckoutChangeDetail, CheckoutManager, type CheckoutState, CommerceClient, Configuration, type CreatePaymentVippsResponse, type CreatePaymentVippsVariables, DELETE_ITEM_MUTATION, type Environment, GET_AVAILABLE_PAYMENT_METHODS_QUERY, GET_CART_QUERY, GET_CHECKOUT_QUERY, GET_LINE_ITEMS_BY_SUPPLIER_QUERY, GET_VIPPS_STATUS_QUERY, type GetVippsStatusVariables, type ImageSize, type PaymentCompleteDetail, type PaymentMethod, type PaymentSelectDetail, type PaymentSuccessDetail, type PaymentSuccessResult, type PlacementComponent, type Product, type ProductCategory, type ProductImage, type ProductOption, type ProductPrice, type ProductVariant, type ResolvedConfig, SDK_VERSION, type Sponsor, type SponsorCartState, type SponsorCommerceBlock, type TrackOptions, UPDATE_CHECKOUT_MUTATION, UPDATE_ITEM_MUTATION, UPDATE_SHIPPINGS_BY_SUPPLIER_MUTATION, VIPPS_BUTTON_SCRIPT, VIPPS_BUTTON_TAG, Vio, VioApi, VioApiError, type VioConfig, type VippsPaymentState, type VippsStatusResult, addItem, checkApplePayAvailability, createCart, createCheckout, createCommerceClient, createPaymentStripe, createPaymentVipps, createVioApi, deleteItem, displayPrice, ensureVippsButton, executeCartGraphQL, formatPrice, getAvailablePaymentMethods, getCart, getCartGraphQLOptions, getCheckout, getCustomerSessionId, getGlobalCurrency, getLineItemsBySupplier, getVippsStatus, primaryImageUrl, purchaseFromPaymentSuccess, resolveCampaignId, showApplePaySheet, updateCheckout, updateItem, updateShippingsBySupplier, vippsButtonAttributes };