Skip to main content
The official PHP SDK (≥ 8.1): any PSR-18 HTTP client (Guzzle by default), PSR-4, readonly DTOs, PHPStan level 8. Mirrors @itemshop/sdk in TypeScript.

Installation

Storefront (public, no secrets)

Checkout

Your site never touches payment data: checkout->create() returns a redirectUrl (the gateway, or the shop’s status page for a free order). The SDK adds a random Idempotency-Key and retries network failures with the same key, so a flaky connection never creates two orders. A cart has 1–20 lines; two or more form one payment group (->groupId, ->orderIds).
Typed models work too (new StorefrontCheckoutDto(items: [new StorefrontCartItemDto(productId: …)], …)). Keep your own key (idempotencyKey:) with the cart in the session to stay idempotent across requests; Storefront::newIdempotencyKey() generates a valid one.

Vouchers and widgets

A widget the shop owner switched off returns empty data.

Client (API key, server-side)

Create a key in the panel under Settings → API keys with only the permissions you need. See API with a key.
Resources: shops, team, servers, products, paymentMethods, blacklist, discounts, vouchers, stats, uploads, orders, paymentErrors, site (files, draft, revisions, builds, deployments), templates, agents, skills. AI Workspace settings and tokens are panel-only, so they are not part of this client.

Site: deploy from CI

Errors

Every exception extends ItemShop\Exception\ItemShopException and carries an always-set $errorCode (UPPER_SNAKE_CASE): the backend’s code when it sent one, otherwise one derived from the status, otherwise an SDK code (NETWORK_ERROR, TIMEOUT, CONFIG_ERROR, VALIDATION_FAILED). $status is 0 when no response arrived.

Retries, timeouts, HTTP client

GET requests and writes carrying an Idempotency-Key (checkout) are retried on network errors and 408/425/429/500/502/503/504; any other write only on 429. Backoff is exponential from 300 ms, capped at 5 s, with jitter, honouring Retry-After.

Webhooks

The backend does not send signed outgoing webhooks yet (orders reach Discord and the game plugin directly) — see Webhooks. Webhook implements the planned Standard Webhooks scheme (webhook-id, webhook-timestamp, webhook-signature: v1,<base64 HMAC-SHA256>), so you can write the receiver today.

Models

Models live in ItemShop\Model as final classes with public readonly properties, generated from OpenAPI. Model::fromArray() hydrates the camelCase wire format; ->toArray() / json_encode($model) turns it back. Fields unknown to the SDK are kept in $model->extra.

Storefront API

The endpoints under the SDK.

Errors and limits

Error codes and rate limits.