npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

woo-store-ts-api

v1.0.0

Published

TypeScript client for the WooCommerce Store API (wc/store/v1) — cart, checkout, and storefront catalog. Separate from the admin REST client (woocommerce-rest-ts-api).

Readme

woo-store-ts-api

License: MIT Node.js WooCommerce

TypeScript client for the WooCommerce Store API (wc/store/v1) — headless cart, checkout, and storefront catalog.

Not the admin REST client.
For authenticated back-office operations (wc/v3 + consumer keys / OAuth), use woocommerce-rest-ts-api.
For AI agents over admin REST, use woo-mcp-server.

| Package | Surface | Auth | Typical use | |---------|---------|------|-------------| | woocommerce-rest-ts-api | Admin REST wc/v3 | Consumer key + secret (OAuth) | ERP, ops, inventory, MCP | | woo-store-ts-api | Store API wc/store/v1 | Cart-Token (preferred) or Nonce | Headless storefront, mobile, BFF | | woo-mcp-server | MCP tools → admin REST | Same as admin library | Claude / agents |

Hard rule: this client rejects consumerKey / consumerSecret. Store API identity is session-based only. Do not mix packages into one “god client.”


Table of contents

  1. Install
  2. Quick start
  3. When to use which package
  4. Authentication & session
  5. Constructor options
  6. Endpoint coverage matrix
  7. API reference
  8. End-to-end examples
  9. Types
  10. Errors
  11. Exports
  12. Architecture
  13. Testing & development
  14. Troubleshooting
  15. Official Store API docs
  16. License

Install

pnpm add woo-store-ts-api
# or
npm install woo-store-ts-api
# or
yarn add woo-store-ts-api

Requirements: Node.js ≥ 18. Peer/runtime dependency: axios (bundled as a dependency).

Monorepo (this repo):

pnpm install
pnpm --filter woo-store-ts-api build
import { WooCommerceStoreApi } from "woo-store-ts-api";
// workspace package: packages/store-api

Quick start

import { WooCommerceStoreApi } from "woo-store-ts-api";

const store = new WooCommerceStoreApi({
  url: "https://shop.example",
});

// 1) Bootstrap session — GET /cart; client captures Cart-Token from response headers
await store.ensureSession();

// 2) Storefront catalog (public product shapes — not admin products)
const products = await store.products.list({
  per_page: 10,
  on_sale: true,
});

// 3) Cart mutations return the full cart envelope
const cart = await store.cart.addItem({
  id: products[0]!.id,
  quantity: 1,
  variation: [], // required empty array for simple products
});

console.log(cart.items_count, cart.totals?.total_price);
console.log("Cart-Token", await store.getCartToken());

When to use which package

┌─────────────────────────────────────────────────────────────────┐
│                     Your application                            │
├────────────────────────────┬────────────────────────────────────┤
│  Back-office / ERP / MCP   │  Headless storefront / mobile      │
│  woocommerce-rest-ts-api   │  woo-store-ts-api                  │
│  wc/v3 + CK/CS             │  wc/store/v1 + Cart-Token          │
│  orders, refunds, stock…   │  cart, checkout, catalog           │
└────────────────────────────┴────────────────────────────────────┘

| Need | Use | |------|-----| | Create/update products as admin, list all orders, refunds, system status | woocommerce-rest-ts-api | | Guest cart, add to cart, apply coupon, place order from storefront | woo-store-ts-api | | Claude / agent tools against admin REST | woo-mcp-server | | Both admin and storefront in one app | Two clients, two configs — never one class |


Authentication & session

Store API does not use API keys. Identity is the cart session.

Preferred: Cart-Token (headless)

  1. Call GET /wp-json/wc/store/v1/cart (or store.ensureSession() / store.cart.get()).
  2. WooCommerce returns a Cart-Token response header.
  3. This client stores it and sends Cart-Token: … on later cart/checkout requests.
  4. When a valid Cart-Token is present, Nonce is not required.

Fallback: Nonce (cookie / same-site)

  • Mutating cart + checkout routes may require a Nonce header when not using Cart-Token.
  • Nonce is generated by WordPress (wc_store_api) and rotates on responses.
  • The client absorbs Nonce from every response and will send it if no Cart-Token is set.

What the client does automatically

| Behavior | Detail | |----------|--------| | Capture tokens | Reads Cart-Token / Nonce from every response (case-insensitive) | | Prefer Cart-Token | Request headers: Cart-Token if set, else Nonce | | Persist | Default: in-memory. Inject sessionStore for Redis / cookies / localStorage | | Reject admin keys | Constructor throws if consumerKey or consumerSecret is passed |

Official references:

Restore a previous session

const store = new WooCommerceStoreApi({
  url: "https://shop.example",
  cartToken: process.env.CART_TOKEN, // from cookie / localStorage / Redis
});

Custom session store

import {
  WooCommerceStoreApi,
  type SessionStore,
  type SessionSnapshot,
} from "woo-store-ts-api";

/** Example: persist Cart-Token across HTTP requests in a BFF */
const cookieBackedStore: SessionStore = {
  async get(): Promise<SessionSnapshot> {
    return {
      cartToken: readCookie("wc_cart_token"), // your helper
      nonce: null,
    };
  },
  async set(snapshot: SessionSnapshot): Promise<void> {
    if (snapshot.cartToken) {
      writeCookie("wc_cart_token", snapshot.cartToken);
    }
  },
};

const store = new WooCommerceStoreApi({
  url: "https://shop.example",
  sessionStore: cookieBackedStore,
});

Built-in: MemorySessionStore (default).


Constructor options

new WooCommerceStoreApi({
  /** Store origin (required). Example: https://shop.example */
  url: "https://shop.example",

  /** WordPress REST prefix. Default: "wp-json" */
  wpAPIPrefix: "wp-json",

  /** Store API version path. Default: "wc/store/v1" */
  version: "wc/store/v1",

  /** Request timeout in ms. Default: 30000 */
  timeoutMs: 30_000,

  /** Max in-flight HTTP calls (0 = unlimited). Default: 0 */
  maxConcurrentRequests: 0,

  /** Seed Cart-Token (restore session) */
  cartToken: undefined,

  /** Seed Nonce (cookie-mode fallback) */
  nonce: undefined,

  /** Custom SessionStore implementation */
  sessionStore: undefined,

  /** Inject axios instance (tests / custom agents) */
  axiosInstance: undefined,

  // ❌ consumerKey / consumerSecret — rejected with StoreApiOptionsError
});

Base URL built as:

{url}/{wpAPIPrefix}/{version}/{endpoint}
→ https://shop.example/wp-json/wc/store/v1/cart

Endpoint coverage matrix

Every official Store API route is reachable. First-class resource methods cover the cart/checkout/catalog happy path; everything else uses store.request().

| HTTP | Endpoint | Client API | |------|----------|------------| | GET | /cart | store.cart.get() · store.ensureSession() | | POST | /cart/add-item | store.cart.addItem(input) | | POST | /cart/update-item | store.cart.updateItem({ key, quantity }) | | POST | /cart/remove-item | store.cart.removeItem(key) | | POST | /cart/apply-coupon | store.cart.applyCoupon(code) | | POST | /cart/remove-coupon | store.cart.removeCoupon(code) | | POST | /cart/update-customer | store.cart.updateCustomer(input) | | POST | /cart/select-shipping-rate | store.cart.selectShippingRate(input) | | GET | /cart/items | store.cart.listItems() | | DELETE | /cart/items | store.cart.clearItems() | | GET/POST/PUT/DELETE | /cart/items/:key | store.request(…, "cart/items/{key}") | | GET/POST/DELETE | /cart/coupons | store.request(…, "cart/coupons") | | GET/DELETE | /cart/coupon/:code | store.request(…, "cart/coupon/{code}") | | GET | /checkout | store.checkout.get() | | POST | /checkout | store.checkout.process(payload?) | | PUT | /checkout | store.checkout.update(payload?) | | POST | /checkout/:id | store.checkout.payForOrder(orderId, payload?) | | GET | /order/:id | store.request("GET", "order/{id}") | | GET | /products | store.products.list(params?) | | GET | /products/:id | store.products.get(id) | | GET | /products/collection-data | store.products.collectionData(params?) | | GET | /products/categories | store.products.listCategories(params?) | | GET | /products/tags | store.products.listTags(params?) | | GET | /products/attributes | store.products.listAttributes(params?) | | GET | /products/attributes/:id | store.request("GET", "products/attributes/{id}") | | GET | /products/attributes/:id/terms | store.request("GET", "products/attributes/{id}/terms") | | GET | /products/brands | store.request("GET", "products/brands") | | GET | /products/reviews | store.products.listReviews(params?) | | POST | /batch | store.batch(requests) |

Official endpoint catalog (HTTP semantics, params): docs/STORE_API.md.


API reference

Session helpers on the client

| Method | Returns | Description | |--------|---------|-------------| | ensureSession(force?: boolean) | Promise<StoreCart> | GET /cart if needed; captures Cart-Token. Subsequent calls no-op unless force or token missing | | getCartToken() | Promise<string \| null> | Current Cart-Token | | session | CartSession | Low-level session object (see below) | | request(method, endpoint, opts?) | Promise<StoreApiResponse<T>> | Escape hatch for unmapped routes | | batch(requests) | Promise<unknown> | POST /batch with { requests } body |

request options:

await store.request<StoreProduct[]>("GET", "products", {
  query: { per_page: 5, on_sale: true },
  body: undefined,           // POST/PUT body
  headers: { "X-Custom": "1" },
  skipSessionHeaders: false, // true = do not send Cart-Token / Nonce
});
// → { data, status, headers }

store.sessionCartSession

| Method | Description | |--------|-------------| | getSnapshot() | { cartToken, nonce } from the SessionStore | | getCartToken() | Cart-Token only | | getNonce() | Nonce only | | getRequestHeaders() | { "Cart-Token": … } or { "Nonce": … } (never both; token wins) | | absorbResponseHeaders(headers) | Merge new tokens from a response (used automatically by HTTP layer) | | setCartToken(token \| null) | Manually set / clear Cart-Token | | clear() | Clear both tokens |

Default store: MemorySessionStore. Inject any SessionStore (get / set) for cookies, Redis, etc.


store.cart — cart lifecycle

All mutating cart methods return the full cart object (Store API contract).

| Method | HTTP | Body / notes | |--------|------|----------------| | get() | GET /cart | Bootstrap / read cart | | addItem({ id, quantity, variation?, … }) | POST /cart/add-item | variation defaults to [] for simple products | | updateItem({ key, quantity }) | POST /cart/update-item | Line key from cart.items[].key | | removeItem(key) | POST /cart/remove-item | | | applyCoupon(code) | POST /cart/apply-coupon | | | removeCoupon(code) | POST /cart/remove-coupon | | | updateCustomer({ billing_address?, shipping_address?, … }) | POST /cart/update-customer | Address objects | | selectShippingRate({ package_id, rate_id }) | POST /cart/select-shipping-rate | From cart.shipping_rates | | listItems() | GET /cart/items | Items collection | | clearItems() | DELETE /cart/items | Empty cart |

Variable products — pass attribute pairs:

await store.cart.addItem({
  id: 100, // variation or parent product id per your catalog
  quantity: 1,
  variation: [
    { attribute: "pa_color", value: "blue" },
    { attribute: "pa_size", value: "m" },
  ],
});

store.products — storefront catalog

These are Store API product shapes (StoreProduct), not admin REST Products.

| Method | HTTP | Notes | |--------|------|--------| | list(params?) | GET /products | Pagination, search, filters | | get(id) | GET /products/:id | Single product | | collectionData(params?) | GET /products/collection-data | Aggregations / price ranges | | listCategories(params?) | GET /products/categories | | | listTags(params?) | GET /products/tags | | | listAttributes(params?) | GET /products/attributes | | | listReviews(params?) | GET /products/reviews | |

Common list params (ProductListParams):

| Param | Type | Example | |-------|------|---------| | page | number | 1 | | per_page | number | 20 (max 100) | | search | string | "beanie" | | order | "asc" \| "desc" | "desc" | | orderby | string | "price", "date", "popularity", "rating", "title", … | | category | string | category id | | tag | string | tag id | | type | string | "simple", "variable", "variation", … | | on_sale | boolean | true | | min_price / max_price | string | minor units per store | | stock_status | string | string[] | "instock", "outofstock", … | | featured | boolean | | | slug | string | | | attribute | string | attribute taxonomy / id | | attribute_term | string | term id(s) | | (index signature) | unknown | any extra Store API query param passes through |

const sale = await store.products.list({
  on_sale: true,
  per_page: 20,
  orderby: "price",
  order: "asc",
});

store.checkout — place order

| Method | HTTP | Notes | |--------|------|--------| | get() | GET /checkout | Draft checkout state | | process(payload?) | POST /checkout | Place order / process payment | | update(payload?) | PUT /checkout | Update draft fields | | payForOrder(orderId, payload?) | POST /checkout/:id | Pay for existing order |

Typical CheckoutProcessInput fields:

await store.checkout.process({
  billing_address: {
    first_name: "Jane",
    last_name: "Doe",
    address_1: "123 Main",
    city: "Austin",
    state: "TX",
    postcode: "78701",
    country: "US",
    email: "[email protected]",
  },
  shipping_address: {
    /* same shape */
  },
  payment_method: "bacs", // or cheque, cod, stripe, …
  customer_note: "Leave at door",
  create_account: false,
  payment_data: [
    // gateway-specific key/value pairs when required
  ],
});

Flow that matches Store API practice:

  1. ensureSession() / cart.get()
  2. cart.addItem / coupons / updateCustomer / selectShippingRate
  3. checkout.process({ … })

Low-level request & batch

// Unmapped or experimental routes
const res = await store.request<unknown>("GET", "products/brands", {
  query: { per_page: 50 },
});
console.log(res.status, res.data, res.headers);

// Batch (WC Store API batch envelope)
await store.batch([
  {
    path: "/wc/store/v1/cart/add-item",
    method: "POST",
    body: { id: 26, quantity: 1 },
  },
]);

End-to-end examples

Browse → cart → coupon → shipping → checkout

import { WooCommerceStoreApi, StoreApiError } from "woo-store-ts-api";

const store = new WooCommerceStoreApi({ url: process.env.STORE_URL! });

try {
  await store.ensureSession();

  const [product] = await store.products.list({ per_page: 1, search: "hoodie" });
  if (!product) throw new Error("No product found");

  let cart = await store.cart.addItem({
    id: product.id,
    quantity: 1,
    variation: [],
  });

  cart = await store.cart.applyCoupon("SAVE10").catch((err) => {
    if (err instanceof StoreApiError) console.warn("coupon:", err.message);
    return cart;
  });

  cart = await store.cart.updateCustomer({
    billing_address: {
      first_name: "Ada",
      last_name: "Lovelace",
      address_1: "1 Analytical Engine Way",
      city: "London",
      postcode: "SW1A 1AA",
      country: "GB",
      email: "[email protected]",
    },
    shipping_address: {
      first_name: "Ada",
      last_name: "Lovelace",
      address_1: "1 Analytical Engine Way",
      city: "London",
      postcode: "SW1A 1AA",
      country: "GB",
    },
  });

  const pkg = cart.shipping_rates?.[0];
  const rate = pkg?.shipping_rates?.find((r) => r.selected) ?? pkg?.shipping_rates?.[0];
  if (pkg && rate) {
    cart = await store.cart.selectShippingRate({
      package_id: pkg.package_id,
      rate_id: rate.rate_id,
    });
  }

  const order = await store.checkout.process({
    payment_method: cart.payment_methods?.[0] ?? "bacs",
  });

  console.log("Order", order.order_id, order.status, order.order_key);
  console.log("Persist this token for the shopper:", await store.getCartToken());
} catch (err) {
  if (err instanceof StoreApiError) {
    console.error(err.status, err.code, err.message, err.isSessionError);
  }
  throw err;
}

ESM vs CJS

// ESM
import { WooCommerceStoreApi } from "woo-store-ts-api";

// CJS
const { WooCommerceStoreApi } = require("woo-store-ts-api");
// or
const Store = require("woo-store-ts-api").default;

Admin + Store side by side (correct pattern)

import WooCommerceRestApi from "woocommerce-rest-ts-api";
import { WooCommerceStoreApi } from "woo-store-ts-api";

// Back-office
const admin = new WooCommerceRestApi({
  url: process.env.WC_URL!,
  consumerKey: process.env.WC_KEY!,
  consumerSecret: process.env.WC_SECRET!,
  version: "wc/v3",
});

// Storefront session (no keys)
const storefront = new WooCommerceStoreApi({
  url: process.env.WC_URL!,
});

const adminProduct = await admin.get("products", { id: 34 });
await storefront.ensureSession();
await storefront.cart.addItem({ id: 34, quantity: 1 });

Types

Store domain types are separate from admin models in woocommerce-rest-ts-api. All cart mutations return StoreCart; catalog returns StoreProduct; checkout returns StoreCheckout. Extra WC extension keys are allowed via index signatures ([key: string]: unknown).

Type index

| Type | Role | |------|------| | StoreCart | Full cart envelope (items, totals, shipping_rates, …) | | StoreCartItem | Line item (key, id, quantity, …) | | StoreCartCoupon | Applied coupon | | StoreCartTotals / StoreMoney | Money fields (minor units + currency metadata) | | StoreAddress | Billing / shipping address | | StoreShippingPackage / StoreShippingRate | Shipping selection | | StoreProduct | Storefront product | | StoreProductImage / StoreProductPrices | Media & prices | | StoreCheckout | Checkout / order result | | AddToCartInput | addItem payload | | UpdateCartItemInput | updateItem payload | | UpdateCustomerInput | Address update | | SelectShippingRateInput | Shipping selection | | CheckoutProcessInput | Checkout POST/PUT body | | ProductListParams | Catalog filters | | StoreApiResponse<T> | { data, status, headers } for request() | | SessionSnapshot / SessionStore | Session persistence contract | | WooCommerceStoreApiOptions | Constructor options | | StoreApiVersion | "wc/store/v1" \| string |

import type {
  StoreCart,
  StoreProduct,
  CheckoutProcessInput,
  SessionStore,
} from "woo-store-ts-api";

StoreCart (cart envelope)

| Field | Notes | |-------|--------| | items | StoreCartItem[] — each has key (line id for update/remove) | | coupons | StoreCartCoupon[] | | totals | StoreCartTotals — amounts as strings in minor units + currency meta | | shipping_address / billing_address | StoreAddress | | shipping_rates | StoreShippingPackage[] → nested shipping_rates[] with rate_id, selected | | payment_methods | Available gateways for this cart | | needs_payment / needs_shipping | Booleans | | items_count / items_weight | Aggregates | | errors / extensions | Validation / plugin data |

Money note: totals.total_price is a string in the store’s minor unit (e.g. cents). Use totals.currency_minor_unit to format.

StoreCartItem

| Field | Notes | |-------|--------| | key | Required for updateItem / removeItem | | id | Product or variation id | | quantity | Current qty | | variation | Selected attributes | | prices / totals | Line money objects | | quantity_limits | { minimum, maximum, multiple_of, editable } |

StoreProduct (storefront — not admin)

| Field | Notes | |-------|--------| | id, name, slug, type, permalink | Identity | | prices | StoreProductPrices (price, regular_price, sale_price, currency meta) | | on_sale, is_purchasable, is_in_stock | Commerce flags | | images | StoreProductImage[] | | categories / tags / brands | Taxonomies | | attributes, variations, has_options | Variable products | | add_to_cart | { text, url, minimum, maximum, multiple_of } |

StoreCheckout

| Field | Notes | |-------|--------| | order_id, order_key, status | Placed order | | billing_address / shipping_address | Addresses on the order | | payment_method | Gateway id | | payment_result | { payment_status, payment_details, redirect_url } | | customer_id, customer_note | Account / notes |

Input payloads

// AddToCartInput
{ id: number; quantity: number; variation?: { attribute: string; value: string }[]; ... }

// UpdateCartItemInput
{ key: string; quantity: number }

// UpdateCustomerInput
{ billing_address?: Partial<StoreAddress>; shipping_address?: Partial<StoreAddress>; ... }

// SelectShippingRateInput
{ package_id: number | string; rate_id: string }

// CheckoutProcessInput
{
  billing_address?: Partial<StoreAddress>;
  shipping_address?: Partial<StoreAddress>;
  payment_method?: string;
  customer_note?: string;
  create_account?: boolean;
  payment_data?: { key: string; value: string }[];
  extensions?: Record<string, unknown>;
}

// StoreAddress
{
  first_name?, last_name?, company?,
  address_1?, address_2?, city?, state?, postcode?, country?,
  email?, phone?
}

Errors

| Class | When | |-------|------| | StoreApiOptionsError | Bad constructor options (missing url, illegal path, admin keys passed) | | StoreApiError | HTTP ≥ 400 or transport failure |

StoreApiError fields:

| Field | Meaning | |-------|---------| | message | Human-readable | | status | HTTP status if any | | code | WooCommerce / WP error code | | data | Raw error payload | | isSessionError | Hint to re-bootstrap session (nonce / 401 / 403 / token issues) |

import { StoreApiError, isSessionRelatedCode } from "woo-store-ts-api";

try {
  await store.cart.addItem({ id: 1, quantity: 1 });
} catch (e) {
  if (e instanceof StoreApiError && e.isSessionError) {
    await store.ensureSession(true);
    // retry once…
  }
}

Exports

// Client
import WooCommerceStoreApi, {
  WooCommerceStoreApi,
  type WooCommerceStoreApiOptions,
} from "woo-store-ts-api";

// Session
import {
  CartSession,
  MemorySessionStore,
  type SessionStore,
  type SessionSnapshot,
} from "woo-store-ts-api";

// Errors
import {
  StoreApiError,
  StoreApiOptionsError,
  isSessionRelatedCode,
} from "woo-store-ts-api";

// Resources (advanced)
import {
  CartResource,
  ProductsResource,
  CheckoutResource,
} from "woo-store-ts-api";

Architecture

WooCommerceStoreApi
├── session: CartSession → SessionStore (Memory by default)
├── cart: CartResource
├── products: ProductsResource
├── checkout: CheckoutResource
└── http: StoreHttpClient
        ├── builds /wp-json/wc/store/v1/*
        ├── injects Cart-Token | Nonce
        ├── absorbs tokens from response headers
        ├── concurrency throttle (optional)
        └── NO oauth-1.0a / NO consumer keys

Intentionally not shared with the admin package:

  • Auth stack (OAuth vs session headers)
  • Domain types (admin product ≠ store product)
  • MCP tool registry

OK to mirror (duplicated small utils): URL sanitize, concurrency throttle — not a shared runtime dependency on woocommerce-rest-ts-api.

Package layout:

packages/store-api/
  src/
    client.ts
    session.ts
    http.ts
    types.ts
    errors.ts
    utils.ts
    resources/
      cart.ts
      products.ts
      checkout.ts
    index.ts
  tests/
  README.md

Testing & development

# from monorepo root
pnpm install
pnpm --filter woo-store-ts-api build
pnpm --filter woo-store-ts-api typecheck
pnpm --filter woo-store-ts-api test          # Jest + nock, coverage thresholds
pnpm test:store                              # same, via root script

Unit tests cover:

  • Session header preference (Cart-Token over Nonce)
  • Token capture from response headers (case-insensitive)
  • Cart mutations, products list/get, checkout process
  • Rejection of admin credentials (consumerKey / consumerSecret)
  • StoreApiError session flags on 403/nonce failures
  • URL / version / endpoint sanitization
  • Optional concurrency throttle

Coverage thresholds are enforced in jest.config.cjs (statements/branches/functions/lines).


Troubleshooting

| Symptom | Cause | Fix | |---------|-------|-----| | Constructor throws about consumerKey | Admin keys passed into Store client | Use woocommerce-rest-ts-api for admin; Store client takes url only | | 403 / woocommerce_rest_invalid_nonce | Missing or stale Nonce without Cart-Token | Call ensureSession() first; prefer Cart-Token; or ensureSession(true) and retry | | isSessionError === true | Token/nonce/auth failure | await store.ensureSession(true) then retry the mutation once | | Cart empty after process restart | Default MemorySessionStore | Persist via sessionStore or seed cartToken | | 404 on /wp-json/wc/store/v1/… | Pretty permalinks off or WC Blocks Store API disabled | Enable permalinks; update WooCommerce | | Wrong product shape vs admin docs | Store product ≠ admin product | Use StoreProduct types / this package’s docs | | Need brands / order by key / coupon collection | No dedicated method yet | store.request("GET", "products/brands") etc. (see coverage matrix) | | Amounts look 100× too large | Minor units | Divide by 10 ** (totals.currency_minor_unit ?? 2) |


Official Store API docs

| Topic | URL | |-------|-----| | Overview | https://developer.woocommerce.com/docs/apis/store-api/ | | Cart tokens | https://developer.woocommerce.com/docs/apis/store-api/cart-tokens/ | | Nonce tokens | https://developer.woocommerce.com/docs/apis/store-api/nonce-tokens/ | | Cart endpoints | https://developer.woocommerce.com/docs/apis/store-api/resources-endpoints/cart/ | | Checkout | https://developer.woocommerce.com/docs/apis/store-api/resources-endpoints/checkout/ | | Products | https://developer.woocommerce.com/docs/apis/store-api/resources-endpoints/products/ | | Monorepo reference | docs/STORE_API.md | | Issue / design | GitHub #62 |


License

MIT © Yuri Lima