import { APIResponse } from "../../../storefront-api-client/src"; import { IkasCart, IkasOrderLineItem, IkasProduct, IkasProductOffer, IkasProductVariant } from "../../../storefront-models/src"; import { IkasCartStore } from "../../../stores/cart"; /** * Get the checkout URL for the current cart. * * @ai-category Cart * @ai-related hasCart, waitForCartStoreInit * * @param cartStore - The cart store instance * @returns The checkout URL string, or empty string if no cart exists * * @example * ```typescript * import { cartStore, getCheckoutUrlFromCartStore } from "@ikas/bp-storefront"; * * function handleCheckout() { * const checkoutUrl = getCheckoutUrlFromCartStore(cartStore); * if (checkoutUrl) { * window.location.href = checkoutUrl; * } * } * ``` */ export declare function getCheckoutUrlFromCartStore(cartStore: IkasCartStore): string; /** * Add a product variant to the shopping cart. * * Clamps the quantity to the sales channel's `minQuantityPerCart`/`maxQuantityPerCart` only * when it creates a new cart line. When the variant already has a line in the cart, the add * is delegated to `changeItemQuantity` (existing quantity + `initialQuantity`) with no * client-side clamp — a quantity past `maxQuantityPerCart` is then rejected by the API with * the `MAX_QUANTITY_PER_CART_LIMIT_REACHED` code in `result.response.errorCodes`, never as a * `validationError`. See `changeItemQuantity` for the handling pattern. * * @ai-category ProductDetail, Cart * @ai-related getSelectedProductVariant, findExistingCartItem, hasProductVariantStock * * @param variant - The product variant to add (get via getSelectedProductVariant) * @param product - The full product object containing variant selection state * @param initialQuantity - Quantity to add (default: 1) * @param options - Optional flags like { isPayWithIkas: true } * @returns Result with success flag and optional validation errors * * @example * ```typescript * import { addItemToCart, getSelectedProductVariant } from "@ikas/bp-storefront"; * import { IkasProduct } from "@ikas/bp-storefront"; * * async function handleAddToCart(product: IkasProduct) { * const variant = getSelectedProductVariant(product); * const result = await addItemToCart(variant, product, 1); * * if (result.success) { * showToast("Added to cart!"); * } else if (result.validationError === "INSUFFICIENT_STOCK") { * showToast("Out of stock"); * } else if (result.validationError === "INVALID_PRODUCT_OPTION_VALUES") { * showToast("Please select all options"); * } * } * ``` */ export declare function addItemToCart(variant: IkasProductVariant, product: IkasProduct, initialQuantity?: number, options?: AddItemOptions): Promise; /** * Add the currently selected product variant to cart (simplified version). * This is a convenience wrapper that automatically gets the selected variant. * * @ai-category ProductList, Cart * @ai-related addItemToCart, getSelectedProductVariant * * @param product - The product object with selectedVariantValues set * @param initialQuantity - Quantity to add (default: 1) * @returns Result with success flag and optional validation errors * * @example * ```typescript * import { addSelectedtedVariantToCart } from "@ikas/bp-storefront"; * import { IkasProduct } from "@ikas/bp-storefront"; * * // Quick add button in product list * async function handleQuickAdd(product: IkasProduct) { * const result = await addSelectedtedVariantToCart(product, 1); * if (result.success) { * showToast("Added to cart!"); * } * } * ``` */ export declare function addSelectedtedVariantToCart(product: IkasProduct, initialQuantity?: number): Promise; /** * Change the quantity of an item in the cart. * Use quantity=0 to remove the item. * * Performs no client-side clamping or validation: a quantity above the sales channel's * `maxQuantityPerCart` is rejected by the API with the `MAX_QUANTITY_PER_CART_LIMIT_REACHED` * code in `result.response.errorCodes` (never as a `validationError`). Prevent violations in * the stepper and treat the error code as the fallback. * * @ai-category Cart * @ai-related removeItem, findExistingCartItem * * @param item - The order line item to update (from cart.orderLineItems) * @param quantity - New quantity (0 removes the item) * @param offers - Optional product offers for campaign pricing * @param product - Optional product for analytics * @returns Result with success flag * * @example * ```typescript * import { APIErrorCode, cartStore, changeItemQuantity } from "@ikas/bp-storefront"; * * // Increment quantity * async function handleIncrement(itemId: string) { * const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId); * if (item) { * const result = await changeItemQuantity(item, item.quantity + 1); * if (!result.success) { * const limitHit = result.response?.errorCodes?.includes( * APIErrorCode.MAX_QUANTITY_PER_CART_LIMIT_REACHED * ); * showToast(limitHit ? "Per-cart quantity limit reached" : "Failed to update quantity"); * } * } * } * * // Decrement quantity * async function handleDecrement(itemId: string) { * const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId); * if (item && item.quantity > 1) { * await changeItemQuantity(item, item.quantity - 1); * } * } * ``` */ export declare function changeItemQuantity(item: IkasOrderLineItem, quantity: number, offers?: IkasProductOffer[], product?: IkasProduct): Promise; /** * Change the quantity of a cart item (cart-aware wrapper). * Delegates to changeItemQuantity — the cart parameter is accepted for API consistency but not used directly. * * @ai-category Cart * @ai-related changeItemQuantity, removeItem, findExistingCartItem * * @param cart - The cart object (accepted for interface consistency) * @param item - The order line item to update (from cart.orderLineItems) * @param quantity - New quantity (0 removes the item) * @param offers - Optional product offers for campaign pricing * @param product - Optional product for analytics * @returns Result with success flag * * @example * ```typescript * import { cartStore, changeCartItemQuantity } from "@ikas/bp-storefront"; * * async function handleQuantityChange(itemId: string, newQuantity: number) { * const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId); * if (cartStore.cart && item) { * const result = await changeCartItemQuantity(cartStore.cart, item, newQuantity); * if (!result.success) { * showToast("Failed to update quantity"); * } * } * } * ``` */ export declare function changeCartItemQuantity(cart: IkasCart, item: IkasOrderLineItem, quantity: number, offers?: IkasProductOffer[], product?: IkasProduct): Promise; /** * Check if a cart line item was automatically created by a campaign adjustment. * Auto-created items (e.g. free gifts) are typically non-removable by the customer. * * @ai-category Cart * @ai-related changeItemQuantity, removeItem * * @param cart - The cart object containing order adjustments * @param item - The order line item to check * @returns True if the item was auto-created by an adjustment, false otherwise * * @example * ```typescript * import { cartStore, isOrderLineItemAutoCreated } from "@ikas/bp-storefront"; * * function renderCartItems() { * const items = cartStore.cart?.orderLineItems ?? []; * return items.map(item => ({ * ...item, * isGift: isOrderLineItemAutoCreated(cartStore.cart!, item), * })); * } * ``` */ export declare function isOrderLineItemAutoCreated(cart: IkasCart, item: IkasOrderLineItem): boolean; /** * Remove an item from the cart. * * @ai-category Cart * @ai-related changeItemQuantity, findExistingCartItem * * @param item - The order line item to remove (from cart.orderLineItems) * @returns Result with success flag * * @example * ```typescript * import { cartStore, removeItem } from "@ikas/bp-storefront"; * * async function handleRemoveItem(itemId: string) { * const item = cartStore.cart?.orderLineItems.find(i => i.id === itemId); * if (item) { * const result = await removeItem(item); * if (result.success) { * showToast("Item removed"); * } * } * } * ``` */ export declare function removeItem(item: IkasOrderLineItem): Promise; /** * Clear the cart from localStorage and the cart store. * After calling this, the cart will be empty and no cart ID will be persisted. * * @ai-category Cart * @ai-related setCart, getCart, hasCart * * @param cartStore - The cart store instance to clear * @returns void * * @example * ```typescript * import { cartStore, removeCart } from "@ikas/bp-storefront"; * * function handleClearCart() { * removeCart(cartStore); * showToast("Cart cleared"); * } * ``` */ export declare function removeCart(cartStore: IkasCartStore): void; /** * Wait for the cart store to finish initial loading. * Use this before accessing cart data to ensure it's loaded. * * @ai-category Cart * @ai-related hasCart, getCart * * @param cartStore - The cart store instance * @returns Promise that resolves when cart is loaded * * @example * ```typescript * import { cartStore, waitForCartStoreInit, hasCart } from "@ikas/bp-storefront"; * * async function initializeCartUI() { * await waitForCartStoreInit(cartStore); * * if (hasCart(cartStore)) { * // Cart has items, show cart badge * updateCartBadge(cartStore.cart!.orderLineItems.length); * } * } * ``` */ export declare function waitForCartStoreInit(cartStore: IkasCartStore): Promise; /** * Find an existing cart item for a specific product variant. * Useful for showing "Already in cart" state or updating quantities. * * @ai-category ProductDetail, Cart * @ai-related addItemToCart, getSelectedProductVariant * * @param cart - The cart object * @param variant - The product variant to find * @param product - The product containing the variant * @returns The matching order line item, or undefined if not found * * @example * ```typescript * import { cartStore, findExistingCartItem, getSelectedProductVariant } from "@ikas/bp-storefront"; * import { IkasProduct } from "@ikas/bp-storefront"; * * function getCartItemForProduct(product: IkasProduct) { * if (!cartStore.cart) return null; * * const variant = getSelectedProductVariant(product); * const existingItem = findExistingCartItem(cartStore.cart, variant, product); * * if (existingItem) { * return { * inCart: true, * quantity: existingItem.quantity * }; * } * return { inCart: false, quantity: 0 }; * } * ``` */ export declare function findExistingCartItem(cart: IkasCart, variant: IkasProductVariant, product: IkasProduct): IkasOrderLineItem | undefined; /** * Find an existing cart item for a product using its currently selected variant. * Convenience wrapper around findExistingCartItem that automatically resolves the selected variant. * * @ai-category ProductDetail, Cart * @ai-related findExistingCartItem, getSelectedProductVariant, addSelectedtedVariantToCart * * @param cart - The cart object * @param product - The product with selectedVariantValues set * @returns The matching order line item, or undefined if not found * * @example * ```typescript * import { cartStore, findExistingCartItemWithProduct } from "@ikas/bp-storefront"; * import { IkasProduct } from "@ikas/bp-storefront"; * * function isProductInCart(product: IkasProduct): boolean { * if (!cartStore.cart) return false; * return !!findExistingCartItemWithProduct(cartStore.cart, product); * } * ``` */ export declare function findExistingCartItemWithProduct(cart: IkasCart, product: IkasProduct): IkasOrderLineItem | undefined; /** * Apply a coupon code to the cart. * * @ai-category Cart * @ai-related removeCouponCode * * @param cart - The cart object * @param couponCode - The coupon code to apply (or null to remove) * @returns Result with success flag * * @example * ```typescript * import { cartStore, saveCouponCode } from "@ikas/bp-storefront"; * * async function handleApplyCoupon(code: string) { * if (!cartStore.cart) return; * * const result = await saveCouponCode(cartStore.cart, code); * if (result.success) { * showToast("Coupon applied!"); * } else { * showToast("Invalid coupon code"); * } * } * ``` */ export declare function saveCouponCode(cart: IkasCart, couponCode?: string | null): Promise; /** * Remove the applied coupon code from the cart. * * @ai-category Cart * @ai-related saveCouponCode * * @param cart - The cart object * @returns Result with success flag * * @example * ```typescript * import { cartStore, removeCouponCode } from "@ikas/bp-storefront"; * * async function handleRemoveCoupon() { * if (!cartStore.cart) return; * * const result = await removeCouponCode(cartStore.cart); * if (result.success) { * showToast("Coupon removed"); * } * } * ``` */ export declare function removeCouponCode(cart: IkasCart): Promise; /** * Remove a gift card (or store credit) line from the cart. * * Gift cards are applied through `saveCouponCode` with the gift card code, and the applied * cards are listed on `cart.giftCardLines`. Pass the `giftCardId` of the line to remove; when * omitted, every gift card line is removed from the cart. * * @ai-category Cart * @ai-related saveCouponCode, getIkasOrderGiftCardTotalPrice * * @param cart - The cart object * @param giftCardId - The gift card to remove, or null/undefined to remove all of them * @returns Result with success flag * * @example * ```typescript * import { cartStore, removeGiftCardLine } from "@ikas/bp-storefront"; * * async function handleRemoveGiftCard(giftCardId: string) { * if (!cartStore.cart) return; * * const result = await removeGiftCardLine(cartStore.cart, giftCardId); * if (result.success) { * showToast("Gift card removed"); * } * } * ``` */ export declare function removeGiftCardLine(cart: IkasCart, giftCardId?: string | null): Promise; /** * Fetch the cart from the API and persist it to the cart store. * Resolves the cart using the localStorage cart ID or the logged-in customer ID. * If the API returns no cart, the local cart is removed. * * @ai-category Cart * @ai-related setCart, removeCart, waitForCartStoreInit * * @returns void (updates cartStore and localStorage as side effects) * * @example * ```typescript * import { getCart, cartStore } from "@ikas/bp-storefront"; * * async function refreshCart() { * await getCart(); * console.log("Cart items:", cartStore.cart?.orderLineItems.length ?? 0); * } * ``` */ export declare function getCart(): Promise; /** * Filter product offers to find those selected by the customer but not yet accepted in the cart. * Used internally when adding or updating cart items to include pending campaign offers. * * @ai-category Cart * @ai-related addItemToCart, changeItemQuantity, isProductOfferAccepted * * @param offers - Array of product offers from the product * @returns Array of accepted offer inputs for the cart API, or undefined if none * * @example * ```typescript * import { getAcceptedOffers } from "@ikas/bp-storefront"; * import { IkasProduct } from "@ikas/bp-storefront"; * * function getPendingOffers(product: IkasProduct) { * const pending = getAcceptedOffers(product.offers); * console.log("Offers to apply:", pending?.length ?? 0); * return pending; * } * ``` */ export declare function getAcceptedOffers(offers: IkasProductOffer[]): { campaignOfferId: string; campaignOfferProductId: string; productId: string; quantity: number | undefined; variantId: string; }[] | undefined; /** * Creates a new temporary cart with the given product and initiates a Pay with ikas session. * This does not affect the user's current cart in localStorage or the CartStore. * * @ai-category Cart, Checkout * @ai-related addItemToCart, getSelectedProductVariant * * @param cartStore - The cart store instance (accepted for interface consistency) * @param product - The product to purchase via fast checkout * @param quantity - The quantity to purchase (defaults to 1) * @returns PayWithIkasResult with the session URL or error * * @example * ```typescript * import { cartStore, createPayWithIkasSession } from "@ikas/bp-storefront"; * import { IkasProduct } from "@ikas/bp-storefront"; * * async function handleBuyNow(product: IkasProduct) { * const result = await createPayWithIkasSession(cartStore, product, 1); * if (result.success && result.payUrl) { * window.location.href = result.payUrl; * } else { * showToast(result.error ?? "Checkout failed"); * } * } * ``` */ export declare function createPayWithIkasSession(cartStore: IkasCartStore, product: IkasProduct, quantity?: number): Promise<{ success: boolean; error: string; payUrl?: undefined; expiresAt?: undefined; } | { success: boolean; payUrl: string; expiresAt: number; error?: undefined; }>; /** * Persist a cart to localStorage and update the cart store. * Saves the cart ID to localStorage under the cart key and sets the cart on the store. * * @ai-category Cart * @ai-related getCart, removeCart, hasCart * * @param cart - The cart object returned from the API * @returns void * * @example * ```typescript * import { setCart } from "@ikas/bp-storefront"; * import { IkasCart } from "@ikas/bp-storefront"; * * async function handleCartResponse(cart: IkasCart) { * await setCart(cart); * console.log("Cart saved with ID:", cart.id); * } * ``` */ export declare function setCart(cart: IkasCart): Promise; /** * Add an item to the cart using a variant ID directly. * This is the public API intended for external integrations (e.g. custom scripts on the storefront) * that don't have access to full product/variant objects. * * @ai-category Cart * @ai-related addItemToCart, addSelectedtedVariantToCart, changeItemQuantity * * @param input - Object with variantId, quantity, and optional itemId for updating existing items * @returns Result with success flag * * @example * ```typescript * import { windowAddToCart } from "@ikas/bp-storefront"; * * // Add a new item by variant ID * async function addByVariantId(variantId: string) { * const result = await windowAddToCart({ variantId, quantity: 1 }); * if (result.success) { * showToast("Added to cart!"); * } * } * * // Update an existing cart item's quantity * async function updateItemQuantity(itemId: string, variantId: string, quantity: number) { * const result = await windowAddToCart({ itemId, variantId, quantity }); * if (!result.success) { * showToast("Failed to update item"); * } * } * ``` */ export declare function windowAddToCart(input: PublicAddToCartInput): Promise; /** * Check if the cart has any items. * * @ai-category Cart * @ai-related waitForCartStoreInit, getCheckoutUrlFromCartStore * * @param cartStore - The cart store instance * @returns True if cart has items, false otherwise * * @example * ```typescript * import { cartStore, hasCart, waitForCartStoreInit } from "@ikas/bp-storefront"; * * async function showCartBadge() { * await waitForCartStoreInit(cartStore); * * if (hasCart(cartStore)) { * const itemCount = cartStore.cart!.orderLineItems.length; * return itemCount; * } * return 0; * } * ``` */ export declare function hasCart(cartStore: IkasCartStore): boolean; export type IkasCartOperationResult = { success: boolean; validationError?: IkasCartOperationValidationError; response?: APIResponse; }; export type IkasCartOperationValidationError = "INSUFFICIENT_STOCK" | "INVALID_PRODUCT_OPTION_VALUES" | "EMPTY_CART"; export type PublicAddToCartInput = { itemId?: string | null; variantId: string; quantity: number; }; export type AddItemOptions = { /** * When true, skips localStorage operations, existing item lookup, and analytics. * Used for Pay with ikas flow to create a temporary cart without affecting the user's cart. */ isPayWithIkas?: boolean; }; export type PayWithIkasResult = { success: boolean; payUrl?: string; expiresAt?: number; error?: string; };