Back to Arky

E-shop

Products, services, providers, orders, checkout, and payment processing

The E-shop module provides complete commerce functionality including product management, service scheduling, carts, order processing, and checkout.

For storefronts, prefer the high-level store from arky-sdk/storefront. It wraps the lower-level methods on this page and keeps CMS state, e-shop state, contact session, cart, quote, checkout, and scheduled service state in one reactive API.

import { initialize } from 'arky-sdk/storefront';

const arky = initialize({ baseUrl, storeId, market: 'us', locale: 'en' });

await arky.eshop.cart.load();
await arky.eshop.cart.addProduct(product, variant, 1);
const quote = await arky.eshop.cart.quote();
const order = await arky.eshop.cart.checkout({ payment_method_key: 'cash' });

Products

Create Product

POST /v1/stores/{storeId}/products
SDK: sdk.eshop.product.create()

Create a new product. New products start in the active state.

const result = await sdk.eshop.product.create({
key: 'premium-widget',
slug: { en: 'premium-widget' },
taxonomies: [
  { taxonomy_id: 'tax_category', entry_ids: ['ent_widgets'] }
],
blocks: [
  {
    key: 'details',
    type: 'TEXT',
    content: {
      body: { en: 'Product specifications...' }
    }
  }
],
variants: [
  {
    sku: 'WIDGET-SM',
    prices: [{ market: 'USD', amount: 2999 }],
    inventory: [{ location_id: 'loc_warehouse', available: 100 }],
    attributes: [],
    weight: 500
  },
  {
    sku: 'WIDGET-LG',
    prices: [{ market: 'USD', amount: 3999 }],
    inventory: [{ location_id: 'loc_warehouse', available: 50 }],
    attributes: [],
    weight: 750
  }
]
});

Parameters

Name Type Description
key required string Unique product key identifier
slug optional Record<string, string> Locale-keyed URL slugs (e.g., {en: 'my-product'})
blocks optional Block[] Content blocks for product details
taxonomies optional TaxonomyEntry[] Taxonomy entries the product belongs to (category, collection, etc.)
variants optional Variant[] Product variants (sku, prices, inventory, attributes, weight)

Get Product

GET /v1/stores/{storeId}/products/{id}
SDK: sdk.eshop.product.get()

Retrieve a product by ID or slug.

// By ID
const result = await sdk.eshop.product.get({
  id: 'prod_xyz789'
});

// By slug (locale-aware)
const result = await sdk.eshop.product.get({
  slug: 'premium-widget'
});

Parameters

Name Type Description
id optional string Product ID (use this OR slug)
slug optional string Product slug (locale-aware lookup)

List Products

GET /v1/stores/{storeId}/products
SDK: sdk.eshop.product.find()

List products with filtering and pagination.

const result = await sdk.eshop.product.find({
ids: ['prod_1', 'prod_2'],
taxonomyQuery: [
  { taxonomy_id: 'tax_category', entry_ids: ['ent_widgets'] }
],
match_all: true,
status: 'active',
query: 'premium',
sort_field: 'created_at',
sort_direction: 'desc',
cursor: null,
limit: 20,
created_at_from: 1704067200,
created_at_to: 1706745600
});

const { items, cursor } = result;
items.forEach(product => {
console.log(product.key, product.variants);
});

Parameters

Name Type Description
ids optional string[] Filter by specific product IDs
taxonomy_query optional TaxonomyQuery[] Filter by taxonomy entries (category, collection, etc.)
match_all optional boolean If true, match all taxonomy filters (AND); if false, match any (OR)
status optional active | draft | archived Filter by product status
query optional string Search query in product content
sort_field optional string Sort field (createdAt, updatedAt, etc.)
sort_direction optional asc | desc Sort direction
cursor optional string Pagination cursor
limit optional number Items per page (max 100)
created_at_from optional number Filter by creation date (Unix timestamp)
created_at_to optional number Filter by creation date (Unix timestamp)

Update Product

PUT /v1/stores/{storeId}/products/{id}
SDK: sdk.eshop.product.update()

Update an existing product. Use status to draft, archive, or re-activate a product.

const result = await sdk.eshop.product.update({
  id: 'prod_xyz789',
  key: 'updated-widget',
  slug: { en: 'updated-widget', es: 'widget-actualizado' },
  taxonomies: [
    { taxonomy_id: 'tax_category', entry_ids: ['ent_widgets', 'ent_sale'] }
  ],
  blocks: [/* updated blocks */],
  variants: [
    {
      id: 'var_existing',
      sku: 'WIDGET-SM-V2',
      prices: [{ market: 'USD', amount: 3499 }],
      inventory: [{ location_id: 'loc_warehouse', available: 150 }],
      attributes: [],
      weight: 500
    }
  ],
  status: 'active'
});

Parameters

Name Type Description
id required string Product ID to update
key optional string Product key identifier
slug optional Record<string, string> Locale-keyed URL slugs
blocks optional Block[] Content blocks
taxonomies optional TaxonomyEntry[] Taxonomy entries the product belongs to
variants optional Variant[] Product variants (id, sku, prices, inventory, attributes, weight)
status optional active | draft | archived Product status

Delete Product

DELETE /v1/stores/{storeId}/products/{id}
SDK: sdk.eshop.product.delete()

Delete a product.

await sdk.eshop.product.delete({
  id: 'prod_xyz789'
});

Services

Services are schedulable catalog items. Providers supply capacity and working rules for those services.

Create Service

POST /v1/stores/{storeId}/services
SDK: sdk.eshop.service.create()
const service = await sdk.eshop.service.create({
  key: 'deep-cleaning',
  slug: { en: 'deep-cleaning' },
  blocks: [/* service content */],
  prices: [{ market: 'USD', amount: 12000 }]
});

List Services

GET /v1/stores/{storeId}/services
SDK: sdk.eshop.service.find()
const { items: services } = await sdk.eshop.service.find({
  query: 'cleaning',
  statuses: ['active'],
  limit: 20
});

Connect Providers

POST /v1/stores/{storeId}/service-providers
SDK: sdk.eshop.service.createProvider()
await sdk.eshop.service.createProvider({
  service_id: service.id,
  provider_id: provider.id,
  working_days: [
    {
      day: 'monday',
      windows: [{ from: '09:00', to: '17:00' }]
    }
  ],
  specific_dates: [],
  durations: [{ duration: 60 }],
  prices: [{ market: 'USD', amount: 12000 }],
  slot_interval: 30
});

Providers

Create Provider

POST /v1/stores/{storeId}/providers
SDK: sdk.eshop.provider.create()
const provider = await sdk.eshop.provider.create({
  key: 'north-team',
  slug: { en: 'north-team' },
  blocks: [/* provider contact */]
});

List Providers

GET /v1/stores/{storeId}/providers
SDK: sdk.eshop.provider.find()
const { items: providers } = await sdk.eshop.provider.find({
  service_id: service.id,
  limit: 20
});

Orders

Carts

POST /v1/storefront/{storeId}/carts/current
SDK: sdk.eshop.cart.current()

Get or create the authenticated contact’s active cart. Orders are created by checking out a cart; every order stores source_cart_id.

const cart = await sdk.eshop.cart.current();

await sdk.eshop.cart.update({
  id: cart.id,
  market: 'us',
  items: [
    { type: 'product', product_id: 'prod_xyz789', variant_id: 'var_small', quantity: 2 },
    {
      type: 'service',
      service_id: 'svc_cleaning',
      provider_id: 'prv_north',
      slots: [{ from: 1780300800, to: 1780304400 }]
    }
  ],
  shipping_address: {
    name: 'Jane Doe',
    street1: '456 Contact Ave',
    city: 'New York',
    state: 'NY',
    postal_code: '10001',
    country: 'US'
  },
  forms: [
    {
      key: 'shipping-notes',
      entries: [{ key: 'note', value: 'Leave at door' }]
    }
  ]
});

const quote = await sdk.eshop.cart.quote({ id: cart.id });
const result = await sdk.eshop.cart.checkout({ id: cart.id, payment_method_key: 'cash' });

Parameters

Name Type Description
id required string Cart ID
market optional string Market key, for example us or eu
items optional CheckoutItem[] Cart items. Product lines use type: 'product', product_id, variant_id, quantity; service appointment lines use type: 'service', service_id, provider_id, slots.
shipping_address optional Address Shipping address
billing_address optional Address Billing address
forms optional FormEntry[] Cart form entries (contact info, notes, etc.)
payment_method_key optional string Market payment method key such as 'cash' or 'credit_card', supplied at checkout or saved on the cart

Get Order

GET /v1/stores/{storeId}/orders/{id}
SDK: sdk.eshop.order.get()

Retrieve an order by ID.

const order = await sdk.eshop.order.get({
  id: 'ord_xyz789'
});

console.log(order.status, order.payment_status, order.fulfillment_status, order.items);

Parameters

Name Type Description
id required string Order ID

List Orders

GET /v1/stores/{storeId}/orders
SDK: sdk.eshop.order.find()

List orders with filtering. Orders keep lifecycle, payment, and fulfillment state separate: status is the order lifecycle, payment_status is derived from order-level payment evidence, and fulfillment_status is derived from product, digital, shipment, and scheduled-service work.

const result = await sdk.eshop.order.find({
contact_id: 'acc_contact123',
statuses: ['confirmed'],
item_statuses: ['confirmed'],
product_ids: ['prod_xyz789'],
service_ids: ['svc_consultation'],
provider_ids: ['provider_123'],
query: '[email protected]',
sort_field: 'created_at',
sort_direction: 'desc',
cursor: null,
limit: 50,
created_at_from: 1704067200,
created_at_to: 1735689600
});

result.items.forEach(order => {
console.log(order.id, order.status, order.payment_status, order.fulfillment_status, order.payment.total);
});

Parameters

Name Type Description
contact_id optional string Filter by contact ID
statuses optional string[] Filter by order lifecycle status: pending, partially_confirmed, confirmed, partially_cancelled, cancelled, completed
item_statuses optional string[] Filter by item status: pending, confirmed, cancelled
product_ids optional string[] Filter by products in order
service_ids optional string[] Filter by scheduled services in order
provider_ids optional string[] Filter by scheduled-service providers in order
verified optional boolean Filter by order verification state
contact_list_id optional string Filter by contact list
query optional string Search query
sort_field optional string Sort field
sort_direction optional asc | desc Sort direction
cursor optional string Pagination cursor
limit optional number Items per page
created_at_from optional number Filter by creation date (Unix timestamp)
created_at_to optional number Filter by creation date (Unix timestamp)

Update Order

PUT /v1/stores/{storeId}/orders/{id}
SDK: sdk.eshop.order.update()

Update an order’s confirmation/cancellation state, addresses, form entries, items, or payment.

// Confirm a pending order
await sdk.eshop.order.update({
id: 'ord_xyz789',
confirm: true
});

// Cancel an order
await sdk.eshop.order.update({
id: 'ord_xyz789',
cancel: true
});

// Update addresses / form entries
await sdk.eshop.order.update({
id: 'ord_xyz789',
shipping_address: {
  name: 'Jane Doe',
  street1: '456 Contact Ave',
  city: 'New York',
  state: 'NY',
  postal_code: '10001',
  country: 'US'
},
forms: [
  { key: 'notes', entries: [{ key: 'note', value: 'Leave at door' }] }
],
items: [
  { product_id: 'prod_xyz', variant_id: 'var_1', quantity: 2 }
]
});

Parameters

Name Type Description
id required string Order ID to update
confirm optional boolean Confirm pending order items when payment rules allow it
cancel optional boolean Cancel the order and release any reserved booking availability when applicable
shipping_address optional Address | null Shipping address (pass null to clear)
billing_address optional Address | null Billing address (pass null to clear)
forms optional FormEntry[] Order form entries
items optional CheckoutItem[] Order items. Product and service appointment lines are both supported.
payment optional Payment Payment object update
Note

status, payment_status, and fulfillment_status are returned on the order. Payment state is order-level and usually advances from checkout/webhooks. Fulfillment summarizes physical shipments, digital access, and scheduled-service work.

Checkout

Cart Quote

POST /v1/storefront/{storeId}/carts/{id}/quote
SDK: sdk.eshop.cart.quote()

Calculate a cart total before checkout. Storefront checkout is cart-backed: update the cart first, then quote or checkout it. The SDK injects storeId and market from the client config.

const cart = await sdk.eshop.cart.current();
await sdk.eshop.cart.update({
id: cart.id,
items: [
  { type: 'product', product_id: 'prod_xyz789', variant_id: 'var_small', quantity: 2 },
  {
    type: 'service',
    service_id: 'svc_cleaning',
    provider_id: 'prv_north',
    slots: [{ from: 1780300800, to: 1780304400 }]
  }
],
payment_method_key: 'credit_card',
shipping_method_id: 'ship_standard',
promo_code: 'SAVE10',
shipping_address: {
  name: 'Jane Doe',
  street1: '456 Contact Ave',
  city: 'New York',
  country: 'US',
  state: 'NY',
  postal_code: '10001'
}
});

const quote = await sdk.eshop.cart.quote({ id: cart.id });

console.log('Subtotal:', quote.subtotal);
console.log('Discount:', quote.discount);
console.log('Shipping:', quote.shipping);
console.log('Tax:', quote.tax);
console.log('Total:', quote.total);

Parameters

Name Type Description
id required string Cart ID to quote
store_id required string Store ID

Cart Checkout

POST /v1/storefront/{storeId}/carts/{id}/checkout
SDK: sdk.eshop.cart.checkout()

Process payment and complete a cart. The SDK injects storeId from the client config. The checkout response includes order_id, order number, a payment_action for any required next action, and the payment object.

const cart = await sdk.eshop.cart.current();
await sdk.eshop.cart.update({
id: cart.id,
items: [
  { type: 'product', product_id: 'prod_xyz789', variant_id: 'var_small', quantity: 2 }
],
shipping_method_id: 'ship_standard',
shipping_address: {
  name: 'Jane Doe',
  street1: '456 Contact Ave',
  city: 'New York',
  state: 'NY',
  postal_code: '10001',
  country: 'US'
},
forms: [
  {
    key: 'contact-info',
    entries: [
      { key: 'email', value: '[email protected]' },
      { key: 'firstName', value: 'John' },
      { key: 'lastName', value: 'Doe' }
    ]
  }
],
promo_code: 'SAVE10'
});

const result = await sdk.eshop.cart.checkout({
id: cart.id,
payment_method_key: 'cash'
});

console.log('Order placed:', result.order_id, result.number);

Parameters

Name Type Description
id required string Cart ID
shipping_method_id optional string Selected shipping method. Required for shipped product carts, not service-only carts.
payment_method_key optional string Market payment method key such as 'cash' or 'credit_card'
confirmation_token_id optional string Stripe confirmation token ID for card checkout. The high-level storefront store creates this through the SDK payment controller.
return_url optional string URL Stripe can return to when a card payment requires redirect-based authentication.
shipping_address optional Address Shipping address
billing_address optional Address Billing address
forms optional FormEntry[] Order form entries (contact info, notes, etc.)
promo_code optional string Applied promo code

Complete Checkout Flow

import { createStripeConfirmationTokenController, initialize } from 'arky-sdk/storefront';

const arky = initialize({ baseUrl, storeId, market: 'us', locale: 'en' });

async function checkout() {
  await arky.eshop.cart.load();

  // 1. Quote the backend cart to show prices
  const quote = await arky.eshop.cart.quote({
    shipping_method_id: selectedShipping,
    shipping_address: shippingAddress,
    forms: [
      {
        key: 'contact',
        entries: [
          { key: 'email', value: contactEmail },
          { key: 'firstName', value: contactFirstName },
          { key: 'lastName', value: contactLastName }
        ]
      }
    ],
    promo_code: promoCodeInput
  });

  if (!quote) throw new Error('Cart quote is unavailable');
  console.log('Total:', quote.payment.total);

  const payment = await createStripeConfirmationTokenController({
    publishableKey: stripePublishableKey,
    element: document.querySelector('#payment-element')!,
    amount: quote.payment.total,
    currency: quote.payment.currency,
  });

  // 2. Checkout with the selected market payment method
  const result = await arky.eshop.cart.checkout({
    payment_method_key: 'credit_card',
    payment,
    billing_details: { email: contactEmail }
  });

  return result.order_id;
}
Tip

Use arky.eshop.cart.quote to show price breakdowns before the contact commits to purchase.

Availability

GET /v1/stores/{storeId}/services/availability
SDK: sdk.eshop.service.getAvailability()

Availability belongs to services because the contact is choosing schedulable service capacity. Checkout still reserves the selected slots on the unified order.

const availability = await sdk.eshop.service.getAvailability({
  service_id: 'svc_cleaning',
  provider_id: 'prv_north',
  from: 1780272000,
  to: 1782864000
});

Parameters

Name Type Description
service_id required string Service to schedule
provider_id optional string Provider to check, or omit to include all eligible providers
from required number Start of the availability window as a Unix timestamp
to required number End of the availability window as a Unix timestamp