Plugin screenshot thumbnail 1/7
Plugin screenshot thumbnail 2/7
Plugin screenshot thumbnail 3/7
Plugin screenshot thumbnail 4/7
Plugin screenshot thumbnail 5/7
Plugin screenshot thumbnail 6/7
Plugin screenshot thumbnail 7/7

Headdy

A token-authenticated headless storefront API for Craft Commerce.

Craft Commerce has exposed products through GraphQL since version 2. It has never exposed a single cart or order mutation — [craftcms/commerce discussion #2350][2350] has been open for years, and the standing advice is to give up on GraphQL for the cart and POST form-encoded requests to actions/commerce/cart/update-cart with a PHP session cookie and a CSRF token.

That works for a Twig site posting to itself. For a Next, Nuxt or Astro front end on another origin it means credentials: 'include', a SameSite policy that survives your CDN, a round trip to fetch a CSRF token, responses shaped like Craft's internal element attributes, and a payment step that is simply unreachable because Craft hashes the return URL into a Twig form your JavaScript cannot produce.

WooCommerce has the Store API and CoCart. Craft has had nothing. Headdy is that layer.

# One request: create a cart with an item in it.
curl -X POST https://example.com/api/storefront/v1/carts \
  -H 'Content-Type: application/json' \
  -H 'X-Headdy-Key: hd_pk_…' \
  -d '{"items":[{"purchasableId":123,"qty":2}]}'
{
  "success": true,
  "cart": {
    "token": "hdc_…",
    "totalQty": 2,
    "lineItems": [{ "id": 456, "sku": "TSHIRT-L", "qty": 2, "total": { "amount": "49.98", "minorUnits": 4998, "currency": "USD", "formatted": "$49.98" } }],
    "totals": { "total": { "amount": "49.98", "minorUnits": 4998, "currency": "USD", "formatted": "$49.98" } }
  }
}

No cookie. No CSRF token. Hold cart.token, send it back as X-Headdy-Cart, and you have a cart.

What you get

  • A REST storefront API — carts, line items, addresses, coupons, shipping methods, checkout, payment, catalog, customer accounts. Versioned at /v1, with a documented JSON contract and stable machine-readable error codes.
  • GraphQL cart mutations — headdyCartCreate, headdyCartAddItem, headdyCartApplyCoupon and the rest, registered on Craft's own GraphQL endpoint. (Pro)
  • Payment that actually works headlessly — including off-site gateways, whose redirect comes back as JSON for your front end to act on rather than as a 302 it cannot follow.
  • Bearer tokens instead of sessions — issued once, stored only as a SHA-256 hash, revocable, and rotated on checkout.
  • Money you can trust — every amount is {amount, minorUnits, currency, formatted}, never a bare float.
  • A configuration check that finds the misconfiguration before your front-end team does.

The one thing worth knowing about the design

services\Carts::update() is the only place a cart changes. Every REST endpoint, every GraphQL mutation and every console command builds a parameter array and hands it to that method. The granular verbs (POST /carts/current/items, PATCH …/items/{id}) exist because they read well — each is a few lines that assembles params and calls update().

So REST and GraphQL cannot drift apart, and there is exactly one place where stock checks, option signatures, recalculation order and validation happen.

Mutations are also applied in a fixed order regardless of the order you wrote them: clear → items → addresses → email → coupon → shipping → gateway → fields. Setting a shipping method before an address exists would pick from an empty option list; applying a coupon before the items are in would not meet the discount's minimum. One big patch and six small ones give the same answer.

Lite

Plus $79/year after one year.

Pro

Plus $159/year after one year.

Installation Instructions

To install this plugin, copy the command above to your terminal.

Reviews

This plugin doesn't have any reviews.

Active Installs
2
Version
5.0.0
License
Craft
Compatibility
Craft 5
Supports GraphQL
Last release
October 3, 2026
Activity (30 days)
0
Closed Issues
0
Open Issues
0
Merged PRs
0
Open PRs