Store Hugs Developers

Carts and checkout

Make and fill a cart, estimate shipping and hand it to the shop's checkout page with a single-use link.

A cart is named by its token. Make one with createCart, keep its cartToken, and reach it again with cart. The CartSession that cart returns sends the token as the X-Cart-Token header for you. Every change answers with the whole cart, with its lines, totals and coupon.

Each write takes $idempotencyKey last: your own Idempotency-Key, or false for none. One is made for you when null (see retries).

Create a cart

$storefront->createCart(string|false|null $idempotencyKey = null): array

A new empty cart, named by the returned cartToken. Keep the token, in the shopper's session or a cookie, to come back to the cart. Made on a client with a shopper's access token, the cart is theirs and priced for them. Limited like cart writes (30 a minute, 300 an hour per visitor).

Parameters

Parameter Type
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none. One is made for you when null.

Returns

The new Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404Not found, or the shop's plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

$cart = $storefront->createCart();
$request->session()->put('cartToken', $cart['cartToken']);

Open a cart

$storefront->cart(string $cartToken): CartSession

A CartSession for the cart a token names. Its methods below act on that cart, and its token property holds the token.

Parameters

Parameter Type
$cartToken string The cart's token.

Returns

A CartSession. No request is made.

Example

$session = $storefront->cart($cart['cartToken']);

Get the cart

$session->get(): array

The cart as it is now, priced as the shop's own cart page prices it.

Returns

A Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled: this shop takes no orders through a cart.
429Rate limited.

Example

$cart = $session->get();

Add a product

$session->addItem(int $productId, int $quantity = 1, string|false|null $idempotencyKey = null): array

Adds a product, or more of one already in the cart. No stock is held until the cart is claimed at checkout. Limited like cart writes.

Parameters

Parameter Type
$productId int The product's id.
$quantity int How many, from 1 to 10000. Default 1.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Returns

The changed Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422cart_change_refused with the shopper-worded reason (out of stock…), validation errors, or an idempotency refusal.
429Rate limited.

Example

$cart = $session->addItem(12, 2);

Change a line's quantity

$session->updateItem(int $itemId, int $quantity, string|false|null $idempotencyKey = null): array

Sets a line's quantity. A quantity of 0 removes the line. Limited like cart writes.

Parameters

Parameter Type
$itemId int The cart line's id (items[].id).
$quantity int The new quantity, from 0 to 10000.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Returns

The changed Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422cart_change_refused with the shopper-worded reason (out of stock…), validation errors, or an idempotency refusal.
429Rate limited.

Example

$cart = $session->updateItem($cart['items'][0]['id'], 3);

Remove a line

$session->removeItem(int $itemId, string|false|null $idempotencyKey = null): array

Removes a line from the cart.

Parameters

Parameter Type
$itemId int The cart line's id (items[].id).
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Returns

The changed Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422cart_change_refused with the shopper-worded reason (out of stock…), validation errors, or an idempotency refusal.
429Rate limited.

Example

$cart = $session->removeItem($cart['items'][0]['id']);

Apply a coupon

$session->applyCoupon(string $code, string|false|null $idempotencyKey = null): array

Checked as the shop's own cart page checks it. A coupon only a known customer can use (first order, per customer) stays on the cart for checkout to decide. Limited to 10 attempts a minute and 60 an hour per visitor.

Parameters

Parameter Type
$code string The coupon code, up to 50 characters, any case.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Returns

The changed Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422The code is unknown or can't be used (errors.code), or an idempotency refusal.
429Rate limited.

Example

$cart = $session->applyCoupon('WELCOME10');

Remove the coupon

$session->removeCoupon(string|false|null $idempotencyKey = null): array

Removes the cart's coupon. Removing an auto-applied coupon stops coupons auto-applying to this cart.

Parameters

Parameter Type
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Returns

The changed Cart array:

FieldTypeDescription
cartTokenstringSend it as X-Cart-Token.
modestringenquiry: a wholesale member's cart, sent to the shop as a quotation request. One of checkout, enquiry.
customerIdinteger or nullThe shopper the cart belongs to; null for a guest cart.
itemsarray of CartItem
items[].idinteger
items[].productIdinteger
items[].slugstring or null
items[].titlestring or null
items[].imagestring (uri) or null
items[].quantityinteger
items[].unitPriceMoneyFields: amount, currency, formatted.
items[].lineTotalMoneyFields: amount, currency, formatted.
totalQuantityinteger
subtotalMoneyFields: amount, currency, formatted.
discountMoneyFields: amount, currency, formatted.
couponobject or null
coupon.codestring
coupon.autoAppliedboolean
couponErrorstring or nullWhy the coupon on the cart doesn't apply now.
offersarray of stringLabels of the offers applied.
taxAddedMoneyFields: amount, currency, formatted.
taxIncludedMoneyFields: amount, currency, formatted.
totalBeforeShippingMoneyFields: amount, currency, formatted.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422cart_change_refused with the shopper-worded reason (out of stock…), validation errors, or an idempotency refusal.
429Rate limited.

Estimate shipping

$session->estimateShipping(array $destination, string|false|null $idempotencyKey = null): array

The shipping rules the shopper could choose at checkout, priced for a destination as checkout prices them. Only when the shop turned its shipping calculator on (shippingEstimates from shop()). A shop without zones ships anywhere, free. Limited to 30 a minute and 300 an hour per visitor.

Parameters

Parameter Type
$destination array The destination's fields, below.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Request fields

FieldTypeDescription
shippingCountryCode requiredstringISO 3166-1 alpha-3. At most 3 characters.
shippingCitystring or nullAt most 100 characters.
shippingStatestring or nullAt most 255 characters.
shippingPostalCodestring or nullAt most 50 characters.
shippingAddressLine1string or nullAt most 1000 characters.
shippingStateIdinteger or null
shippingCityIdinteger or null
shippingNeighbourhoodIdinteger or null
shippingLocationUnlistedboolean or null

Returns

A ShippingEstimate array:

FieldTypeDescription
shipsTobooleanWhether the shop ships to the country.
shipsFreebooleanTrue for a shop without shipping zones (ships anywhere, free).
quotesarray of objectEmpty for an empty or digital-only cart.
quotes[].methodIdinteger
quotes[].namestring
quotes[].costnumberA plain amount in the shop's base currency (not a Money object).
quotes[].isLiveRateboolean
quotes[].isCarrierPriceboolean

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404shipping_estimates_off, cart_not_found, or the shop's plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422Validation errors ({ message, errors }), or an idempotency refusal(idempotency_key_reused, idempotency_key_invalid).
429Rate limited.

Example

$estimate = $session->estimateShipping([
    'shippingCountryCode' => 'SAU',
    'shippingCity' => 'Riyadh',
]);

if ($estimate['shipsTo']) {
    foreach ($estimate['quotes'] as $quote) {
        echo $quote['name'], ': ', $quote['cost'], PHP_EOL;
    }
}

Get a checkout link

$session->checkout(array $options = [], string|false|null $idempotencyKey = null): array

A single-use link to the shop's checkout page with this cart, valid for 30 minutes, for the shopper's browser to open now. Once opened, the cart belongs to that browser and the token no longer reaches it. When requiresSignIn is true, the cart belongs to a shopper, who must be signed in on the shop. A wholesale member's cart (mode enquiry) leads to the shop's cart page, where it is sent as a quotation request. Limited like cart writes.

Parameters

Parameter Type
$options array The checkout's fields, below.
$idempotencyKey string|false|null Your own Idempotency-Key, or false for none.

Request fields

FieldTypeDescription
returnPathstring or nullPath on the shop's site (Settings → Integration API) the receipt's "Continue shopping" links to. Starts with a single /. At most 500 characters.
cartPathstring or nullPath on the shop's site checkout's back link leads to. Starts with a single /. At most 500 characters.
attributionobject or nullThe visit's UTM tags and click ids, recorded when the link is opened.
attribution.utmSourcestring or nullAt most 255 characters.
attribution.utmMediumstring or nullAt most 255 characters.
attribution.utmCampaignstring or nullAt most 255 characters.
attribution.fbclidstring or nullAt most 255 characters.
attribution.gclidstring or nullAt most 255 characters.
attribution.gbraidstring or nullAt most 255 characters.
attribution.wbraidstring or nullAt most 255 characters.
attribution.dclidstring or nullAt most 255 characters.
attribution.msclkidstring or nullAt most 255 characters.
attribution.ttclidstring or nullAt most 255 characters.
attribution.liFatIdstring or nullAt most 255 characters.
attribution.twclidstring or nullAt most 255 characters.

Returns

A CheckoutLink array:

FieldTypeDescription
checkoutUrlstring (uri)Open it in the shopper's browser. Single use.
expiresAtstring (date-time)
modestringOne of checkout, enquiry.
requiresSignInbooleanThe browser must be signed in on the checkout host as the cart's owner.

Errors

StatusWhen
401invalid_api_key: no active Storefront key of this shop, or invalid_customer_token: a bearer token not valid for this shop.
402The shop is suspended (message only).
403origin_not_allowed (publishable key from an unlisted site), secret_key_in_browser, or the shop is not live (message only).
404cart_not_found: the token names no open cart of this shop (opened at checkout, checked out, or another's), or the plan has no Integration API.
409cart_disabled, or idempotency_in_progress.
422Invalid paths or attribution, cart_empty, or an idempotency refusal.
429Rate limited.

Example

$link = $session->checkout([
    'returnPath' => '/thanks',
    'cartPath' => '/cart',
    'attribution' => ['utmSource' => 'newsletter', 'utmCampaign' => 'november'],
]);

return redirect()->away($link['checkoutUrl']);