Storefront channel — integration guide
Storefront acts on one Areye Business account under that account owner's grant. It never holds the merchant's API key or a platform-wide credential. Every call carries a short-lived token that Storefront signs for that business, that request and that one use.
| Live | Sandbox | |
|---|---|---|
| Base URL | https://api.areye.app/api/internal/channel/storefront |
https://sandbox.areye.app/api/internal/channel/storefront |
Token audience (aud) |
areye |
areye-sandbox |
| Verifying key held by Areye | Storefront's live public key | Storefront's sandbox public key (a different key pair) |
| Grant | enabled by the owner in the business portal, with a code | created with the owner's sandbox credentials (portal → Settings & API → Sandbox), already enabled |
A sandbox token is refused on live, and a live token is refused in the
sandbox, with 401 and code wrong_environment.
The token
A compact JWS signed RS256 with Storefront's private key.
header {"alg":"RS256","typ":"JWT","kid":"<key id: see below>"}
claims {"iss":"storefront","aud":"areye" | "areye-sandbox",
"sub":"<Areye business id>" (or "link" for the sign-in exchange),
"iat":<unix>, "exp":<unix, at most 300 s after iat>,
"jti":"<unique, single use>",
"htm":"POST", "htu":"/api/internal/channel/storefront/deliveries"}
The key id is the first 16 hex characters of the SHA-256 of the public key's DER bytes (RSA, at least 2048 bits). Areye keeps the previous key verifying for 24 hours after a rotation.
Send it as Authorization: Bearer <token>. Areye checks, in order: the
signature against the key named by kid; issuer and audience; the time
window (30 s of clock skew allowed); that htm and htu are this request;
the business's Storefront grant is enabled and the business active; the
action is within the grant's scopes; and that jti has not been used.
Endpoints
| Call | Scope | What it does |
|---|---|---|
POST /link {code} |
token sub: "link" |
The sign-in exchange: returns the business, its owner (first names and surname), the grant's scopes and the webhook secret for this grant (only ever revealed here). |
GET /account |
account.read |
The account and what it may do now (actions.publish/payments/dispatch.allowed and, when not, reason). |
POST /deliveries |
deliveries.book |
Book a delivery. Exactly the POST /business/book contract: same payload, same idempotency on external_reference, same webhooks. type must be parcel. |
GET /deliveries/{reference} |
deliveries.read |
One delivery. |
POST /deliveries/{reference}/cancel |
deliveries.cancel |
Cancel before collection. |
GET /wallet |
wallet.read |
Balance and billing mode. |
Webhooks
trip.* events for deliveries booked through the channel are POSTed to
Storefront's events URL, signed with the grant's webhook secret:
X-Areye-Signature: sha256=HMAC-SHA256(raw body, secret) and
X-Areye-Signature-V2: t=<unix>,sha256=HMAC-SHA256("<t>." + raw body, secret).
Payloads are those of the Business API webhooks,
with "sales_channel": "storefront" in the envelope.
Errors
Every refusal is {"success": false, "code": "...", "message": "..."}:
token_required, malformed, bad_algorithm, unknown_key,
bad_signature, wrong_audience, wrong_environment, missing_claim,
expired, lifetime, not_yet_valid, wrong_request, replayed, no_grant,
grant_disabled, business_inactive, scope_denied, not_verified,
prepaid_only, deliveries_only, plus every booking code listed under
Errors. On live, a booking whose text
starts with a test marker (__TEST, [TEST], …) is refused with
test_booking_refused, and "test": true with test_mode_moved_to_sandbox:
test in the sandbox.
Testing in the sandbox
- The merchant (or Areye, for Storefront's own test account) creates sandbox
credentials in the business portal: Settings & API → Sandbox. The response
includes the sandbox
business_idand the sandbox grant'swebhook_secret; the grant is already enabled. - Storefront signs sandbox tokens with its sandbox key pair and
aud: "areye-sandbox", and sends them to the sandbox base URL. Areye holds the sandbox public key (Areye sets it on its side when Storefront sends it; never the live key). - Drive each delivery through its lifecycle with the simulation endpoints — the real webhooks arrive at Storefront's sandbox events URL.