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

# External services and interfaces

> How to configure consent to data processing, how to connect captcha, Trusted Shops, newsletter management, and the affiliate program, and which interfaces the shop uses to talk to external systems.

Everything the shop addresses outside of itself is configured here. These are three different kinds of services.

First, the services concerned with the visitor's consent, that is, cookie consent and captcha. Then the business services the shop works with, from Trusted Shops through the e-marketing manager to the affiliate program. Finally, the technical interfaces through which data flows in both directions.

Reference: Shop configuration shop.config, overview of all sections

## `AgreementCookies`

The central section for consent to data processing. It defines which services the visitor can allow or reject individually or in groups. The selection is saved only when the visitor clicks a "Save settings" button.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<AgreementCookies>
   Allow = yes
   <+ConsentGroupInfo>
      ConsentGroupID = marketing
      Name           = Marketing
      Descr          = Dienste zur Reichweitenmessung und Werbung
   </+ConsentGroupInfo>
   <+Entry>
      Allow          = yes
      ID             = google-analytics
      Type           = OptIn
      Name           = Google Analytics
      Descr          = Misst die Nutzung unseres Shops.
      Preselection   = unchecked
      ConsentGroupID = marketing
   </+Entry>
   <+Entry>
      Allow           = yes
      ID              = komfort
      Type            = OptIn
      Name            = Komfortfunktionen
      Descr           = Merkt sich Ihren Warenkorb und Ihre Einstellungen.
      +WEBSALEService = CookieBasket
      +WEBSALEService = WelcomeCookie
   </+Entry>
</AgreementCookies>
```

> [!NOTE]
>
> The sample code in the source documentation closed the section with `<AgreementCookies>` instead of `</AgreementCookies>`. This has been corrected here.

### Main switch

| Parameter | Purpose | Values |
| - | - | - |
| `Allow` | Enable consent management | `no`, `yes`, `test`. Default: `no` |

`no` assumes the visitor has consented. The entire section then has no effect, all wrappers in the templates become active, all services run, and all cookies are set. The same applies if the section is not present in the `shop.config` at all.

`yes` activates the configured settings. In addition, the convenience functions are automatically disabled until they are configured and consent has been given. This affects the cookie basket, the welcome-back function, and affiliate, referrer, and design cookies.

`test` displays all positive `AC-AgreementMadeForID` areas, so the wrapped services run for every visitor.

> [!WARNING]
>
> The source documentation states that `Allow = test` also takes effect "for normal shop requests in live operation". However, the kernel only evaluates `test` if the shop is actually running in test mode. In live operation, `test` behaves like `no`.
>
> This difference matters, because it determines whether privacy-relevant services run for real visitors. Have this confirmed before you use `test`.

### `+Entry`

One subsection per service for which consent is to be requested.

| Parameter | Purpose | Values |
| - | - | - |
| `Allow` | enable this service entry | `yes`, `no`, `test`. Default: `yes` |
| `ID` | ID of the service | alphanumeric, hyphen, and underscore |
| `Name` | name of the service | text, maximum 128 characters |
| `Descr` | description of the service | text of any length |
| `Type` | type of consent | `OptIn`, `OptOutChecked`, `OptOutUnchecked`. Default: `OptIn` |
| `Preselection` | preselection of the checkbox | `checked`, `unchecked`. Default: `unchecked` |
| `ConsentGroupID` | assignment to a group | alphanumeric, hyphen, and underscore |
| `ExternalServiceID` | identifier of a special third-party service | in preparation |
| `+WEBSALEService` | WEBSALE convenience function bound to this service | see below |
| `iOSApp-AcceptViaTrackingFramework-List` | tracking status values from the iOS app for which this entry becomes active | see below |

`OptIn` means: the visitor checks the checkbox and thereby gives consent. `OptOutChecked` means: a checked checkbox counts as an objection. `OptOutUnchecked` means: an **unchecked** checkbox counts as an objection.

> [!NOTE]
>
> The checkbox for an entire group is always implemented as `OptIn`. It does, however, correctly process the different types of the services it contains.

#### WEBSALE convenience functions

Use a separate `+WEBSALEService` parameter for each function.

| Value | Function |
| - | - |
| `CookieBasket` | Cookie basket |
| `WelcomeCookie` | Welcome-back function |
| `DesignCookie` | Design cookie `DC-CookieData` |
| `RefererCookie` | Passing referrers |
| `AffiliateProgram` | Affiliate program |
| `TellAFriendCookie` | Tell-a-friend function |

> [!WARNING]
>
> `RefererCookie` and `AffiliateProgram` should always be in the same group, because the two services are partly connected. Separate consent leads to gaps in advertising performance tracking.

#### Tracking status from the iOS app

Since iOS 14.5, the AppTrackingTransparency framework asks users when they first open the app whether they allow tracking. The framework passes the status to the WEBSALE app in the HTTP header. With `iOSApp-AcceptViaTrackingFramework-List`, you define as a comma-separated list for which status values this entry becomes active.

| Value | Meaning |
| - | - |
| `authorized` | the user allows tracking |
| `denied` | the user rejects tracking |
| `not_determined` | the user has not decided yet |
| `restricted` | tracking is disabled globally on the device |
| `pre_ios14` | the device runs an iOS version earlier than 14, which has no framework |
| `always` | the service is activated regardless of the value passed |

> [!NOTE]
>
> When the iOS app is used, no consent layer is displayed. Instead, the user makes the decision in the framework.

### `+ConsentGroupInfo`

Combines several services into a group that the visitor can allow or reject together.

| Parameter | Purpose | Values |
| - | - | - |
| `ConsentGroupID` | ID as used in the `+Entry` sections | alphanumeric |
| `Name` | name of the group | text, maximum 128 characters |
| `Descr` | description of the group | text of any length |

The order of the `+ConsentGroupInfo` sections determines the display order in the template. Ungrouped services appear below them.

> [!NOTE]
>
> If there are services without a `ConsentGroupID`, the shop automatically creates a group with the ID `ws_noconsentgroupfound` and assigns all these services to it.

## Captcha

You can integrate two captcha services. Both are configured here; the associated tags are described on their own pages.

### `ReCaptchaV3`

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<ReCaptchaV3>
   SiteKey            = 6Lxxxxxxxxxxxxxxxxxxxx
   SecretKey          = 6Lyyyyyyyyyyyyyyyyyyyy
   APIUrl             = https://www.google.com/recaptcha/api.js
   VerifyUrl          = https://www.google.com/recaptcha/api/siteverify
   MinimumScoreToPass = 0.5
</ReCaptchaV3>
```

| Parameter | Purpose | Values |
| - | - | - |
| `SiteKey` | site key from Google | key |
| `SecretKey` | secret key from Google | key |
| `APIUrl` | URL of the reCAPTCHA API | URL |
| `VerifyUrl` | URL for verifying the response | URL |
| `MinimumScoreToPass` | score from which a visitor counts as human | 0.1 to 1.0. Default: 0.5 |

reCAPTCHA returns a score between 0 and 1. 0 means very likely a bot, 1 very likely a human. Use `MinimumScoreToPass` to fine-tune the threshold.

Reference: RECAPTCHAV3 tags

### `FriendlyCaptchaV1`

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<FriendlyCaptchaV1>
   ApplicationID = ABCDEFGH12345678
   APIKey        = A1B2C3D4E5F6
   APIUrl        = https://eu-api.friendlycaptcha.eu/api/v1/puzzle
   VerifyUrl     = https://eu-api.friendlycaptcha.eu/api/v1/siteverify
</FriendlyCaptchaV1>
```

| Parameter | Purpose |
| - | - |
| `ApplicationID` | ApplicationID from the FriendlyCaptcha backend |
| `APIKey` | API key from FriendlyCaptcha |
| `APIUrl` | URL of the FriendlyCaptcha API |
| `VerifyUrl` | URL for verifying the response |

FriendlyCaptcha offers a global endpoint and an EU endpoint. Which one applies to you is stated in the FriendlyCaptcha documentation.

Reference: FRIENDLYCAPTCHAV1 tags

## Trusted Shops

### `TrustedShopsAdvList`

Defines the buyer protection products offered to the customer for selection. One `+Entry` subsection per product.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<TrustedShopsAdvList>
   VATType       = static
   VATRate-Value = 1
   <+Entry>
      TSID-Txt      = TS080501_500_30_EUR
      ERPID-Txt     =
      ListName-Txt  = Käuferschutz bis 500 Euro (0,98 Euro inkl. MwSt.)
      OrderName-Txt = Käuferschutz bis 500 Euro
      Cost-Value    = 0.98
   </+Entry>
   <+Entry>
      TSID-Txt      = TS080501_1500_30_EUR
      ListName-Txt  = Käuferschutz bis 1.500 Euro (2,94 Euro inkl. MwSt.)
      OrderName-Txt = Käuferschutz bis 1.500 Euro
      Cost-Value    = 2.94
   </+Entry>
</TrustedShopsAdvList>
```

| Parameter | Purpose | Values |
| - | - | - |
| `VATType` | how the VAT rate for buyer protection is determined | `dynamic`, `static`. Default: `static` |
| `VATRate-Value` | VAT index, only with `static` | 1 to 10. Default: 1 |

Per `+Entry`:

| Parameter | Purpose | Values |
| - | - | - |
| `TSID-Txt` | Trusted Shops product ID. Passed exactly as entered | ID as specified by Trusted Shops |
| `ERPID-Txt` | optional item number from the ERP system | number |
| `ListName-Txt` | entry in the selection list | text |
| `OrderName-Txt` | text in the order data | text |
| `Cost-Value` | cost of the buyer protection product | amount |

> [!WARNING]
>
> `TSID-Txt` must match the Trusted Shops specification exactly. The shop passes this value unchanged.
>
> You only need `ERPID-Txt` if your ERP system cannot process the Trusted Shops product ID directly.

### `TrustedShops-Txt`

Texts for the confirmation page after an order, through which the buyer can register with Trusted Shops.

| Parameter | Purpose |
| - | - |
| `HeadLine` | title text |
| `Line2` to `Line5` | body text describing the service |

> [!WARNING]
>
> This section belongs to an outdated form of the Trusted Shops integration. The current integration uses `TrustedShopsAdvList`. Only use `TrustedShops-Txt` in existing shops that still rely on it.

## `eMarketingManager`

The templates for newsletter management and the online view of the newsletter. In the configuration, the section is called `eMarketingManager`, without hyphens.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<eMarketingManager>
   Manage         = incl_newsletter.htm
   OnlineView     = incl_newsletter_onlineview.htm
   ShopManage     = tpl_newsletter.htm
   ShopOnlineView = tpl_newsletter_onlineview.htm
</eMarketingManager>
```

| Parameter | Purpose |
| - | - |
| `Manage` | ExternInclude area for target group management |
| `OnlineView` | ExternInclude area for the online view in the shop |
| `ShopManage` | shop template that includes `Manage` |
| `ShopOnlineView` | shop template that includes `OnlineView` |

> [!NOTE]
>
> In the sample code of the source documentation, the explanations for `ShopManage` and `ShopOnlineView` were swapped. This has been corrected here. Each shop template includes the include area of the same name.

### `eMarketingManager-Txt`

The success and error messages related to newsletter subscription.

| Parameter | Appears when |
| - | - |
| `NoEmail` | no valid email address was entered |
| `NoTargetgroupSelected` | no area of interest was selected |
| `TargetgroupAlreadySubscribed` | the visitor is already subscribed to all selected areas |
| `InputTooLong` | the input exceeds the maximum length |
| `MaxSubscriber` | no further subscribers can be accepted at this time |
| `WaitVerification` | a confirmation email has already been sent |
| `OldVerification` | the validity period of the subscription link has expired |
| `VerificationError` | confirmation of the email address failed |
| `ErrorCreate` | an error occurred while creating the data |
| `IncorrectConfiguration` | the service cannot be used due to missing configuration |
| `Error` | a general error occurred |
| `SubscriberOnly` | the address is not subscribed to the newsletter |
| `VerifiedOK` | the email address was confirmed successfully |
| `SubscribedOK` | the subscription was successful |
| `UnsubscribedOK` | the unsubscription was successful |
| `VerifyEmailSent` | a confirmation email was sent |
| `BlackListed` | the visitor was unsubscribed from all newsletters and added to the blacklist |

## `WSAffiliateTemplates`

The banner templates for the WEBSALE affiliate program. You only need this section if partners may use every product in the shop as a banner in addition to the banners you have created, the so-called dynamic banners.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<WSAffiliateTemplates>
   Start    = ws_affiliate_start.htm
   Category = ws_affiliate_category.htm
   Product  = ws_affiliate_product.htm
</WSAffiliateTemplates>
```

| Parameter | Purpose |
| - | - |
| `Start` | start page for banner selection |
| `Category` | category page for banner selection |
| `Product` | product detail page for banner selection |

> [!NOTE]
>
> In the source documentation, all three parameters used the same example `ws_affiliate_category.htm`. Descriptive examples are used here so the assignment remains clear.

## `ExternSystemLiveChecks`

Checks the availability of external systems. Up to ten `+Entry` subsections, each with its own ID. You use this ID as the argument of the area tag `WS-ExternSystemLiveCheck()`.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<ExternSystemLiveChecks>
   <+Entry>
      ID        = search
      URL       = https://suche.beispiel.de/alivetest.php
      Type      = 2
      CheckMode = failPersistant
      Timeout   = 1000
   </+Entry>
</ExternSystemLiveChecks>
```

| Parameter | Purpose | Values |
| - | - | - |
| `ID` | unique identifier for the tag | text, must not be empty |
| `URL` | address of the LiveCheck request | URL, must not be empty |
| `Type` | type of check | `1` for any service provider, `2` for the Findologic alive test |
| `CheckMode` | when the check runs | `always`, `failPersistant`, `successPersistant`. Default: `always` |
| `Timeout` | response time in milliseconds | 1 to 3000. Default: 3000 |

`always` sends a request for every check. `failPersistant` keeps sending requests until the check fails for the first time, and then treats it as failed for the rest of the session. `successPersistant` works the other way around and treats the whole session as successful after the first success.

> [!WARNING]
>
> A `+Entry` is silently skipped if `ID` is empty, `URL` is empty, or `Type` does not contain a valid number. Every tag that uses such a dropped ID as its argument remains unreplaced in the template.
>
> The previous documentation only lists `ID` and `Type` as required parameters. The fact that an empty `URL` also discards the entry has been added here.
>
> A `Timeout` of 0 or above the maximum is silently set to the maximum.

> [!WARNING]
>
> Choosing the timeout is a trade-off. Too small, and the check fails even though the external system is available. Too large, and page rendering is noticeably delayed if the system cannot be reached.

### Interface for type 1

With `Type = 1`, the shop sends an HTTP GET request to the specified URL. If the system responds with `OK`, the check counts as successful. Any other response and any missing response count as a failure.

```php theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<?php
// Eigene Prüfungen implementieren, dabei keine Ausgaben erzeugen.
// Ergebnis in $result ablegen.
if ($result == true)
    echo "OK";
else
    echo "Not OK";
```

Reference: WS-ExternSystemLiveCheck()

## `IDSSchnittstelle`

Configures the integrated data interface IDS. The sender data is sent to the requesting system; the remaining parameters control the transfer format.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<IDSSchnittstelle>
   SupplierName             = Mein Shop GmbH
   SupplierStreet           = Musterstraße 1
   SupplierPCode            = 90000
   SupplierCity             = Nürnberg
   SupplierCountry          = Deutschland
   SupplierPhone            = 0911 1234567
   SupplierEmail            = info@mein-shop.de
   SendVatInPercent         = yes
   RueckgabeKZ              = yes
   EncodeOrderInfo          = no
   GenerateOrderInfoIfEmpty = yes
   ClearBasket              = yes
   SurchargeAsOrderItem     = yes
</IDSSchnittstelle>
```

### Sender data

| Parameter | Purpose |
| - | - |
| `SupplierName` | company name of the shop operator |
| `SupplierStreet` | street and house number |
| `SupplierPCode` | postal code |
| `SupplierCity` | city |
| `SupplierCountry` | country |
| `SupplierPhone` | phone number |
| `SupplierEmail` | email address |

### Transfer format

| Parameter | Purpose | Values |
| - | - | - |
| `WriteToOrderFile` | write an IDS area with a hex-encoded basket to the order data | `yes`, `no`. Default: `no` |
| `SendVatInPercent` | pass VAT as a percentage instead of an amount | `yes`, `no`. Default: `no` |
| `RueckgabeKZ` | pass a return flag indicating whether an order was placed | `yes`, `no`. Default: `no` |
| `EncodeOrderInfo` | pass OrderInfo XML-encoded | `yes`, `no`. Default: `yes` |
| `GenerateOrderInfoIfEmpty` | generate missing required fields of the OrderInfo | `yes`, `no`. Default: `no` |
| `ResetStateAfterSend` | reset the internal IDS status after sending | `yes`, `no`. Default: `no` |
| `ClearBasket` | empty the basket with every new IDS request | `yes`, `no`. Default: `no` |
| `SurchargeAsOrderItem` | create a separate OrderItem for the small-quantity surcharge | `yes`, `no`. Default: `no` |
| `SendPriceBasis` | also pass the price basis | `yes`, `no`. Default: `no` |

> [!NOTE]
>
> For the LABELWIN ERP system, five of these switches are predefined: `SendVatInPercent = yes`, `RueckgabeKZ = yes`, `EncodeOrderInfo = no`, `GenerateOrderInfoIfEmpty = yes`, `ClearBasket = yes`, and `SurchargeAsOrderItem = yes`.
>
> `SendPriceBasis` is not described in the previous documentation and has been added here.

> [!WARNING]
>
> The IDS interface must also be enabled for the shop. This activation is not a `shop.config` setting; it is done by WEBSALE AG. Without it, the entire section has no effect.

## `ASSE`

The interface for asynchronous data transfer, Asynchronous Server Side Events. One `+Entry` subsection per transfer target.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<ASSE>
   <+Entry>
      ID              = tracking
      Endpoint        = https://tracking.beispiel.de/event
      Type            = Post
      ContentType     = application/json
      ServiceCategory = Tracking
      <DefinitionOfOK>
         <+ConditionGroup>
            <+Condition>
               Proof = HTTPStatusCode
               Type  = value
               Value = 200
            </+Condition>
         </+ConditionGroup>
      </DefinitionOfOK>
      <AdditionalHeaders>
         <+HttpHeader>
            Name  = X-Api-Key
            Value = geheim
         </+HttpHeader>
      </AdditionalHeaders>
   </+Entry>
</ASSE>
```

### `+Entry`

| Parameter | Purpose | Values |
| - | - | - |
| `ID` | unique identifier | alphanumeric, maximum 64 characters |
| `Endpoint` | target of the transfer. WEBSALE tags are allowed | URL |
| `Type` | HTTP method | `Post`, `Get`, `Put`. Default: `Post` |
| `PayloadParameterName` | optional parameter name before the payload | text |
| `ContentType` | data format | for example `application/json` |
| `ServiceCategory` | controls retries, intervals, and timeout | `Tracking`, `OrderNotification` |

> [!WARNING]
>
> `ID` and `Endpoint` are required. If either is missing, the entry is discarded.
>
> Unlike most sections of the `shop.config`, `ASSE` reports configuration errors. An empty `ID`, an empty `Endpoint`, an unknown `Type`, and an unknown `ServiceCategory` each produce an internal error message. This is not described in the previous documentation and has been added here.
>
> `ASSE` also requires activation by WEBSALE AG, which happens outside the `shop.config`.

The values of `ServiceCategory` are predefined by WEBSALE. They correspond to different settings for retries and timeouts.

### `DefinitionOfOK`

Optional section with the conditions for successful delivery. If it is missing, the data is sent once and the result is not checked.

The `+ConditionGroup` sections are combined with **or**, the `+Condition` sections within them with **and**.

| Parameter | Purpose | Values |
| - | - | - |
| `Proof` | what is checked | see below |
| `DataSelector` | selection of the data field, only with `Proof = ResponseJSONData` | field identifier |
| `Type` | type of check | `filled`, `empty`, `value`, `notvalue`, `inlist`, `notinlist`, `greater`, `smaller` |
| `Value` | value checked, not relevant for `filled` and `empty` | text |

| `Proof` | checks |
| - | - |
| `HTTPStatusCode` | the status code of the response, for example 200 |
| `ContentType` | the data format of the response |
| `ResponsePlain` | the response as plain text, for example `OK` |
| `ResponseJSON` | the same in JSON format |
| `ResponseJSONData` | individual fields of the returned JSON data. Requires `DataSelector` and `Type` |

### `AdditionalHeaders`

Optional section for additional HTTP headers. One `+HttpHeader` subsection with `Name` and `Value` per header.

## `Upload`

Activates the upload module and stores the associated texts.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Upload>
   Allow                    = yes
   ID-Txt                   = Upload-ID
   PositionID-Txt           = Position-ID
   Link-Txt                 = Upload-Link
   OrderDataUploadLink-Type = UploadLink
</Upload>
```

| Parameter | Purpose | Values |
| - | - | - |
| `Allow` | enable the upload module | `yes`, `no`. Default: `no` |
| `ID-Txt` | text for the upload ID input field | text |
| `PositionID-Txt` | text for the position ID input field | text |
| `Link-Txt` | text for the upload link | text |
| `OrderDataUploadLink-Type` | type of link in the order data | `UploadLink`, `UploadLinkOrderNumber`. Default: `UploadLink` |

`UploadLink` writes a deep link with a secured upload ID to the order data. `UploadLinkOrderNumber` instead writes a deep link with a secured order number.

## `Download`

The texts and URL logic for the download module.

```ini theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
<Download>
   ID-Txt   = Download-ID
   Link-Txt = Download-Link
   URLType  = default
</Download>
```

| Parameter | Purpose | Values |
| - | - | - |
| `ID-Txt` | text for the download ID | text |
| `Link-Txt` | text for the download link | text |
| `URLType` | type of URL in the download templates | `default`, `relative`. Default: `default` |

`default` uses an absolute URL configured globally for all shops. `relative` inserts relative URLs. Which domain the browser then displays depends on the URL through which the download module was called.

## `TellAFriend`

Controls whether and how the referrer information from the tell-a-friend function is written to the order data. The section is fully described on the page about the TAF tags and is therefore only linked here.

Reference: TAF tags and TellAFriend section


## Related topics

- [External services: Overview](https://dokumentation.websale.de/en/v8s/externe-dienste/externe-dienste.md)
- [Interfaces](https://dokumentation.websale.de/en/schnittstellen.md)
- [Wish list, comparison, upload and external services](https://dokumentation.websale.de/en/v8s/referenz/tags/ws/merkzettel-vergleich-upload-und-externe-dienste.md)
- [JSON interface](https://dokumentation.websale.de/en/v8s/externe-dienste/json-schnittstelle.md)


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