Back to arkyStore.io

E-commerce Store

Build a cart-first storefront with products, quotes, checkout, and payments

Arky storefronts are cart-first. The browser should not keep its own checkout model in local storage; it should use the SDK storefront store, hydrate the server cart, and let checkout create the order from that cart.

Store Setup

Create one store for the app and call setup when the storefront boots or when locale/market context changes.

import { createArkyStore } from 'arky-sdk/storefront-store';

export const arkyStore = createArkyStore({
  baseUrl: 'https://api.arky.io',
  storeId: import.meta.env.PUBLIC_ARKY_STORE_ID,
  locale: 'en',
  market: 'us',
  marketForLocale: (locale) => (locale === 'it' ? 'ita' : 'us'),
});

await arkyStore.setup({
  locale: 'en',
  hydrateCart: true,
  track: {
    type: 'page_view',
    payload: { path: location.pathname },
  },
});

hydrateCart: true identifies the current profile session and loads the backend cart. Anonymous visitors are still profiles, so the cart is always tied to a profile context.

Product Listing

Use the e-shop module on the store. The call updates arkyStore.eshop.state, so a page can either use the returned value or subscribe to the store state.

const { items: products } = await arkyStore.eshop.product.list({
  limit: 24,
});

const first = products[0];
const variant = first.variants[0];
const price = arkyStore.utils.formatPrice(variant.prices);

Product Detail

Adding a product should update the server cart immediately. The local UI gets refreshed from the cart response.

const product = await arkyStore.eshop.product.loadDetail({ id: productId });
const variant = product.variants[0];

await arkyStore.eshop.cart.addProduct(product, variant, 1);

Cart UI

The cart store exposes Nano Store atoms, so React, Svelte, Vue, Astro islands, or plain browser code can subscribe without a framework-specific adapter.

const unsubscribe = arkyStore.eshop.cart.snapshot.subscribe((snapshot) => {
  console.log(snapshot.item_count);
  console.log(snapshot.product_items);
  console.log(snapshot.service_items);
});

const status = arkyStore.eshop.cart.status.get();
const currentQuote = arkyStore.eshop.cart.quote_result.get();

unsubscribe();

Common cart methods live directly under eshop.cart.

await arkyStore.eshop.cart.setProductQuantity(item.id, 2);
await arkyStore.eshop.cart.removeProduct(item.id);
await arkyStore.eshop.cart.applyPromoCode('SUMMER20');
await arkyStore.eshop.cart.selectShippingMethod('standard');

Quote

Quote calculation also goes through the cart. Pass addresses, promo codes, forms, and shipping method when they are available.

const quote = await arkyStore.eshop.cart.quote({
  shipping_method_id: 'standard',
  promo_code: 'SUMMER20',
  shipping_address: {
    name: 'Jane Doe',
    street1: '456 Profile Ave',
    city: 'New York',
    state: 'NY',
    postal_code: '10001',
    country: 'US',
  },
});

console.log(quote?.payment.total);

Checkout

Checkout creates the order from the cart. Storefronts should not call an order checkout endpoint directly.

const result = await arkyStore.eshop.cart.checkout({
  payment_method_id: 'credit_card',
  shipping_method_id: 'standard',
  shipping_address,
  billing_address,
  forms,
});

if (result.client_secret) {
  await stripe.confirmCardPayment(result.client_secret);
}

console.log(result.order_id, result.number);
Note

For card payments, create the Stripe payment method in your UI, pass its ID as payment_method_id, then confirm the returned client_secret if Stripe requires an additional step.

Mixed Carts

Products and scheduled service lines share the same cart. Product storefronts usually use eshop.cart.addProduct, while service pages can use the service controller and checkout through the same cart.

await arkyStore.eshop.service.initialize();
await arkyStore.eshop.service.select(service);
await arkyStore.eshop.service.findFirstAvailable();

const serviceState = arkyStore.eshop.service.state.get();
await arkyStore.eshop.service.selectTimeSlot(serviceState.slots[0]);
await arkyStore.eshop.service.addToCart();

const order = await arkyStore.eshop.cart.checkout({
  payment_method_id: 'cash',
});

Storefront Rules

  • Use createArkyStore as the storefront integration point.
  • Use the backend cart as the source of truth.
  • Use eshop.cart.quote before presenting totals.
  • Use eshop.cart.checkout to create orders.
  • Use arkyStore.client only for unusual low-level cases that are not represented by the store yet.