> ## 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.

# Adding products via voucher

> Use a voucher to automatically add up to three products to the basket, mark products for this purpose, and offer variant selection in the basket.

A voucher does not have to deduct money; it can also bring something along. If the buyer enters a voucher number on the basket page and the voucher is accepted, the shop automatically adds up to three predefined products to the basket.

You determine which products these are when creating the voucher in the voucher generator. The products themselves must be prepared for this, and that is the part that requires work in the shop.

## The rules for products that can be added

### What the product must have

| Condition | Why |
| - | - |
| It is marked as addable via the product field `VoucherProduct` | A voucher may only add marked products to the basket |
| It has a unique product number | The voucher stores the product number, not the product index. The shop uses it to look up the product and, with duplicate numbers, finds the wrong one or none at all |
| It is in a hidden category | Otherwise it appears in search and in category lists even though nobody can buy it |

> [!NOTE]
>
> Variants are supported. The voucher can therefore also add a product for which the buyer still chooses a size or color.

### What is not possible

These product types can **not** be added:

* Upload products
* Set products
* Products with dynamic stock

> [!WARNING]
>
> A product that can be added via voucher cannot be added to the basket from the product view. Without a suitable notice, the buyer clicks there in vain. Step 3 defines this message.

### What the buyer can do with it

| Action | Possible |
| - | - |
| Change variant | yes, from the basket |
| Change quantity | no, the quantity is always one |
| Delete individually from the basket | no |
| Remove all added products | yes, by removing the voucher |

> [!NOTE]
>
> If the buyer enters the same voucher again while its products are already in the basket, the shop does not add them a second time. The quantity remains one.

> [!NOTE]
>
> Added products are marked as such in the order data and can therefore be distinguished from regularly purchased items in the merchandise management system.

## Prerequisites

**The voucher generator must be activated.** If you want to use it, contact your WEBSALE representative.

> [!NOTE]
>
> If the vouchers come from an external system and are therefore not in WEBSALE format, add the entry `ExternalVouchers-Allow = yes` in the `<Voucher-Txt>` section of the `shop.config`.

**Voucher entry must be integrated in the shop.** Without it, no voucher gets into the basket and therefore no added product either.

Guide: Provide voucher entry · Reference: Voucher-Txt section

## Step 1: Marking the products

In the WSPManager or in your merchandise management system, set the field `VoucherProduct` for the product in question.

```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
VoucherProduct: y
```

> [!WARNING]
>
> The value is checked for `y`. Any other value and an empty field mean "not a voucher product". A typo turns the product into an ordinary item that can then be openly purchased in the shop, and the voucher finds nothing to add.

## Step 2: Configuring the voucher

When creating the voucher in the voucher generator, enter the product numbers, at most three, in the **Products for basket** field.

> [!NOTE]
>
> The upper limit of three products is fixed in the shop and cannot be increased. If more numbers are stored, the shop processes the first three.

## Step 3: Defining the notice message

If someone tries to add a voucher product to the basket directly from the product detail view, the shop rejects this. The text for this is located in the `shop.config`.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<NotifyMessages-Txt>
   VoucherProduct = Dieses Produkt ist nur in Verbindung mit einem Gutschein verfügbar.
</NotifyMessages-Txt>
```

Reference: NotifyMessages-Txt section

## Step 4: Adjusting the quantity field in the product detail view

The quantity of an added product is always one. On the product detail view, the quantity field for these products therefore belongs in the form as a hidden field, so that the buyer does not even enter a quantity that the shop then discards.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<form action="~FORM-Product~" method="post">

   {PR-VoucherProduct}
      <input type="hidden" name="~PR-Quantity_Input~" value="1">
   {/PR-VoucherProduct}

   {!PR-VoucherProduct}
      <input type="text" name="~PR-Quantity_Input~" value="~PR-Quantity~">
   {/!PR-VoucherProduct}

</form>
```

Reference: PR-VoucherProduct

## Step 5: Marking voucher products (optional)

A notice is worthwhile in two places, each with the same pattern: a section that only applies to voucher products.

| Template | Section | Useful text |
| - | - | - |
| Product detail view `ws_product.htm` | `PR-VoucherProduct` | that the product can only be ordered with a voucher |
| Basket page `ws_basket.htm` | `BASKET-PR-VoucherProduct` | that the item is in the basket because of the entered voucher |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{PR-VoucherProduct}
   Bitte beachten Sie: Dieses Produkt ist nur in Verbindung mit einem Gutschein verfügbar.
{/PR-VoucherProduct}
```

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{@BASKET-PR-Data}
   {BASKET-PR-VoucherProduct}
      Dieses Produkt erhalten Sie aufgrund Ihres eingegebenen Gutscheins.
   {/BASKET-PR-VoucherProduct}
{/@BASKET-PR-Data}
```

> [!NOTE]
>
> The notice in the basket is more than cosmetic. Because the item cannot be deleted individually, the buyer would otherwise look for the missing delete icon. The sentence explains where the item comes from.

Reference: BASKET-PR-VoucherProduct

## Step 6: Unresolved voucher products (optional)

If an added product has variants, there are two options. Either you define the variant in the voucher, in which case nothing else needs to be done. Or the buyer should choose it themselves. In this case, the product initially ends up in the basket **unresolved**, and the order can only be completed once the choice has been made.

This section describes the second case and consists of three parts: the configuration, the notice in the basket, and the selection itself.

### 6.1 Activating the function

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Voucher-Txt>
   UnresolvedVoucherProducts-Allow = yes
</Voucher-Txt>
```

### 6.2 Displaying the notice in the basket

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{@BASKET-PR-Data}
   {BASKET-PR-UnresolvedVoucherProduct}
      Bitte wählen Sie die gewünschte Variante Ihres Gutscheinproduktes aus,
      um die Bestellung abschließen zu können.
   {/BASKET-PR-UnresolvedVoucherProduct}
{/@BASKET-PR-Data}
```

> [!WARNING]
>
> This notice is not optional if you switch on the function. As long as an unresolved voucher product is in the basket, the shop blocks order completion. Without the notice, the buyer faces an order button that does nothing and does not know why.

Reference: BASKET-PR-UnresolvedVoucherProduct

### 6.3 Offering variant selection in the basket

The selection itself runs via AJAX and a dedicated template. The following example uses FastInclude.

#### Addition in the FastInclude file

Insert the following block in the `Incl-Basket` section of the file `incl_fast_includes.htm`.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{BASKET-PR-Data}
   {@BASKET-PR-Data}
      {ST-BasketPage}
         ~DC-FPshowVariationBtn_reset~

         {BASKET-PR-UnresolvedVoucherProduct}
            ~DC-FPshowVariationBtn_set(true)~
         {/BASKET-PR-UnresolvedVoucherProduct}

         {BASKET-PR-VoucherProduct}
            {BASKET-PR-Variations}
               ~DC-FPshowVariationBtn_set(true)~
            {/BASKET-PR-Variations}
         {/BASKET-PR-VoucherProduct}

         {VOUCHER-VoucherProducts_data}
            {@VOUCHER-VoucherProducts_data}
               ~DC-SPvoucherProductIndex_set($VOUCHER-VoucherProducts_data_prodnumber$)~
            {/@VOUCHER-VoucherProducts_data}
         {/VOUCHER-VoucherProducts_data}

         {DC-FPshowVariationBtn(true)}
            <button type="button" id="wsVoucherProductVariationBtn"
                    onclick="ws_AJAXloadTemplate('~BASKET-PR-ChangeLink~'+'&tpl=incl_voucher_product_change.htm&otp1=~BASKET-PR-ProdIndex~', '~WS-CharSet~', ws_AJAXVoucherProductChangeQuantityStart, ws_AJAXVoucherProductChangeQuantityError, 'ws_AJAXVoucherProductChangeQuantityResponseSuccess()', 'ws_AJAXVoucherProductChangeQuantityResponseError()');"
                    {BASKET-PR-UnresolvedVoucherProduct} style="display:none"{/BASKET-PR-UnresolvedVoucherProduct}>Gutscheinprodukt wählen</button>

            <script>
               function ws_AJAXVoucherProductChangeQuantityStart() {}
               function ws_AJAXVoucherProductChangeQuantityError() {}
               function ws_AJAXVoucherProductChangeQuantityResponseSuccess() {}
               function ws_AJAXVoucherProductChangeQuantityResponseError() {}

               $(document).on("change", '.select_dep_variations', function() {
                  $("#voucherProductForm_~BASKET-PR-ProdIndex~ input[name='js_dep_var']").val("on");
               });
            </script>
         {/DC-FPshowVariationBtn(true)}
      {/ST-BasketPage}
   {/@BASKET-PR-Data}
{/BASKET-PR-Data}
```

> [!NOTE]
>
> The switch `DC-FPshowVariationBtn` is reset for each basket item and only set if the item is either an unresolved voucher product or a voucher product with variants. As a result, the button only appears where there is something to choose.

#### The container for the display

The container belongs **outside** `FORM-Basket`, because the displayed template brings its own form and nested forms do not work in the browser.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{Incl-Basket}
   {ST-BasketPage}
      <div id="voucherProduct">
         <div id="voucherProductChangeAjax_~DC-SPvoucherProductIndex~"></div>
      </div>
   {/ST-BasketPage}
{/Incl-Basket}
```

#### The template `incl_voucher_product_change.htm`

Create a new template with this name in your template directory, for example under `benutzer/templates`, or in a multilingual shop in the directory of the respective subshop.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<WS-Ajax-voucherProductChangeAjax_~WS-OTP1~>
   {PR-Data}
      <form action="~FORM-Product~" method="post" id="voucherProductForm_~PR-Number~">

         {PR-Thumbnail}
            <img src="~PR-Thumbnail~" width="150" height="150" alt="~PR-Name~">
         {/PR-Thumbnail}

         {PR-DepVariationName1}
            ~PR-DepVariationName1~
            ~PR-DepVariationList1~
         {/PR-DepVariationName1}

         {PR-DepVariationName2}
            ~PR-DepVariationName2~
            ~PR-DepVariationList2~
         {/PR-DepVariationName2}

         {ST-PR_Change}
            ~PR-PrintHiddenDepVariations~
            <input type="hidden" name="tpl" value="incl_voucher_product_change.htm">
            <input type="hidden" name="otp1" value="~WS-OTP1~">
            <input type="hidden" name="otp2" value="~PR-Number~">
            <input type="hidden" name="~PR-Quantity_Input~" value="~PR-Quantity~">
         {/ST-PR_Change}

         <button type="submit"
                 {!ST-DepVar_OK} disabled{/!ST-DepVar_OK}{ST-DepVar_OK}{PR-Inventory}{PR-InventoryState(red-hard)} disabled{/PR-InventoryState(red-hard)}{/PR-Inventory}{/ST-DepVar_OK}>Speichern</button>

      </form>
   {/PR-Data}
</WS-Ajax-voucherProductChangeAjax_~WS-OTP1~>
```

> [!NOTE]
>
> The save button is disabled as long as no valid variant combination is selected or the selected combination is not available. This way, the buyer cannot submit a selection that the shop would then have to reject.

> [!WARNING]
>
> The name of the Ajax area, the container ID, and the `otp1` parameter must match. If they differ, the template loads, but the response does not end up in any container, and nothing visibly happens for the buyer.

Reference: VOUCHER-VoucherProducts\_data · BASKET-PR-ChangeLink · DC- · WS-OTP1

## Related topics

* Guide: Offering vouchers: Overview
* Guide: Create or import vouchers
* Guide: Provide voucher entry


## Related topics

- [Purchase vouchers for printing](https://dokumentation.websale.de/en/v8s/gutscheine-anbieten/kaufgutscheine-zum-ausdrucken.md)
- [Vouchers](https://dokumentation.websale.de/en/admin-interface/marketing/gutscheine.md)
- [Creating a purchase voucher product](https://dokumentation.websale.de/en/admin-interface/katalog/produkte/kaufgutschein-produkt.md)
- [Vouchers depending on product data](https://dokumentation.websale.de/en/v8s/gutscheine-anbieten/gutscheine-abhaengig-von-produktdaten.md)
- [Practical examples - Vouchers](https://dokumentation.websale.de/en/frontend/praxisbeispiele/gutscheine.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.