Back to arkyStore.io

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-store. It wraps the lower-level methods on this page and keeps CMS state, e-shop state, profile session, cart, quote, checkout, and scheduled service state in one reactive API.

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

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

await arkyStore.setup({ hydrateCart: true });
await arkyStore.eshop.cart.addProduct(product, variant, 1);
const quote = await arkyStore.eshop.cart.quote();
const order = await arkyStore.eshop.cart.checkout({ payment_method_id: '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 | 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 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 | 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 profile */]
});

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 profile’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 Profile 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_id: 'credit_card' });

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 (profile info, notes, etc.)
payment_method_id optional string Market payment method ID 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.workflow_status, order.total, 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 have two status fields: status (active / archived) for soft archival, and workflow_status for the payment/fulfillment lifecycle.

const result = await sdk.eshop.order.find({
profile_id: 'acc_profile123',
status: 'active',
workflow_status: 'confirmed',
product_ids: ['prod_xyz789'],
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.workflow_status, order.total);
});

Parameters

Name Type Description
profile_id optional string Filter by profile account ID
status optional active | archived Filter by order archival status
workflow_status optional string Filter by workflow status: created, pending, authorized, confirmed, completed, cancelled, failed
product_ids optional string[] Filter by products in order
audience_id optional string Filter by audience
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 archival state, workflow status, addresses, form entries, items, or payment.

// Advance the workflow
await sdk.eshop.order.update({
id: 'ord_xyz789',
workflow_status: 'confirmed'
});

// Archive an order
await sdk.eshop.order.update({
id: 'ord_xyz789',
status: 'archived'
});

// Update addresses / form entries
await sdk.eshop.order.update({
id: 'ord_xyz789',
shipping_address: {
  name: 'Jane Doe',
  street1: '456 Profile 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
status optional active | archived Archival status
workflow_status optional string Workflow status: created, pending, authorized, confirmed, completed, cancelled, failed
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 controls whether the order is visible in the active list or archived. workflow_status drives the payment and fulfillment lifecycle and is usually advanced by the server (checkout, webhooks, etc.).

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_id: 'credit_card',
shipping_method_id: 'ship_standard',
promo_code: 'SAVE10',
shipping_address: {
  name: 'Jane Doe',
  street1: '456 Profile 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 Stripe client_secret (when 3DS or additional confirmation is required), 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 Profile Ave',
  city: 'New York',
  state: 'NY',
  postal_code: '10001',
  country: 'US'
},
forms: [
  {
    key: 'profile-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_id: 'credit_card'
});

if (result.client_secret) {
// Additional confirmation (e.g. 3D Secure) required on the client
const { error } = await stripe.confirmCardPayment(result.client_secret);
if (error) throw new Error(error.message);
}

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_id optional string Market payment method ID such as 'cash' or 'credit_card'
shipping_address optional Address Shipping address
billing_address optional Address Billing address
forms optional FormEntry[] Order form entries (profile info, notes, etc.)
promo_code optional string Applied promo code

Complete Checkout Flow

import { loadStripe } from '@stripe/stripe-js';
import { createArkyStore } from 'arky-sdk/storefront-store';

const stripe = await loadStripe('pk_live_xxx');
const arkyStore = createArkyStore({ baseUrl, storeId, market: 'us', locale: 'en' });

async function checkout() {
  await arkyStore.setup({ hydrateCart: true });

  // 1. Quote the backend cart to show prices
  const quote = await arkyStore.eshop.cart.quote({
    shipping_method_id: selectedShipping,
    shipping_address: shippingAddress,
    forms: [
      {
        key: 'profile',
        entries: [
          { key: 'email', value: profileEmail },
          { key: 'firstName', value: profileFirstName },
          { key: 'lastName', value: profileLastName }
        ]
      }
    ],
    promo_code: promoCodeInput
  });

  console.log('Total:', quote?.payment.total);

  // 2. Checkout with the selected market payment method
  const result = await arkyStore.eshop.cart.checkout({
    payment_method_id: 'credit_card'
  });

  if (result.client_secret) {
    // Handle 3D Secure / additional confirmation
    const { error } = await stripe.confirmCardPayment(result.client_secret, {
      payment_method: {
        card: cardElement,
        billing_details: { email: profileEmail }
      }
    });
    if (error) throw new Error(error.message);
  }

  return result.order_id;
}
Tip

Use arkyStore.eshop.cart.quote to show price breakdowns before the profile commits to purchase.

Availability

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

Availability belongs to services because the profile 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