Checkout Agreements

Configure required checkout consent checkboxes and checkout settings

GET /admin/api/checkout-agreements

List every checkout agreement checkbox in display order (by position ascending, ties broken by id). Each agreement includes its required flag and the per-language markdown label map.

GET /admin/api/checkout-agreements/{id}

Fetch a single checkout agreement by id.

POST /admin/api/checkout-agreements

Create a checkout agreement checkbox. The translations map must include the shop's default language, every key must be an enabled shop language, and all text must be non-empty. Labels may contain inline markdown links `[text](url)`; only http(s) and root-relative `/path` URLs are accepted.

PATCH /admin/api/checkout-agreements/{id}

Partial update of a checkout agreement. Any field may be omitted; omitted fields are left unchanged. When translations are supplied they replace the entire map and are re-validated (default language present, enabled languages only, non-empty text, safe markdown link URLs).

DELETE /admin/api/checkout-agreements/{id}

Delete an agreement checkbox. Idempotent — deleting a missing id also returns 204 No Content.

POST /admin/api/checkout-agreements/reorder

Reorder all agreement checkboxes in one call. The `ids` list must contain exactly the current set of agreement ids (no missing, extra, or duplicate ids) — agreements are then stored in the given order.

GET /admin/api/checkout-settings

Read the controlled-checkout settings for this tenant: checkout mode, field visibility, header notice, color palette, Google Places autocomplete, dual-currency display, and delivery-date rules. A default row is seeded by migration, so this always returns a value. `currency_code` is read-only here and is exposed so the UI can show the BGN dual-currency toggle only for EUR shops.

PATCH /admin/api/checkout-settings

Update the controlled-checkout settings. `checkout_mode` and `checkout_phone_field` must be recognised enum values and every color must be a `#rrggbb` hex string. `checkout_logo_url` / `has_checkout_logo` / `checkout_google_places_active` and `currency_code` are read-only and not accepted here. Set `checkout_allow_today_delivery` to true to let customers pick today as the preferred delivery date; when false (default) tomorrow is the earliest selectable date. Returns 204 No Content on success.

GET /admin/api/checkout-agreements

List every checkout agreement checkbox in display order (by position ascending, ties broken by id). Each agreement includes its required flag and the per-language markdown label map.

Response 200

[
  {
    "id": 1,
    "position": 0,
    "required": true,
    "translations": {
      "en": "I agree to the [Terms & Conditions](/legal/terms) and [Privacy Policy](https://yourshop.zeroshop.io/legal/privacy).",
      "fr": "J'accepte les [Conditions générales](/legal/terms)."
    }
  },
  {
    "id": 2,
    "position": 1,
    "required": false,
    "translations": {
      "en": "Subscribe me to the newsletter."
    }
  }
]

Example

curl "https://yourshop.zeroshop.io/admin/api/checkout-agreements" \
  -H "Authorization: Bearer zspat_..."
GET /admin/api/checkout-agreements/{id}

Fetch a single checkout agreement by id.

Response 200

{
  "id": 1,
  "position": 0,
  "required": true,
  "translations": {
    "en": "I agree to the [Terms & Conditions](/legal/terms) and [Privacy Policy](https://yourshop.zeroshop.io/legal/privacy).",
    "fr": "J'accepte les [Conditions générales](/legal/terms)."
  }
}

Example

curl "https://yourshop.zeroshop.io/admin/api/checkout-agreements/1" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/checkout-agreements

Create a checkout agreement checkbox. The translations map must include the shop's default language, every key must be an enabled shop language, and all text must be non-empty. Labels may contain inline markdown links `[text](url)`; only http(s) and root-relative `/path` URLs are accepted.

Request Body

{
  "required": true,
  "translations": {
    "en": "I agree to the [Terms & Conditions](/legal/terms).",
    "fr": "J'accepte les [Conditions générales](/legal/terms)."
  },
  "position": 0
}

Response 201

{
  "id": 3,
  "position": 2,
  "required": true,
  "translations": {
    "en": "I agree to the [Terms & Conditions](/legal/terms).",
    "fr": "J'accepte les [Conditions générales](/legal/terms)."
  }
}

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/checkout-agreements" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "required": true,
    "translations": {
      "en": "I agree to the [Terms & Conditions](/legal/terms).",
      "fr": "J'\''accepte les [Conditions générales](/legal/terms)."
    }
  }'
PATCH /admin/api/checkout-agreements/{id}

Partial update of a checkout agreement. Any field may be omitted; omitted fields are left unchanged. When translations are supplied they replace the entire map and are re-validated (default language present, enabled languages only, non-empty text, safe markdown link URLs).

Request Body

{
  "required": false
}

Response 200

{
  "id": 1,
  "position": 0,
  "required": false,
  "translations": {
    "en": "I agree to the [Terms & Conditions](/legal/terms) and [Privacy Policy](https://yourshop.zeroshop.io/legal/privacy).",
    "fr": "J'accepte les [Conditions générales](/legal/terms)."
  }
}

Example

curl -X PATCH "https://yourshop.zeroshop.io/admin/api/checkout-agreements/1" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"required": false}'
DELETE /admin/api/checkout-agreements/{id}

Delete an agreement checkbox. Idempotent — deleting a missing id also returns 204 No Content.

Response 204

Example

curl -X DELETE "https://yourshop.zeroshop.io/admin/api/checkout-agreements/1" \
  -H "Authorization: Bearer zspat_..."
POST /admin/api/checkout-agreements/reorder

Reorder all agreement checkboxes in one call. The `ids` list must contain exactly the current set of agreement ids (no missing, extra, or duplicate ids) — agreements are then stored in the given order.

Request Body

{
  "ids": [
    2,
    1,
    3
  ]
}

Response 204

Example

curl -X POST "https://yourshop.zeroshop.io/admin/api/checkout-agreements/reorder" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{"ids": [2, 1, 3]}'
GET /admin/api/checkout-settings

Read the controlled-checkout settings for this tenant: checkout mode, field visibility, header notice, color palette, Google Places autocomplete, dual-currency display, and delivery-date rules. A default row is seeded by migration, so this always returns a value. `currency_code` is read-only here and is exposed so the UI can show the BGN dual-currency toggle only for EUR shops.

Response 200

{
  "checkout_mode": "controlled",
  "checkout_phone_field": "optional",
  "checkout_company_field": false,
  "checkout_order_notes": true,
  "checkout_separate_billing": false,
  "checkout_header_notice": "Orders placed before 2pm ship same day.",
  "checkout_accent_color": "#0f7a55",
  "checkout_highlight_text_color": "#005237",
  "checkout_page_bg_color": "#f9f9f9",
  "checkout_highlight_bg_color": "#e7f2ee",
  "checkout_button_text_color": "#ffffff",
  "checkout_logo_url": "https://cdn.zeroshop.io/tenant/checkout-logo.png?v=1716991200",
  "has_checkout_logo": true,
  "checkout_google_places_enabled": true,
  "checkout_google_places_api_key": "AIzaSyExampleBrowserKey",
  "checkout_google_places_active": true,
  "checkout_dual_currency_bgn": false,
  "checkout_allow_today_delivery": false,
  "currency_code": "EUR"
}

Example

curl "https://yourshop.zeroshop.io/admin/api/checkout-settings" \
  -H "Authorization: Bearer zspat_..."
PATCH /admin/api/checkout-settings

Update the controlled-checkout settings. `checkout_mode` and `checkout_phone_field` must be recognised enum values and every color must be a `#rrggbb` hex string. `checkout_logo_url` / `has_checkout_logo` / `checkout_google_places_active` and `currency_code` are read-only and not accepted here. Set `checkout_allow_today_delivery` to true to let customers pick today as the preferred delivery date; when false (default) tomorrow is the earliest selectable date. Returns 204 No Content on success.

Request Body

{
  "checkout_mode": "controlled",
  "checkout_phone_field": "optional",
  "checkout_company_field": false,
  "checkout_order_notes": true,
  "checkout_separate_billing": false,
  "checkout_header_notice": "Orders placed before 2pm ship same day.",
  "checkout_accent_color": "#0f7a55",
  "checkout_highlight_text_color": "#005237",
  "checkout_page_bg_color": "#f9f9f9",
  "checkout_highlight_bg_color": "#e7f2ee",
  "checkout_button_text_color": "#ffffff",
  "checkout_google_places_enabled": true,
  "checkout_google_places_api_key": "AIzaSyExampleBrowserKey",
  "checkout_dual_currency_bgn": false,
  "checkout_allow_today_delivery": false
}

Response 204

Example

curl -X PATCH "https://yourshop.zeroshop.io/admin/api/checkout-settings" \
  -H "Authorization: Bearer zspat_..." \
  -H "Content-Type: application/json" \
  -d '{
    "checkout_mode": "controlled",
    "checkout_phone_field": "optional",
    "checkout_company_field": false,
    "checkout_order_notes": true,
    "checkout_separate_billing": false,
    "checkout_header_notice": "Orders placed before 2pm ship same day.",
    "checkout_accent_color": "#0f7a55",
    "checkout_highlight_text_color": "#005237",
    "checkout_page_bg_color": "#f9f9f9",
    "checkout_highlight_bg_color": "#e7f2ee",
    "checkout_button_text_color": "#ffffff",
    "checkout_google_places_enabled": true,
    "checkout_google_places_api_key": "AIzaSyExampleBrowserKey",
    "checkout_allow_today_delivery": false
  }'

We value your privacy

We use cookies for essential site functionality and, with your consent, analytics to understand how our platform is used. No personal data is shared with third parties. See our Privacy Policy for details.