> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# $wsCheckout - Checkout

> Read order process data in the frontend: payment and shipping selection, addresses, totals, validation, and errors of the current checkout.

With the `$wsCheckout` module, you can read all data of the order process in the frontend. This includes the selected payment and shipping method, billing and delivery address, the order totals, as well as the validation and error status.

This page covers reading the checkout data. Everything that **changes** the checkout (selecting an address, setting the payment method, triggering the order) is documented under [Actions → Checkout](/en/frontend/referenz/aktionen/checkout).

***

## Basic concept

The checkout collects the customer's selection (payment, shipping, addresses, free fields) and continuously checks whether the order can be executed. Through `$wsCheckout`, you read this selection and the validation status to design the order flow and provide targeted feedback to the customer.

### Validation

There are three levels of validation feedback that differ in granularity. Choose the level based on what you want to display:

* **Overall status** - `isValid` indicates whether the order as a whole can be executed. Use it, for example, to enable or disable the "Buy" button.
* **Field state** - `fieldStates` provides a state per field (`untouched`, `empty`, `invalid`, `incompatible`, `valid`). Use it, for example, to visually mark a field.
* **Specific errors** - `problems` provides a list of errors per area with an error code and the name of the failed check. Use it, for example, to tell the customer exactly how to resolve the error.

### Immediate errors and errors after an action

The checkout has two sources of error feedback:

* `$wsCheckout.problems.*` - shown as soon as a field has been selected or left, provided that `show*BeforeSubmit` is set to `true` in the [configuration](/en/konfiguration/checkout-bestellablauf#7-checkout-fielderrorvisibility-fehleranzeige). After the first purchase attempt, the errors are shown regardless of this setting.
* `actionResponse` errors - originate from the server response after an action. For most sections, they are output unfiltered. Exception: for customer data fields and the [draft address](/en/frontend/referenz/aktionen/checkout#checkoutsetdraftaddress), there is no `problems.*`; in those cases, `actionResponse` errors are filtered via `show*BeforeSubmit`.

### Selection IDs and draft addresses

The `selected*` variables contain the ID of the respective selected option (e.g. the address ID that you pass to [`$wsAccount.loadAddress()`](/en/frontend/referenz/module/wsAccount#wsaccount-loadaddress)).

If the customer creates a new address during the order flow that is not yet saved in the customer account (draft address), it is kept under a **fixed system ID**: `draftBillAddressId` or `draftShippingAddressId`. These IDs are **always** present - even if no draft exists. Whether a draft is actually present (and what data it contains) is read via the maps [`draftBillAddress` / `draftShippingAddress`](#wscheckout-draftbilladdress-draftshippingaddress), which are only output in that case.

***

## Module overview

**Example / excerpt of** `$wsCheckout`

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{= $wsCheckout | json }}
```

**JSON output** (abbreviated)

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
  "accountType": "...",
  "customerData": { },
  "draftBillAddressId": "...",
  "draftShippingAddressId": "...",
  "fieldStates": { },
  "freeFields": [...],
  "guestMail": "...",
  "isExpressCheckoutLocked": false,
  "isOrderBlockedByIneffectiveVoucher": false,
  "isPPCApplePayExpressCheckout": false,
  "isPPCExpressCheckout": false,
  "isPPCGooglePayExpressCheckout": false,
  "isValid": false,
  "paymentBlocked": false,
  "paymentCaptchaRequired": false,
  "paymentMethodAutoReset": false,
  "problems": {
    "billAddress": [...],
    "clearing": [...],
    "general": [...],
    "payment": [...],
    "shippingAddress": [...],
    "shippingMethod": [...]
  },
  "selectedBillAddress": "...",
  "selectedPayment": "...",
  "selectedPseudoCC": "...",
  "selectedShippingAddress": "...",
  "selectedShippingMethod": "...",
  "selectedStoreId": 0,
  "shippingMethodAutoReset": false,
  "sum": { },
  "useAlternativeShippingAddress": false,
  "verificationStatus": 0,
  "verificationStatusOptions": [...],
  "voucherAppliesPerItem": false,
  "getAmountInSmallestUnit": "ƒ()",
  "getShippingCost": "ƒ()",
  "getShippingMethodDisabledErrors": "ƒ()",
  "isFinished": "ƒ()",
  "isPending": "ƒ()",
  "isValidBillAddress": "ƒ()",
  "isValidPayment": "ƒ()",
  "isValidShippingAddress": "ƒ()",
  "isValidShippingMethod": "ƒ()",
  "itemVoucherDiscount": "ƒ()"
}
```

Note: `"ƒ()"` denotes a function. Conditional variables such as `orderId`, `orderCreatedAt`, `restUntilFreeDelivery`, `freeShippingMethod`, `draftBillAddress` and `draftShippingAddress` only appear when they are set.

**Variables overview**

| **Variable**                                        | **Return type** | **Description**                                                                                                                                                                                                                                                                                                                                                   |
| --------------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `accountType`                                       | string          | Account type: `"guest"`, `"new"`, or `"registered"`. Empty (`""`) as long as no account type has been chosen yet.                                                                                                                                                                                                                                                 |
| `customerData`                                      | map             | Customer data fields, grouped and split by target group (including `groupedFields`, `newCustomerFieldGroups`, `existingCustomerFieldGroups`; see structure below).                                                                                                                                                                                                |
| `freeFields`                                        | array           | Free checkout fields (structure see below).                                                                                                                                                                                                                                                                                                                       |
| `guestMail`                                         | string          | Email of a guest account.                                                                                                                                                                                                                                                                                                                                         |
| `selectedPayment`                                   | string          | ID of the selected payment method.                                                                                                                                                                                                                                                                                                                                |
| `selectedShippingMethod`                            | string          | ID of the selected shipping method.                                                                                                                                                                                                                                                                                                                               |
| `selectedBillAddress`                               | string          | ID of the selected billing address.                                                                                                                                                                                                                                                                                                                               |
| `selectedShippingAddress`                           | string          | ID of the selected delivery address.                                                                                                                                                                                                                                                                                                                              |
| `draftBillAddressId`                                | string          | Fixed system ID under which a draft billing address is kept. Always present.                                                                                                                                                                                                                                                                                      |
| `draftShippingAddressId`                            | string          | Fixed system ID under which a draft delivery address is kept. Always present.                                                                                                                                                                                                                                                                                     |
| `draftBillAddress`                                  | map             | Data of the draft billing address. Only present if a draft exists.                                                                                                                                                                                                                                                                                                |
| `draftShippingAddress`                              | map             | Data of the draft delivery address. Only present if a draft exists.                                                                                                                                                                                                                                                                                               |
| `selectedPseudoCC`                                  | string          | Pseudo credit card token.                                                                                                                                                                                                                                                                                                                                         |
| `selectedStoreId`                                   | int             | ID of the selected store (e.g. Click & Collect).                                                                                                                                                                                                                                                                                                                  |
| `useAlternativeShippingAddress`                     | bool            | Whether a different delivery address is active.                                                                                                                                                                                                                                                                                                                   |
| `orderId`                                           | string          | ID of the order. Only present once an order exists in the session.                                                                                                                                                                                                                                                                                                |
| `orderCreatedAt`                                    | string          | Creation time of the order (ISO 8601). Only present once an order exists.                                                                                                                                                                                                                                                                                         |
| `shippingMethodAutoReset`<br />(**future feature**) | bool            | Indicates whether the shipping method was automatically reset because the previously selected shipping method became invalid due to a change in the order context (e.g. change of delivery country). <br />Whether the shipping method is automatically reselected is controlled by [`prevSelectionInvalidAutoSelect`](/en/konfiguration/checkout-bestellablauf). |
| `paymentMethodAutoReset`<br />(**future feature**)  | bool            | Indicates whether the payment method was automatically reset because the previously selected payment method became invalid due to a change in the order context (e.g. change of delivery country). <br />Whether the payment method is automatically reselected is controlled by [`prevSelectionInvalidAutoSelect`](/en/konfiguration/checkout-bestellablauf).    |
| `isValid`                                           | bool            | Checks whether the order as a whole can be executed.                                                                                                                                                                                                                                                                                                              |
| `isExpressCheckoutLocked`                           | bool            | Checks whether the express checkout is locked (e.g. after a PayPal payment).                                                                                                                                                                                                                                                                                      |
| `isPPCExpressCheckout`                              | bool            | Checks whether the PayPal Commerce Platform Express Checkout is active.                                                                                                                                                                                                                                                                                           |
| `isPPCApplePayExpressCheckout`                      | bool            | Checks whether the Apple Pay Express Checkout is active.                                                                                                                                                                                                                                                                                                          |
| `isPPCGooglePayExpressCheckout`                     | bool            | Checks whether the Google Pay Express Checkout is active.                                                                                                                                                                                                                                                                                                         |
| `problems`                                          | map             | Specific errors per area (structure see below).                                                                                                                                                                                                                                                                                                                   |
| `fieldStates`                                       | map             | State per checkout field (values see below).                                                                                                                                                                                                                                                                                                                      |
| `sum`                                               | map             | Price information for the checkout (structure see below).                                                                                                                                                                                                                                                                                                         |
| `verificationStatus`                                | int             | Verification status of the order.                                                                                                                                                                                                                                                                                                                                 |
| `verificationStatusOptions`                         | array           | Available verification status options.                                                                                                                                                                                                                                                                                                                            |
| `voucherAppliesPerItem`                             | bool            | Checks whether vouchers are applied per item.                                                                                                                                                                                                                                                                                                                     |
| `restUntilFreeDelivery`                             | float           | Remaining amount until the free shipping threshold (`0` if reached). Only present if a free-shipping threshold can be determined for the basket.                                                                                                                                                                                                                  |
| `freeShippingMethod`                                | string          | ID of the default free-shipping method. Only present if `restUntilFreeDelivery` is output, no shipping method has been chosen yet, and a default free-shipping method has been configured.                                                                                                                                                                        |
| `isOrderBlockedByIneffectiveVoucher`                | bool            | Checks whether the order is blocked by an ineffective voucher.                                                                                                                                                                                                                                                                                                    |
| `paymentBlocked`                                    | bool            | Checks whether the payment is blocked (protection against repeated payment attempts, IP- or session-based).                                                                                                                                                                                                                                                       |
| `paymentCaptchaRequired`                            | bool            | Checks whether a captcha is required for the payment (protection against repeated payment attempts).                                                                                                                                                                                                                                                              |

**Methods overview**

| **Method**                          | **Return type** | **Description**                                                      |
| ----------------------------------- | --------------- | -------------------------------------------------------------------- |
| `isValidPayment()`                  | bool            | Checks whether a payment method is available.                        |
| `isValidShippingMethod()`           | bool            | Checks whether a shipping method is available.                       |
| `isValidBillAddress()`              | bool            | Checks whether an address is valid as a billing address.             |
| `isValidShippingAddress()`          | bool            | Checks whether an address is valid as a delivery address.            |
| `isPending()`                       | bool            | Checks whether a payment process is pending.                         |
| `isFinished()`                      | bool            | Checks whether an order has been completed.                          |
| `getAmountInSmallestUnit()`         | int             | Converts an amount into the smallest currency unit (e.g. cents).     |
| `getShippingMethodDisabledErrors()` | array           | Returns why a shipping method is disabled.                           |
| `getShippingCost()`                 | float           | Shipping costs of a shipping method, relative to the current basket. |
| `itemVoucherDiscount()`             | float           | Calculates the voucher discount for an item.                         |

***

## Templates

The checkout is freely designable and can span one or more shop pages. The order of the elements is arbitrary.

***

## Variables

### \$wsCheckout.accountType

Returns the account type: `"guest"` (guest), `"new"` (new account), or `"registered"` (logged in). As long as the customer has not yet chosen an account type, the value is empty (`""`). Evaluate it, for example, to offer a guest the option to create an account.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.accountType == "guest" }}
  <!-- Guest order -->
{{ /if }}
```

### \$wsCheckout.guestMail

Returns the email address of a guest account. Only populated for a guest order.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Email: {{= $wsCheckout.guestMail }}
```

### \$wsCheckout.selectedPayment / selectedShippingMethod

Return the ID of the selected payment method or shipping method. Evaluate them to display or check the selection that was made.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.selectedPayment == "stripe" }}
  <!-- Stripe is selected -->
{{ /if }}
```

### \$wsCheckout.selectedBillAddress / selectedShippingAddress

Return the ID of the selected billing or delivery address. You pass this ID, for example, to [`$wsAccount.loadAddress()`](/en/frontend/referenz/module/wsAccount#wsaccount-loadaddress) to load the full address.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $billAddress = $wsAccount.loadAddress($wsCheckout.selectedBillAddress) }}
{{= $billAddress.firstName }} {{= $billAddress.lastName }}
```

### \$wsCheckout.draftBillAddressId / draftShippingAddressId

Return the **fixed system ID** under which a new address that was created during the order flow and is not yet saved in the customer account (draft address) is kept — for example, to recognize it as the selected address in the address selection.

Both IDs are **always** present, regardless of whether a draft exists. Whether a draft is actually present is checked via the maps [`draftBillAddress` / `draftShippingAddress`](#wscheckout-draftbilladdress-draftshippingaddress).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.selectedBillAddress == $wsCheckout.draftBillAddressId }}
  <!-- The newly created (not yet saved) billing address is selected -->
{{ /if }}
```

### \$wsCheckout.draftBillAddress / draftShippingAddress

Return the data of the draft billing or draft delivery address as a map. **Only present if a draft exists** — so they also work as an existence check.

The keys correspond to the address field names (standard fields such as `firstName`, `lastName`, `street`, `zip`, `city`, `country`, as well as [additional address fields](/en/konfiguration/accounts-benutzerkonten#accounts-customaddressfield-weitere-adressdatenfelder)). Only fields with a non-empty value are output.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.draftBillAddress }}
  New billing address:
  {{= $wsCheckout.draftBillAddress.firstName }} {{= $wsCheckout.draftBillAddress.lastName }},
  {{= $wsCheckout.draftBillAddress.street }}, {{= $wsCheckout.draftBillAddress.zip }} {{= $wsCheckout.draftBillAddress.city }}
{{ /if }}
```

A draft address is created via the action [CheckoutSetDraftAddress](/en/frontend/referenz/aktionen/checkout#checkoutsetdraftaddress).

### \$wsCheckout.useAlternativeShippingAddress

Returns whether a delivery address different from the billing address is used.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.useAlternativeShippingAddress }}
  <!-- Different delivery address -->
{{ /if }}
```

### \$wsCheckout.selectedStoreId

Returns the ID of the selected store (e.g. for Click & Collect). `0` if no store is selected.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.selectedStoreId > 0 }}
  <!-- Store selected -->
{{ /if }}
```

### \$wsCheckout.selectedPseudoCC

Returns the pseudo credit card token of the selected payment.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Token: {{= $wsCheckout.selectedPseudoCC }}
```

### \$wsCheckout.orderId / orderCreatedAt

Return the ID and creation time (ISO 8601) of the order. Both variables are **only present once an order exists in the current session** — e.g. on the order confirmation page.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.orderId }}
  Your order number: {{= $wsCheckout.orderId }} (created: {{= $wsCheckout.orderCreatedAt }})
{{ /if }}
```

### \$wsCheckout.customerData

Returns the configured customer data fields — grouped and split by target group. Which fields are included depends on the login status: for logged-in customers, the account fields; otherwise, the fields stored in the order.

#### Structure of `$wsCheckout.customerData`

| **Key**                       | **Type** | **Description**                                                                                                                                                                                                              |
| ----------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `groupedFields`               | array    | Field groups with their fields (see group object structure). Always present.                                                                                                                                                 |
| `newCustomerFieldGroups`      | array    | Field groups with the fields for the [new customer registration](/en/konfiguration/customer-kundendaten#customer-customerdatafieldsettings-feldkonfiguration). Always present.                                               |
| `existingCustomerFieldGroups` | array    | Field groups with the fields for the existing customer registration. Always present.                                                                                                                                         |
| `ungroupedFields`             | array    | Fields without a group assignment. Only present when `showUngroupedFields` is active in [`customer.customerDataFieldSettings`](/en/konfiguration/customer-kundendaten#customer-customerdatafieldsettings-feldkonfiguration). |
| `newCustomerFields`           | array    | Fields of the new customer registration as a flat list. Only present when `showUngroupedFields` is active.                                                                                                                   |
| `existingCustomerFields`      | array    | Fields of the existing customer registration as a flat list. Only present when `showUngroupedFields` is active.                                                                                                              |

#### Group object

The groups correspond to the configuration under [`customer.customerDataGroup`](/en/konfiguration/customer-kundendaten#customer-customerdatagroup-gruppierung).

| **Property** | **Type** | **Description**                                                                               |
| ------------ | -------- | --------------------------------------------------------------------------------------------- |
| `name`       | string   | Technical name of the group.                                                                  |
| `label`      | string   | Display name of the group.                                                                    |
| `hidden`     | bool     | Whether the group should be hidden (`true` when, for example, it contains no visible fields). |
| `fields`     | array    | The fields of the group (see field object structure).                                         |

#### Field object

| **Property**  | **Type**    | **Description**                                                            |
| ------------- | ----------- | -------------------------------------------------------------------------- |
| `name`        | string      | Technical name of the field.                                               |
| `label`       | string      | Display name of the field.                                                 |
| `type`        | string      | Field type (e.g. `text`, `number`, `date`, `checkbox`, `select`).          |
| `association` | string      | Storage location according to `storageStrategy` (account, order, or both). |
| `hidden`      | bool        | Whether the field should be hidden.                                        |
| `readonly`    | bool        | Whether the field is read-only.                                            |
| `touched`     | bool        | Whether the field has already been edited by the customer.                 |
| `required`    | bool        | Whether the field is a required field.                                     |
| `value`       | string/bool | Current value (bool for `checkbox`, string otherwise).                     |
| `externalId`  | string      | External identifier of the field. Only present if configured.              |
| `unit`        | map         | Unit information. Only for `number` fields with a configured unit.         |
| `options`     | array       | Selection options (`{value, label}`). Only for `select` fields.            |

**Example** that outputs all visible field groups with their fields:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $group in $wsCheckout.customerData.groupedFields }}
  {{ if not $group.hidden }}
    <fieldset>
      <legend>{{= $group.label }}</legend>
      {{ foreach $field in $group.fields }}
        {{ if not $field.hidden }}
          <label>{{= $field.label }}{{ if $field.required }} *{{ /if }}</label>
        {{ /if }}
      {{ /foreach }}
    </fieldset>
  {{ /if }}
{{ /foreach }}
```

### \$wsCheckout.freeFields

Returns the free checkout fields (e.g. T\&C checkbox, comment field). Iterate over the fields and evaluate them via their `id`.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsCheckout.freeFields }}
  {{= $field.name }} ({{= $field.type }}, required: {{= $field.required }})
{{ /foreach }}
```

#### Properties of a free field

| **Property** | **Return type** | **Description**                                                                                |
| ------------ | --------------- | ---------------------------------------------------------------------------------------------- |
| `id`         | string          | ID of the field (e.g. `"agb"`, `"comment"`).                                                   |
| `name`       | string          | Display name of the field (e.g. `"T&C"`).                                                      |
| `type`       | string          | Field type (`"checkbox"`, `"text"`).                                                           |
| `required`   | bool            | Whether the field is a required field.                                                         |
| `default`    | bool/string     | Default value (bool for checkbox, string for text field).                                      |
| `checked`    | bool            | Whether the checkbox is checked (only for `type == "checkbox"`).                               |
| `text`       | string          | Currently entered text (only for `type == "text"` and only present when a value has been set). |

### \$wsCheckout.isValid

Returns whether the order as a whole can be executed. This is the overall status across all fields – use it to enable or disable the "Buy" button.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValid }}
  <!-- Order can be executed -->
{{ /if }}
```

### \$wsCheckout.isExpressCheckoutLocked

Returns whether the express checkout is locked – e.g. after the customer has paid via PayPal and is redirected back to the shop for confirmation. Evaluate it to prevent editing of the basket in this state.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isExpressCheckoutLocked }}
  Editing your basket is currently not possible.
{{ /if }}
```

### \$wsCheckout.isPPCExpressCheckout / isPPCApplePayExpressCheckout / isPPCGooglePayExpressCheckout

Return whether the respective PayPal Commerce Platform express checkout is active. Use them to display the appropriate express checkout flow.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isPPCExpressCheckout }}
  <!-- PayPal Express Checkout active -->
{{ /if }}
```

### \$wsCheckout.paymentCaptchaRequired / paymentBlocked

Protection against repeated payment attempts (IP- or session-based): `paymentCaptchaRequired` indicates whether a captcha must be solved before the next payment attempt. `paymentBlocked` indicates whether further payment attempts are currently blocked.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.paymentBlocked }}
  Too many failed payment attempts. Please try again later.
{{ elseif $wsCheckout.paymentCaptchaRequired }}
  <!-- Show captcha -->
{{ /if }}
```

### \$wsCheckout.isOrderBlockedByIneffectiveVoucher

Indicates whether the order is blocked because a redeemed voucher cannot take effect on the current basket. Use it to point the customer to the ineffective voucher.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isOrderBlockedByIneffectiveVoucher }}
  A redeemed voucher cannot be applied to this basket.
{{ /if }}
```

### \$wsCheckout.verificationStatus / verificationStatusOptions

`verificationStatus` returns the verification status of the order as a number. `verificationStatusOptions` lists the possible statuses.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $option in $wsCheckout.verificationStatusOptions }}
  {{= $option.id }}: {{= $option.name }}
{{ /foreach }}
```

### \$wsCheckout.voucherAppliesPerItem

Returns whether a voucher is applied per item (instead of on the total amount).

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.voucherAppliesPerItem }}
  <!-- Voucher is calculated per item -->
{{ /if }}
```

### \$wsCheckout.restUntilFreeDelivery / freeShippingMethod

`restUntilFreeDelivery` returns the remaining amount until the free shipping threshold (`0` if the threshold has been reached). The variable is **only present if a free-shipping threshold can be determined for the basket**. Use it for a "Only X left until free shipping" notice.

`freeShippingMethod` additionally contains the ID of the configured default free-shipping method — but only as long as the customer has not yet chosen a shipping method and a default free-shipping method is configured.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.restUntilFreeDelivery > 0 }}
  Only {{= $wsCheckout.restUntilFreeDelivery | currency }} left until free shipping!
{{ /if }}
```

### \$wsCheckout.fieldStates

Returns a map with the state of each checkout field (`payment`, `shippingMethod`, `billAddress`, `shippingAddress`). Use it to mark individual fields specifically – e.g. an unfilled field neutrally, a faulty one in red.

| **Value**        | **Description**                                             |
| ---------------- | ----------------------------------------------------------- |
| `"untouched"`    | The field has not yet been edited or selected.              |
| `"empty"`        | The field was filled, but the value was removed again.      |
| `"invalid"`      | A value is present but failed validation.                   |
| `"incompatible"` | The value is valid but not allowed in the current context.  |
| `"valid"`        | The field is filled in correctly and has passed all checks. |

<Info>
  The states build on each other. The system checks in sequence: selected (`untouched`) → value present (`empty`) → valid (`invalid`) → allowed in context (`incompatible`). Only when all checks have passed does the field count as `valid`. The first applicable state is returned.
</Info>

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.fieldStates.payment == "valid" }}
  <!-- Payment method correctly selected -->
{{ /if }}
```

### \$wsCheckout.problems

Returns a map with specific errors per area. The map contains exactly six areas: `payment`, `shippingMethod`, `billAddress`, `shippingAddress`, `clearing`, and `general`. Each area is a list of errors; it is populated when a problem is present there.

#### Properties of an error

Each error is an object with exactly two properties:

| **Property** | **Return type** | **Description**                                                                                                                                                                                        |
| ------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `code`       | string          | Error code (see table below).                                                                                                                                                                          |
| `check`      | string          | Name of the failed validation service (e.g. `"voucherDeny"`). If `code == "missing"`, `check` is `null`. In the `clearing` area, `check` instead contains the error message from the payment provider. |

<Warning>
  The error objects do **not** contain a descriptive error text (`text`) or the affected field (`field`). Formulate the customer-facing message in the template based on `code` and, if applicable, `check` (see example below).
</Warning>

#### Meaning of the error codes

| **Code**              | **Meaning**                                                                                                                | **Example**                                                                          |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| `"missing"`           | No value selected or entered.                                                                                              | No payment method selected.                                                          |
| `"checkFailed"`       | A value is present but failed validation.                                                                                  | Invalid address; in `general`: not-allowed account type (`check` = `"accountType"`). |
| `"checkIncompatible"` | The value is valid but not allowed in the current context.                                                                 | Payment method blocked for the delivery country.                                     |
| `"clearingFailed"`    | The payment processing at the provider failed. Only in the `clearing` area; `check` contains the provider's error message. | Payment rejected by Computop.                                                        |

**Example** that outputs the payment method errors in a customer-friendly way:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $prob in $wsCheckout.problems.payment }}
  {{ if $prob.code == "missing" }}
    Please select a payment method.
  {{ elseif $prob.code == "checkFailed" }}
    The selected payment method is invalid ({{= $prob.check }}).
  {{ elseif $prob.code == "checkIncompatible" }}
    The selected payment method is not available for your selection ({{= $prob.check }}).
  {{ /if }}
{{ /foreach }}
```

<Info>
  To access an individual error, use the index, e.g. `$wsCheckout.problems.payment[0].code`. `$wsCheckout.problems` does not provide errors for free checkout fields — those are evaluated via the `actionResponse` errors of the respective action (e.g. [CheckoutSetFreeFields](/en/frontend/referenz/aktionen/checkout)).
</Info>

### \$wsCheckout.sum

Returns a map with the price information for the checkout. To display a value as a monetary amount, use the `currency` filter – it already includes the currency symbol.

#### Properties of `$wsCheckout.sum`

| **Property**        | **Return type** | **Description**                                               |
| ------------------- | --------------- | ------------------------------------------------------------- |
| `total`             | float           | Total amount of the order (incl. shipping, discounts, taxes). |
| `totalNet`          | float           | Net amount.                                                   |
| `totalGross`        | float           | Gross amount.                                                 |
| `totalTax`          | float           | Total VAT.                                                    |
| `totalPreDeduction` | float           | Total amount before tax deduction.                            |
| `totalVoucher`      | float           | Value of the redeemed vouchers.                               |
| `totalWeight`       | float           | Total weight of the order.                                    |
| `shippingCost`      | float           | Shipping costs.                                               |
| `paymentCost`       | float           | Costs of the payment method.                                  |
| `surchargeCost`     | float           | Extra costs / surcharges.                                     |
| `currency`          | string          | Currency code (e.g. `"EUR"`).                                 |
| `totalTaxDeduction` | float           | Amount of deducted tax (in case of tax exemption).            |
| `isTaxExempt`       | bool            | Whether the order is tax-exempt.                              |
| `usedExemptionRule` | string          | Active tax check rule (e.g. `"shippingOnly"`).                |
| `billingCountry`    | string          | Country code of the billing address.                          |
| `shippingCountry`   | string          | Country code of the delivery address.                         |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Total amount: {{= $wsCheckout.sum.total | currency }}
Shipping costs: {{= $wsCheckout.sum.shippingCost | currency }}
```

***

## Methods

### \$wsCheckout.isValidPayment()

Checks whether the payment method with the specified ID is available. All validation rules configured for the payment method under `validations` are executed (see [`paymentValidation.*` - Payment method validation](/en/konfiguration/validierungs-und-prufservices#paymentvalidation-%2A-zahlungsarten-validierung)) — e.g. country rules, order value limits, or exclusion when voucher products are in the basket (`paymentValidation.voucherDeny`). Additionally, it is checked whether the payment method is active and permitted for the customer account.

If at least one rule fails, the method returns `false`. This is how the configured validation rules take effect in the frontend: the template hides or disables the payment method.

**Signature**\
`$wsCheckout.isValidPayment(paymentId)`

**Return value**\
`true / false` — payment method available / not available.

**Parameters**

| **Name**    | **Type** | **Required** | **Description**                         |
| ----------- | -------- | ------------ | --------------------------------------- |
| `paymentId` | string   | yes          | ID of the payment method to be checked. |

**Example** that checks whether the payment method is available.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidPayment("stripe") }}
  // Stripe is available
{{ /if }}
```

**Example** that offers all payment methods as a selection and disables those that are not available. Payment methods whose validation fails (e.g. due to `paymentValidation.voucherDeny` with a voucher product in the basket) are visible but not selectable.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $cPayment in $wsConfig.payments }}
  <input type="radio" name="paymentId" value="{{= $cPayment.id }}"
    {{ if $wsCheckout.selectedPayment == $cPayment.id }} checked{{ /if }}
    {{ if not $wsCheckout.isValidPayment($cPayment.id) }} disabled{{ /if }}>
  <label>{{= $cPayment.name }}</label>
{{ /foreach }}
```

Why the currently selected payment method is invalid can be evaluated via [`$wsCheckout.problems.payment`](#wscheckout-problems); the `check` field there contains the name of the failed validation service.

### \$wsCheckout.isValidShippingMethod()

Checks whether the shipping method with the specified ID is available. All validation rules configured for the shipping method under `validations` are executed (see [`shippingMethodValidation.*` - Shipping method validation](/en/konfiguration/validierungs-und-prufservices#shippingmethodvalidation-%2A-versandarten-validierung)) — e.g. country rules, order value limits, or product type restrictions.

If at least one rule fails, the method returns `false`. The template then hides or disables the shipping method (same pattern as [`isValidPayment()`](#wscheckout-isvalidpayment)). The reasons for a disabled shipping method can be output via [`getShippingMethodDisabledErrors()`](#wscheckout-getshippingmethoddisablederrors).

**Signature**\
`$wsCheckout.isValidShippingMethod(shippingMethodId)`

**Return value**\
`true / false` — shipping method available / not available.

**Parameters**

| **Name**           | **Type** | **Required** | **Description**                          |
| ------------------ | -------- | ------------ | ---------------------------------------- |
| `shippingMethodId` | string   | yes          | ID of the shipping method to be checked. |

**Example** that checks whether the specified shipping method is available.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidShippingMethod("dhl_standard") }}
  // DHL Standard is available
{{ /if }}
```

### \$wsCheckout.isValidBillAddress() / isValidShippingAddress()

Check whether the address with the specified ID is valid as a billing or delivery address.

**Signature**\
`$wsCheckout.isValidBillAddress(addressId)` · `$wsCheckout.isValidShippingAddress(addressId)`

**Return value**\
`bool` – valid / not valid.

| **Name**    | **Type** | **Required** | **Description**                  |
| ----------- | -------- | ------------ | -------------------------------- |
| `addressId` | string   | yes          | ID of the address to be checked. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidBillAddress($wsCheckout.selectedBillAddress) }}
  <!-- Billing address is valid -->
{{ /if }}
```

### \$wsCheckout.isPending() / isFinished()

`isPending()` checks whether a payment process is still pending; `isFinished()` checks whether the order has been completed. Use them to detect the status of an ongoing or completed order.

**Signature**\
`$wsCheckout.isPending()` · `$wsCheckout.isFinished()`

**Return value**\
`bool`.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isPending() }}
  <!-- Payment process still ongoing -->
{{ /if }}
```

### \$wsCheckout.getAmountInSmallestUnit()

Returns an amount in the smallest currency unit (e.g. cents instead of euros). Useful for payment APIs that expect amounts in cents.

**Signature**\
`$wsCheckout.getAmountInSmallestUnit(amount)`

**Return value**\
`int` – amount in the smallest unit.

| **Name** | **Type** | **Required** | **Description**              |
| -------- | -------- | ------------ | ---------------------------- |
| `amount` | float    | yes          | Amount in the main currency. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ var $cents = $wsCheckout.getAmountInSmallestUnit($wsCheckout.sum.total) }}
```

### \$wsCheckout.getShippingMethodDisabledErrors()

Returns why a shipping method is disabled. Use it to explain to the customer why a shipping method cannot be selected.

**Signature**\
`$wsCheckout.getShippingMethodDisabledErrors(shippingMethodId)`

**Return value**\
`array` – list of error messages.

| **Name**           | **Type** | **Required** | **Description**                          |
| ------------------ | -------- | ------------ | ---------------------------------------- |
| `shippingMethodId` | string   | yes          | ID of the shipping method to be checked. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $error in $wsCheckout.getShippingMethodDisabledErrors("express") }}
  {{= $error }}
{{ /foreach }}
```

### \$wsCheckout.getShippingCost()

Returns the shipping costs of a specific shipping method, even if it is not selected. The value is based on the current basket. Use it, for example, to display the shipping costs of various options in advance.

**Signature**\
`$wsCheckout.getShippingCost(shippingMethodId)`

**Return value**\
`float` – shipping costs of the specified shipping method.

| **Name**           | **Type** | **Required** | **Description**                                             |
| ------------------ | -------- | ------------ | ----------------------------------------------------------- |
| `shippingMethodId` | string   | yes          | ID of the shipping method whose costs are to be determined. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Shipping costs: {{= $wsCheckout.getShippingCost("dhl_standard") | currency }}
```

### \$wsCheckout.itemVoucherDiscount()

Calculates the voucher discount for a single basket item. Pass the ID of a [basket entry](/en/frontend/referenz/module/wsbasket#wsbasket-items).

**Signature**\
`$wsCheckout.itemVoucherDiscount(itemId)`

**Return value**\
`float` – discount amount for the item.

| **Name** | **Type** | **Required** | **Description**         |
| -------- | -------- | ------------ | ----------------------- |
| `itemId` | string   | yes          | ID of the basket entry. |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Discount: {{= $wsCheckout.itemVoucherDiscount($item.id) | currency }}
```

***

## Actions

Actions that change the checkout (selecting an address, setting the payment method, triggering the order) are documented separately: [Actions → Checkout](/en/frontend/referenz/aktionen/checkout).

***

## Examples

### Check whether the order can be placed and display errors

This example combines the validation levels: \
If the order is valid, the "Buy" area is shown; otherwise the specific problems are listed — based on `code` and `check`, since the error objects do not contain a ready-made text.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValid }}
  <!-- Show buy button -->
{{ else }}
  {{ foreach $prob in $wsCheckout.problems.payment }}
    {{ if $prob.code == "missing" }}
      Please select a payment method.
    {{ else }}
      The selected payment method is not available ({{= $prob.check }}).
    {{ /if }}
  {{ /foreach }}
  {{ foreach $prob in $wsCheckout.problems.shippingMethod }}
    {{ if $prob.code == "missing" }}
      Please select a shipping method.
    {{ else }}
      The selected shipping method is not available ({{= $prob.check }}).
    {{ /if }}
  {{ /foreach }}
  {{ foreach $prob in $wsCheckout.problems.billAddress }}
    Please check your billing address ({{= $prob.code }}).
  {{ /foreach }}
{{ /if }}
```

**Result** \
For a valid order, the buy area appears; otherwise the open items per area are shown.

### Totals overview

A complete totals display. The `currency` filter already includes the currency symbol.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Subtotal: {{= $wsCheckout.sum.totalNet | currency }}
Shipping costs: {{= $wsCheckout.sum.shippingCost | currency }}
VAT: {{= $wsCheckout.sum.totalTax | currency }}
{{ if $wsCheckout.sum.totalVoucher > 0 }}
  Voucher: {{= $wsCheckout.sum.totalVoucher | currency }}
{{ /if }}
Total amount: {{= $wsCheckout.sum.total | currency }}
```

**Result** \
A breakdown of totals with correctly formatted monetary amounts.

### Check T\&C acceptance

Checks whether the free field `agb` is checked before the order is allowed.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ foreach $field in $wsCheckout.freeFields }}
  {{ if $field.id == "agb" and not $field.checked }}
    Please accept the terms and conditions.
  {{ /if }}
{{ /foreach }}
```

**Result** \
If the T\&C checkbox is not checked, the notice appears.

### Check the selected payment method

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{{ if $wsCheckout.isValidPayment($wsCheckout.selectedPayment) }}
  Selected payment method: {{= $wsCheckout.selectedPayment }}
{{ /if }}
```

**Result** \
The selected payment method is shown if it is valid.

***

## Related links

* [Actions → Checkout](/en/frontend/referenz/aktionen/checkout) – change the checkout (set selection, trigger order), since `$wsCheckout` itself is read-only.
* [\$wsBasket](/en/frontend/referenz/module/wsbasket) – the basket on which the checkout is built; provides the items for `itemVoucherDiscount()`.
* [\$wsAccount](/en/frontend/referenz/module/wsAccount) – uses `loadAddress()` to load the full address for `selectedBillAddress`/`selectedShippingAddress`.
* [Checkout configuration](/en/konfiguration/checkout-bestellablauf#7-checkout-fielderrorvisibility-fehleranzeige) – controls when errors are displayed via `show*BeforeSubmit`.
