JavaScript

A tiny client for any website, with no framework.

The API is plain HTTPS and JSON, so fetch is all you need. This small client handles the key, errors and idempotency:

cashiar.js
const BASE = 'https://api.cashiar.app/v1/storefront';

export function cashiar(key) {
  async function call(method, path, body) {
    const res = await fetch(`${BASE}${path}`, {
      method,
      headers: {
        Authorization: `Bearer ${key}`,
        ...(body && {
          'Content-Type': 'application/json',
          'Idempotency-Key': crypto.randomUUID(),
        }),
      },
      body: body && JSON.stringify(body),
    });
    const data = await res.json();
    if (!res.ok) throw Object.assign(new Error(data.message), data);
    return data;
  }
  return {
    shop: () => call('GET', '/shop'),
    products: (query = {}) =>
      call('GET', `/products?${new URLSearchParams(query)}`),
    product: (id) => call('GET', `/products/${id}`),
    order: (order) => call('POST', '/orders', order),
    orderStatus: (id) => call('GET', `/orders/${id}`),
    services: () => call('GET', '/services'),
    freeTimes: (query) => call('GET', `/services/times?${new URLSearchParams(query)}`),
    book: (booking) => call('POST', '/bookings', booking),
  };
}
index.html
<ul id="products"></ul>
<script type="module">
  import { cashiar } from './cashiar.js';

  const api = cashiar('pk_live_your_key');
  const shop = await api.shop();
  const money = (n) =>
    new Intl.NumberFormat(undefined, { style: 'currency', currency: shop.currency }).format(n / 100);

  const { items } = await api.products({ limit: 20 });
  document.querySelector('#products').innerHTML = items
    .map((p) => `<li>${p.name} · ${money(p.versions[0].sellingPrice)}</li>`)
    .join('');
</script>

Idempotency for a retry

The client makes a new Idempotency-Key for each call. To retry a failed order safely, keep the key from the first try and send it again: see Idempotency.