Skip to content

Storefront Checkouts

Storefront

Storefront Checkouts groups 4 operations on the storefront tier.

Storefront tier. Reachable anonymously; a public vnstss_ token may be sent to identify the storefront.

POST

/api/{version}/checkouts

Promote the current visitor's cart into a checkout and return it. Returns 422 when the cart is empty.

AuthenticationAnonymousStorefront tier. Reachable anonymously; a public vnstss_ token may be sent to identify the storefront.

Responses

curl -X POST \
  'https://<your-shop-domain>/api/2026-04-01/checkouts' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer vnstss_<token>'
Response200example shape
{
  "checkout": {
    "id": "00000000-0000-0000-0000-000000000000",
    "currency": "string",
    "is_completed": true,
    "guest_checkout_enabled": true,
    "comments": "string",
    "line_items": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "article_id": "00000000-0000-0000-0000-000000000000",
        "title": "string",
        "sku": "string",
        "quantity": 1,
        "unit_price": 1,
        "unit_price_with_tax": 1,
        "line_total": 1,
        "line_total_with_tax": 1,
        "image_url": "string"
      }
    ],
    "totals": {
      "subtotal": 1,
      "subtotal_before_discount": 1,
      "tax_amount": 1,
      "shipping_amount": 1,
      "shipping_tax_rate": 1,
      "shipping_method_name": "string",
      "discount": 1,
      "coupon_text": "string",
      "total": 1,
      "currency": "string",
      "price_includes_tax": true,
      "tax_lines": [
        {}
      ]
    },
    "shipping_options": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "string",
        "price": "string",
        "expected_delivery_date": "string"
      }
    ],
    "selected_shipping_method_id": "00000000-0000-0000-0000-000000000000",
    "payment_types": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "string",
        "image_url": "string"
      }
    ],
    "selected_payment_type_id": "00000000-0000-0000-0000-000000000000",
    "shipping_address": {
      "id": "00000000-0000-0000-0000-000000000000",
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "department": "string",
      "vat_number": "string",
      "street": "string",
      "po_box": "string",
      "zip_code": "string",
      "location": "string",
      "email": "string",
      "phone_number": "string",
      "mobile_number": "string",
      "country_code": "string",
      "country_name": "string"
    },
    "billing_address": {
      "id": "00000000-0000-0000-0000-000000000000",
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "department": "string",
      "vat_number": "string",
      "street": "string",
      "po_box": "string",
      "zip_code": "string",
      "location": "string",
      "email": "string",
      "phone_number": "string",
      "mobile_number": "string",
      "country_code": "string",
      "country_name": "string"
    },
    "billing_same_as_shipping": true,
    "available_countries": [
      {
        "code": "string",
        "name": "string"
      }
    ],
    "compliance": {
      "terms": {
        "required": true,
        "terms_url": "string",
        "privacy_url": "string"
      },
      "age_verification": {
        "required": true,
        "min_age": 1
      }
    }
  }
}
GET

/api/{version}/checkouts/{token}

Read a checkout by its opaque token. A completed checkout still returns 200 with is_completed: true.

AuthenticationAnonymousStorefront tier. Reachable anonymously; a public vnstss_ token may be sent to identify the storefront.

Path parameters

NameTypeDescription
token
required
string (uuid)
curl -X GET \
  'https://<your-shop-domain>/api/2026-04-01/checkouts/<token>' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer vnstss_<token>'
Response200example shape
{
  "checkout": {
    "id": "00000000-0000-0000-0000-000000000000",
    "currency": "string",
    "is_completed": true,
    "guest_checkout_enabled": true,
    "comments": "string",
    "line_items": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "article_id": "00000000-0000-0000-0000-000000000000",
        "title": "string",
        "sku": "string",
        "quantity": 1,
        "unit_price": 1,
        "unit_price_with_tax": 1,
        "line_total": 1,
        "line_total_with_tax": 1,
        "image_url": "string"
      }
    ],
    "totals": {
      "subtotal": 1,
      "subtotal_before_discount": 1,
      "tax_amount": 1,
      "shipping_amount": 1,
      "shipping_tax_rate": 1,
      "shipping_method_name": "string",
      "discount": 1,
      "coupon_text": "string",
      "total": 1,
      "currency": "string",
      "price_includes_tax": true,
      "tax_lines": [
        {}
      ]
    },
    "shipping_options": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "string",
        "price": "string",
        "expected_delivery_date": "string"
      }
    ],
    "selected_shipping_method_id": "00000000-0000-0000-0000-000000000000",
    "payment_types": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "string",
        "image_url": "string"
      }
    ],
    "selected_payment_type_id": "00000000-0000-0000-0000-000000000000",
    "shipping_address": {
      "id": "00000000-0000-0000-0000-000000000000",
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "department": "string",
      "vat_number": "string",
      "street": "string",
      "po_box": "string",
      "zip_code": "string",
      "location": "string",
      "email": "string",
      "phone_number": "string",
      "mobile_number": "string",
      "country_code": "string",
      "country_name": "string"
    },
    "billing_address": {
      "id": "00000000-0000-0000-0000-000000000000",
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "department": "string",
      "vat_number": "string",
      "street": "string",
      "po_box": "string",
      "zip_code": "string",
      "location": "string",
      "email": "string",
      "phone_number": "string",
      "mobile_number": "string",
      "country_code": "string",
      "country_name": "string"
    },
    "billing_same_as_shipping": true,
    "available_countries": [
      {
        "code": "string",
        "name": "string"
      }
    ],
    "compliance": {
      "terms": {
        "required": true,
        "terms_url": "string",
        "privacy_url": "string"
      },
      "age_verification": {
        "required": true,
        "min_age": 1
      }
    }
  }
}
PUT

/api/{version}/checkouts/{token}

Apply the supplied facets (shipping/billing address, shipping method, payment type, comments) and return the recalculated checkout.

AuthenticationAnonymousStorefront tier. Reachable anonymously; a public vnstss_ token may be sent to identify the storefront.

Path parameters

NameTypeDescription
token
required
string (uuid)

Request body

application/json, text/json, application/*+json · optional

StorefrontCheckoutUpdateRequest

Body of PUT /api/{version}/checkouts/{token}. Every field is optional — only the supplied facets are applied (shipping/billing address, shipping method, payment type, comments).

Responses

curl -X PUT \
  'https://<your-shop-domain>/api/2026-04-01/checkouts/<token>' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer vnstss_<token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "shipping_address": {
    "id": "00000000-0000-0000-0000-000000000000",
    "first_name": "string",
    "last_name": "string",
    "company": "string",
    "department": "string",
    "vat_number": "string",
    "street": "string",
    "po_box": "string",
    "zip_code": "string",
    "location": "string",
    "email": "string",
    "phone_number": "string",
    "mobile_number": "string",
    "country_code": "string",
    "country_name": "string"
  },
  "billing_address": {
    "id": "00000000-0000-0000-0000-000000000000",
    "first_name": "string",
    "last_name": "string",
    "company": "string",
    "department": "string",
    "vat_number": "string",
    "street": "string",
    "po_box": "string",
    "zip_code": "string",
    "location": "string",
    "email": "string",
    "phone_number": "string",
    "mobile_number": "string",
    "country_code": "string",
    "country_name": "string"
  },
  "billing_same_as_shipping": true,
  "shipping_method_id": "00000000-0000-0000-0000-000000000000",
  "payment_type_id": "00000000-0000-0000-0000-000000000000",
  "comments": "string"
}'
Response200example shape
{
  "checkout": {
    "id": "00000000-0000-0000-0000-000000000000",
    "currency": "string",
    "is_completed": true,
    "guest_checkout_enabled": true,
    "comments": "string",
    "line_items": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "article_id": "00000000-0000-0000-0000-000000000000",
        "title": "string",
        "sku": "string",
        "quantity": 1,
        "unit_price": 1,
        "unit_price_with_tax": 1,
        "line_total": 1,
        "line_total_with_tax": 1,
        "image_url": "string"
      }
    ],
    "totals": {
      "subtotal": 1,
      "subtotal_before_discount": 1,
      "tax_amount": 1,
      "shipping_amount": 1,
      "shipping_tax_rate": 1,
      "shipping_method_name": "string",
      "discount": 1,
      "coupon_text": "string",
      "total": 1,
      "currency": "string",
      "price_includes_tax": true,
      "tax_lines": [
        {}
      ]
    },
    "shipping_options": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "string",
        "price": "string",
        "expected_delivery_date": "string"
      }
    ],
    "selected_shipping_method_id": "00000000-0000-0000-0000-000000000000",
    "payment_types": [
      {
        "id": "00000000-0000-0000-0000-000000000000",
        "name": "string",
        "image_url": "string"
      }
    ],
    "selected_payment_type_id": "00000000-0000-0000-0000-000000000000",
    "shipping_address": {
      "id": "00000000-0000-0000-0000-000000000000",
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "department": "string",
      "vat_number": "string",
      "street": "string",
      "po_box": "string",
      "zip_code": "string",
      "location": "string",
      "email": "string",
      "phone_number": "string",
      "mobile_number": "string",
      "country_code": "string",
      "country_name": "string"
    },
    "billing_address": {
      "id": "00000000-0000-0000-0000-000000000000",
      "first_name": "string",
      "last_name": "string",
      "company": "string",
      "department": "string",
      "vat_number": "string",
      "street": "string",
      "po_box": "string",
      "zip_code": "string",
      "location": "string",
      "email": "string",
      "phone_number": "string",
      "mobile_number": "string",
      "country_code": "string",
      "country_name": "string"
    },
    "billing_same_as_shipping": true,
    "available_countries": [
      {
        "code": "string",
        "name": "string"
      }
    ],
    "compliance": {
      "terms": {
        "required": true,
        "terms_url": "string",
        "privacy_url": "string"
      },
      "age_verification": {
        "required": true,
        "min_age": 1
      }
    }
  }
}
POST

/api/{version}/checkouts/{token}/complete

Place the order and initialize payment. Returns { payment_url } for redirect-based providers, or the placed-order identifiers for prepayment / invoice. The success body is StorefrontCheckoutCompleteResponse — the same checkout key as the reads above, but a different payload. A refused consent gate is a 422 carrying code (terms_acceptance_required / age_verification_required), and a checkout that is already completed is a 409.

AuthenticationAnonymousStorefront tier. Reachable anonymously; a public vnstss_ token may be sent to identify the storefront.

Path parameters

NameTypeDescription
token
required
string (uuid)

Request body

application/json, text/json, application/*+json · optional

StorefrontCheckoutCompleteRequest

Body of POST /api/{version}/checkouts/{token}/complete. return_url is where the buyer is redirected after a redirect-based payment provider finishes; it is required for every payment method except prepayment / invoice. Consent.accepted_terms and age_confirmed are attestations by the storefront operator, supplied per call and never stored: send them whenever the checkout's compliance block reports the matching gate as required, or the call is rejected with 422 and a code of terms_acceptance_required / age_verification_required. They are on this request only — a PUT cannot carry consent forward, because nothing is persisted between calls.

  • payment_type_idstring (uuid)required
  • commentsstringnullable
  • return_urlstringnullable
  • accepted_termsbooleannullable

    The buyer accepted the tenant's Terms & Conditions. Required when the checkout's compliance.terms.required is true.

  • age_confirmedbooleannullable

    The storefront confirmed the buyer meets compliance.age_verification.min_age. An attestation, not proof — the storefront operator runs and keeps the record of its own check.

Responses

curl -X POST \
  'https://<your-shop-domain>/api/2026-04-01/checkouts/<token>/complete' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer vnstss_<token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "payment_type_id": "00000000-0000-0000-0000-000000000000"
}'
Response200example shape
{
  "checkout": {
    "success": true,
    "payment_url": "string",
    "order_id": "00000000-0000-0000-0000-000000000000",
    "order_number": "string",
    "hash": "string"
  }
}

Schemas

ApiErrorResponse

The error envelope every non-2xx response from this API uses. Documentation shape: actions build it as an anonymous object, so this type exists to give the OpenAPI document a schema to point at.

  • errorsstringnullable

    Human-readable description of what went wrong, e.g. Not Found, Invalid page_info.

  • codestringnullable

    Machine-readable error code. Only a few endpoints (checkout) emit one; omitted everywhere else.

StorefrontCheckoutAddressDto

  • idstring (uuid)nullable
  • first_namestringnullable
  • last_namestringnullable
  • companystringnullable
  • departmentstringnullable
  • vat_numberstringnullable

    Company VAT / UID number, when the tenant collects one at checkout.

  • streetstringnullable
  • po_boxstringnullable
  • zip_codestringnullable
  • locationstringnullable
  • emailstringnullable
  • phone_numberstringnullable
  • mobile_numberstringnullable
  • country_codestringnullable
  • country_namestringnullable

StorefrontCheckoutAgePolicyDto

  • requiredboolean

    Whether this checkout needs an age attestation. Recomputed on every read — it depends on the cart's products and the delivery country, so it can flip after a PUT that changes the address.

  • min_ageinteger (int32)

    The minimum age the buyer must meet; 0 when no check is required.

StorefrontCheckoutCompleteDto

Result of POST /checkouts/{token}/complete. On success the order identifiers (order_id, order_number, hash) are always set; payment_url is set as well when the chosen method needs the buyer redirected to a provider to pay. Keep order_id and hash before redirecting, and put them on the return_url you hand to complete — the provider brings the buyer back in a fresh document with no client state, and those two are what GET /orders/{id}?hash=… needs to render the receipt.

  • successboolean
  • payment_urlstringnullable
  • order_idstring (uuid)nullable
  • order_numberstringnullable
  • hashstringnullable

StorefrontCheckoutCompleteRequest

Body of POST /api/{version}/checkouts/{token}/complete. return_url is where the buyer is redirected after a redirect-based payment provider finishes; it is required for every payment method except prepayment / invoice. Consent.accepted_terms and age_confirmed are attestations by the storefront operator, supplied per call and never stored: send them whenever the checkout's compliance block reports the matching gate as required, or the call is rejected with 422 and a code of terms_acceptance_required / age_verification_required. They are on this request only — a PUT cannot carry consent forward, because nothing is persisted between calls.

  • payment_type_idstring (uuid)required
  • commentsstringnullable
  • return_urlstringnullable
  • accepted_termsbooleannullable

    The buyer accepted the tenant's Terms & Conditions. Required when the checkout's compliance.terms.required is true.

  • age_confirmedbooleannullable

    The storefront confirmed the buyer meets compliance.age_verification.min_age. An attestation, not proof — the storefront operator runs and keeps the record of its own check.

StorefrontCheckoutCompleteResponse

Envelope returned by POST /checkouts/{token}/complete. Carries a different type under the same checkout key as Cloudwawi.Shop.Api.V2026_04_01.Storefront.StorefrontCheckoutReadResponse: not the checkout itself, but the outcome of placing the order.

StorefrontCheckoutComplianceDto

The consent gates for this checkout. Policy only — the API stores no consent, so there is no "already accepted" state: the client re-attests on every complete call.

StorefrontCheckoutCountryDto

  • codestringnullable
  • namestringnullable

StorefrontCheckoutDto

Versioned (2026-04-01) storefront representation of a guest checkout. id is the opaque token used to address the checkout in GET/PUT /checkouts/{token} and POST /checkouts/{token}/complete. Money is a decimal value in currency; quantities are decimal. Cloudwawi.Shop.Api.V2026_04_01.Storefront.StorefrontCheckoutTotalsDto.PriceIncludesTax tells the client whether the figures are tax-inclusive.

StorefrontCheckoutLineDto

  • idstring (uuid)
  • article_idstring (uuid)nullable
  • titlestringnullable
  • skustringnullable
  • quantitynumber (double)
  • unit_pricenumber (double)
  • unit_price_with_taxnumber (double)
  • line_totalnumber (double)
  • line_total_with_taxnumber (double)
  • image_urlstringnullable

StorefrontCheckoutPaymentTypeDto

  • idstring (uuid)
  • namestringnullable
  • image_urlstringnullable

StorefrontCheckoutReadResponse

Envelope returned by POST /checkouts, GET /checkouts/{token} and PUT /checkouts/{token} — the three actions that read or edit a checkout. POST /checkouts/{token}/complete answers under the samecheckout key but with a different payload — see Cloudwawi.Shop.Api.V2026_04_01.Storefront.StorefrontCheckoutCompleteResponse. The key being shared is a published shape, not an oversight; a client must branch on the endpoint it called, not on the key. The type is named …ReadResponse rather than StorefrontCheckoutResponse only because that name is already taken by the application-layer result the controller maps from.

StorefrontCheckoutShippingOptionDto

  • idstring (uuid)
  • namestringnullable
  • pricestringnullable
  • expected_delivery_datestringnullable

StorefrontCheckoutTaxLineDto

  • namestringnullable
  • ratenumber (double)
  • amountnumber (double)

StorefrontCheckoutTermsPolicyDto

  • requiredboolean

    Send accepted_terms: true on complete when this is true.

  • terms_urlstringnullable
  • privacy_urlstringnullable

StorefrontCheckoutTotalsDto

  • subtotalnumber (double)
  • subtotal_before_discountnumber (double)
  • tax_amountnumber (double)
  • shipping_amountnumber (double)
  • shipping_tax_ratenumber (double)
  • shipping_method_namestringnullable
  • discountnumber (double)
  • coupon_textstringnullable
  • totalnumber (double)
  • currencystringnullable
  • price_includes_taxboolean

    When true, the figures above are tax-inclusive (gross); otherwise tax-exclusive (net).

StorefrontCheckoutUpdateRequest

Body of PUT /api/{version}/checkouts/{token}. Every field is optional — only the supplied facets are applied (shipping/billing address, shipping method, payment type, comments).