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

# EJD- (JSON interface)

> Read, iterate over, modify and create JSON data in the template: your own files from the FTP access, internally available data and JSON objects you build yourself.

With the JSON interface, a template brings data into the shop that does not come from the product data: a nutrition table per item, sales figures for the signed-in customer, the response of a payment service provider. Conversely, it also builds JSON that the shop passes on to a tracking or external system.

The tags with the prefix `EJD-` (External JSON Data) give you access to this. They cover three tasks.

| Task | Entry tag |
| - | - |
| read your own JSON file from the FTP access | `EJD-LoadData(global…)` or `EJD-LoadData(subshop…)` |
| read internally available JSON data | `EJD-LoadData(intern…)` |
| build new JSON in the template | `EJD-CreateNewData()` |

Guide: JSON interface

## The process

Every access runs in three steps: load, check, access. When loading, the data gets a freely chosen **ID** by which all further tags find it again.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(global,$PR-Number$.json,jdat)~

{EJD-DataOK(jdat)}
   ~EJD-SetUseID(jdat)~

   Beschreibung: ~EJD-DA-Value(AdditionalInfo.Beschreibung)~
{/EJD-DataOK(jdat)}

{!EJD-DataOK(jdat)}
   <!-- keine Zusatzdaten zu diesem Produkt -->
{/!EJD-DataOK(jdat)}
```

> [!NOTE]
>
> Several JSON data sets can be kept loaded at the same time. The ID keeps them apart. That is why every access tag carries the ID as its last parameter, and `EJD-SetUseID()` saves you from repeating it every time.

The examples on this page refer to this file:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
   "Produktname": "Sportlicher Sneaker",
   "Produktnummer": "A-1234",
   "AdditionalInfo": {
      "Beschreibung": "Moderne Schuhe für jeden Anlass",
      "lieferbar": true,
      "Crosslinks": [ "A-5678", "B-9876", "C-2323" ],
      "Lagerbestand": 42,
      "Preis": 59.95
   }
}
```

## Loading data

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(Typ,Pfad,ID)~
```

### The type

| Type | Where the data comes from |
| - | - |
| `global` | from the main directory of the JSON interface's FTP access, the same for all subshops |
| `subshop` | from the subdirectory of the currently called subshop |
| `userdir` | from any directory below `benutzer` on the shop's FTP server |
| `intern` | from data that the shop or an external system already provides, without file access |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(global,file.json,jdat)~
~EJD-LoadData(global,unterverzeichnis/file.json,jdat)~
~EJD-LoadData(subshop,file.json,jdat)~
~EJD-LoadData(userdir,navigation/grafiken/JSON/file.json,jdat)~
```

> [!NOTE]
>
> With the `subshop` type, the shop selects the matching subdirectory itself. In the English subshop, `~EJD-LoadData(subshop,file.json,jdat)~` therefore loads the file `/English/file.json`. The same line in the template thus works in all subshops.

### The path with the "intern" type

With the `intern` type, the second parameter does not contain a file but the technical name of the provided data.

| Name | Content |
| - | - |
| `rawdatainput` | the data passed with `EJD-SetRawDataInput()` |
| `rawdatahexcodedinput` | the data passed with `EJD-SetRawDataHexCodedInput()` |
| `hreflang-start` | hreflang information for the home page of the connected subshops |
| `hreflang-global-start` | the same for all connected subshops |
| `hreflang-cat-<CatIndex>` | hreflang information for a category page |
| `hreflang-global-cat-<CatIndex>` | the same for all connected subshops |
| `hreflang-prod-<ProdIndex>` | hreflang information for a product page |
| `hreflang-global-prod-<ProdIndex>` | the same for all connected subshops |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(intern,hreflang-cat-$CAT-Index$,href)~
~EJD-LoadData(intern,hreflang-prod-$PR-ProdIndex$,href)~
```

In addition, individual modules provide their responses.

| Name | Module |
| - | - |
| `PaymorrowGetPaymentTokenResponse` | Paymorrow, request of the payment token |
| `PaymorrowAuthorizeByRefResponse` | Paymorrow, authorization of the payment |
| `PaymorrowDebitAuthorizeByRefResponse` | Paymorrow, direct debit |
| `TaxJarTaxesRequest` | TaxJar, tax calculation |
| `TaxJarTaxRateForZIP` | TaxJar, tax rate for a postal code |

> [!NOTE]
>
> The last three are not listed in the previous documentation but exist in the shop. Further names are added with new modules; ask WEBSALE AG or the respective service provider about them.

> [!NOTE]
>
> With internal data, you often do not know in advance which fields will be delivered. `EJD-RawDataOutput()` outputs the complete data set and is the fastest way to get an overview.

## Checking whether loading succeeded

`EJD-DataOK()` brackets on success. As a single tag, it outputs the error code.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{EJD-DataOK(jdat)}
   <!-- Daten liegen vor -->
{/EJD-DataOK(jdat)}

{!EJD-DataOK(jdat)}
   <!-- Fehlercode: ~EJD-DataOK(jdat)~ -->
{/!EJD-DataOK(jdat)}
```

| Code | Meaning |
| - | - |
| 0 | data OK |
| 1 | unknown value for the type |
| 4 | file path incorrect or file not found |
| 5 | error parsing the file |
| 6 | internal JSON data is empty |
| 7 | unknown name with the `intern` type |
| 8 | file path not configured |
| 999 | internal error during initialization |
| 9999 | ID not loaded |

> [!WARNING]
>
> `EJD-DataOK()` always needs the ID written out. `EJD-SetUseID()` has no effect here, since it only appears inside the bracket itself.

## Setting the ID once

`EJD-SetUseID()` defines the ID that all subsequent access tags use if they are not given one themselves.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{EJD-DataOK(jdat)}
   ~EJD-SetUseID(jdat)~

   Preis: ~EJD-DA-Value(AdditionalInfo.Preis)~
   Bestand: ~EJD-DA-Value(AdditionalInfo.Lagerbestand)~
{/EJD-DataOK(jdat)}
```

> [!NOTE]
>
> For all access, check and modification tags, the ID is therefore **optional**. The previous documentation lists it as a mandatory parameter on the individual pages. It is only necessary if no default ID is set or if you switch between several data sets.

> [!NOTE]
>
> The default ID can be set again as often as you like. With several data sets loaded at the same time, you use it to switch back and forth.

## The access path

All access tags expect the path to the element as their first parameter.

| Notation | Meaning |
| - | - |
| `Produktname` | an element at the top level |
| `AdditionalInfo.Beschreibung` | an element in an object, levels separated by a period |
| `AdditionalInfo.Crosslinks[0]` | the first element of an array, counted from 0 |
| empty or `_root_` | the root element itself |

> [!WARNING]
>
> Array elements are counted from 0. The first element is `[0]`. That is why `DC-ZeroLoopX` is a better fit as a loop over an array than `DC-LoopX`, which counts from 1.

## Reading values

| Tag | Returns |
| - | - |
| `EJD-DA-Value()` | the value of the element |
| `EJD-DA-NameExists()` | applies if there is an element with this name |
| `EJD-DA-ArrayElements()` | the number of elements in an array |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Nummer: ~EJD-DA-Value(Produktnummer,jdat)~
Beschreibung: ~EJD-DA-Value(AdditionalInfo.Beschreibung,jdat)~

{EJD-DA-NameExists(AdditionalInfo.Crosslinks,jdat)}
   Anzahl der Crosslinks: ~EJD-DA-ArrayElements(AdditionalInfo.Crosslinks,jdat)~
{/EJD-DA-NameExists(AdditionalInfo.Crosslinks,jdat)}
```

> [!NOTE]
>
> As an area tag, `EJD-DA-ArrayElements()` only applies if the element really is an array **and** is not empty. The bracket thus answers in one step whether a loop is worthwhile at all.

### Checking the type of a value

JSON has several value types. Eight area tags check which one is present.

| Tag | Applies to |
| - | - |
| `EJD-DA-IsString()` | a string |
| `EJD-DA-IsNumber()` | an integer |
| `EJD-DA-IsReal()` | a floating-point number |
| `EJD-DA-IsObject()` | an object |
| `EJD-DA-IsArray()` | an array |
| `EJD-DA-IsTrue()` | the value `true` |
| `EJD-DA-IsFalse()` | the value `false` |
| `EJD-DA-IsNull()` | the value `null` |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{EJD-DA-IsTrue(AdditionalInfo.lieferbar,jdat)}
   <span class="lieferbar">sofort lieferbar</span>
{/EJD-DA-IsTrue(AdditionalInfo.lieferbar,jdat)}

{EJD-DA-IsNull(AdditionalInfo.lieferbar,jdat)}
   <span>keine Angabe zur Lieferbarkeit</span>
{/EJD-DA-IsNull(AdditionalInfo.lieferbar,jdat)}
```

> [!WARNING]
>
> The eight check tags are pure area tags. Written as a single tag, they have no effect.

> [!NOTE]
>
> With third-party data, type checking is worthwhile. A field that was a number yesterday and is `null` today otherwise leaves an unchecked output empty.

## Reusing values

The access tags carry parameters. This means they cannot be written as `$…$` in another tag, because tag-in-tag only works with single tags without their own argument.

That is why the shop remembers the addressed name and value with every access. Two parameterless tags output them again.

| Tag | Returns |
| - | - |
| `EJD-LastNameAccessed` | the most recently accessed name |
| `EJD-LastValueAccessed` | the most recently accessed value |

| These tags remember the name | These tags remember the value |
| - | - |
| `EJD-DA-NameExists()`, `EJD-DA-TouchName()` | `EJD-DA-Value()`, `EJD-DA-TouchValue()`, all eight `EJD-DA-Is…()`, `EJD-DA-ArrayElements()`, `EJD-DA-TouchArrayElements()` |

`EJD-DA-TouchName()`, `EJD-DA-TouchValue()` and `EJD-DA-TouchArrayElements()` exist only for this purpose: they remember something without outputting anything themselves.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-DA-TouchArrayElements(AdditionalInfo.Crosslinks,jdat)~
~DC-ZeroLoopCross_set($EJD-LastValueAccessed$)~

{@DC-ZeroLoopCross}
   Crosslink ~DC-ZeroLoopCross_position~:
   ~EJD-DA-Value(AdditionalInfo.Crosslinks[$DC-ZeroLoopCross_position$],jdat)~<br>
{/@DC-ZeroLoopCross}
```

Output:

```text theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
Crosslink 0: A-5678
Crosslink 1: B-9876
Crosslink 2: C-2323
```

> [!NOTE]
>
> This is the standard pattern for arrays: remember the count, set up a counting loop with it, and insert the position as the index. `DC-ZeroLoopX` counts from 0 and thus matches the array indexes exactly.

Reference: DC- (loops)

## Iterating over elements

For an object whose keys you do not know, a counting loop does not help. `EJD-ElementIterator()` instead runs over the children of an element and outputs their names.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(global,D200297.json,bezuege)~

{EJD-DataOK(bezuege)}
   ~EJD-SetUseID(bezuege)~

   {@EJD-ElementIterator(Items)}
      Artikel: ~EJD-ElementIterator~<br>
      Letztes Jahr: ~EJD-DA-Value(Items.$EJD-ElementIterator$.Sales PY)~<br>
      Dieses Jahr: ~EJD-DA-Value(Items.$EJD-ElementIterator$.Sales CY)~<br>
   {/@EJD-ElementIterator(Items)}
{/EJD-DataOK(bezuege)}
```

> [!NOTE]
>
> As a single tag inside the loop, `EJD-ElementIterator` outputs the name of the current element. Because it is then parameterless, it can be inserted into the access path as `$EJD-ElementIterator$`. The pattern above is based on exactly this.

> [!WARNING]
>
> The loop can be nested, but only up to a fixed depth of ten levels. If this is exceeded, the shop writes a critical error to the log and the loop does not start.

## Outputting floating-point numbers

`EJD-SetRealOutputFormat()` defines how many decimal places floating-point numbers are output with. Values from 0 to 6 are permitted.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-DA-Value(AdditionalInfo.Preis,jdat)~        <!-- 59.95 -->
~EJD-SetRealOutputFormat(4)~
~EJD-DA-Value(AdditionalInfo.Preis,jdat)~        <!-- 59.9500 -->
```

> [!WARNING]
>
> A value outside 0 to 6 makes the tag invalid; the previous setting then remains in place. The setting applies from the point in the template at which it is set, and for all loaded data sets.

## Creating and modifying JSON

`EJD-CreateNewData()` creates an empty JSON object that you fill in the template.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-CreateNewData(jdat)~
~EJD-DA-SetStringValue(Straße,$A-Street1$,jdat)~
~EJD-RawDataOutput(jdat)~
```

Output:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ "Straße": "Gutenstetter Str. 2" }
```

| Tag | Sets the value to |
| - | - |
| `EJD-DA-SetStringValue()` | the specified string |
| `EJD-DA-SetNumberValue()` | the specified integer |
| `EJD-DA-SetRealValue()` | the specified floating-point number |
| `EJD-DA-SetToTrue()` | `true` |
| `EJD-DA-SetToFalse()` | `false` |
| `EJD-DA-SetToNull()` | `null` |
| `EJD-DA-SetToEmptyObject()` | an empty object |
| `EJD-DA-SetToEmptyArray()` | an empty array |

| Tag | Effect |
| - | - |
| `EJD-DA-ArrayExtend()` | appends an element with the value `null` to an array |
| `EJD-DA-DeleteElement()` | deletes an element |

> [!NOTE]
>
> All these tags work not only on newly created data but also on loaded data. This lets you enrich a file you have read in within the template and then pass it on.

> [!WARNING]
>
> If the path already exists, the previous value is replaced. If it does not exist yet, it is created, provided the parent element exists. `EJD-DA-ArrayExtend()` and `EJD-DA-DeleteElement()`, on the other hand, do not create anything: if their path leads nowhere, they report an error.

> [!WARNING]
>
> The root element can only be turned into an object or an array. Any attempt to give it a simple value ends with error code 14.

### Building an array

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-CreateNewData(jdat)~
~EJD-DA-SetToEmptyArray(Crosslinks,jdat)~          <!-- { "Crosslinks": [] } -->

~EJD-DA-ArrayExtend(Crosslinks,jdat)~              <!-- [ null ] -->
~EJD-DA-ArrayExtend(Crosslinks,jdat)~              <!-- [ null, null ] -->

~EJD-DA-SetStringValue(Crosslinks[0],A1234,jdat)~
~EJD-DA-SetStringValue(Crosslinks[1],B5678,jdat)~

~EJD-RawDataOutput(jdat)~
```

Output:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ "Crosslinks": [ "A1234", "B5678" ] }
```

> [!NOTE]
>
> If the root element itself is to be an array, specify `_root_` as the path: `~EJD-DA-SetToEmptyArray(_root_,jdat)~` results in `[]`.

### An example from tracking

Build a JSON with the index and price of all displayed products on the product overview page:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-CreateNewData(jdat)~

{EJD-DataOK(jdat)}
   ~EJD-DA-SetToEmptyArray(data,jdat)~
   ~EJD-DA-ArrayExtend(data,jdat)~
   ~EJD-DA-SetToEmptyObject(data[0],jdat)~
   ~EJD-DA-SetStringValue(data[0].event_name,ViewContent,jdat)~

   {CAT-Data}
      ~EJD-DA-SetToEmptyArray(data[0].contents,jdat)~
      ~DC-Int1_set(0)~

      {@PR-Data}
         ~EJD-DA-ArrayExtend(data[0].contents,jdat)~
         ~EJD-DA-SetToEmptyObject(data[0].contents[$DC-Int1$],jdat)~
         ~EJD-DA-SetStringValue(data[0].contents[$DC-Int1$].id,$PR-ProdIndex$,jdat)~

         ~WS-DisablePriceAndNumberFormat~
         ~EJD-DA-SetRealValue(data[0].contents[$DC-Int1$].item_price,$PR-Price$,jdat)~
         ~WS-EnablePriceAndNumberFormat~

         ~DC-Int1_inc~
      {/@PR-Data}
   {/CAT-Data}
{/EJD-DataOK(jdat)}

~EJD-RawDataOutput(jdat)~
```

> [!WARNING]
>
> Turn off price formatting before you pass a price as a number. Otherwise, it arrives with thousands separators and a decimal comma and is truncated when converted to a number.

### Checking whether the modification succeeded

`EJD-ModificationOK` brackets on the success of the last modification and, as a single tag, outputs the error code.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-DA-SetToFalse(AdditionalInfo.lieferbar,jdat)~

{!EJD-ModificationOK}
   <!-- Fehler: ~EJD-ModificationOK~ -->
{/!EJD-ModificationOK}

~EJD-ResetModificationOK~
```

> [!WARNING]
>
> The error code persists even if the next modification succeeds. Therefore, reset it after every check with `EJD-ResetModificationOK`; otherwise, all subsequent checks report the same old error.

| Code | Cause |
| - | - |
| 0 | OK |
| 1 | attempt to modify a non-existent array entry |
| 2 | the parent element of the path does not exist |
| 3 to 5 | internal memory error |
| 6 | `EJD-DA-ArrayExtend()` or `EJD-DA-DeleteElement()`: element does not exist |
| 7 | no data found with this ID |
| 8 | the raw data could not be regenerated after the modification |
| 9 to 12 | `EJD-DA-DeleteElement()` failed |
| 13 | `EJD-DA-ArrayExtend()`: the element is not an array |
| 14 | attempt to change the root element to something other than an object or array |
| 15 | `EJD-DA-SetStringValue()`: the passed value could not be resolved |

> [!NOTE]
>
> Code 15 is not listed in the previous documentation but exists in the shop.

## Inputting and outputting raw data

| Tag | Effect |
| - | - |
| `EJD-RawDataOutput()` | outputs the complete data set as JSON |
| `EJD-SetRawDataInput()` | passes JSON as plain text to the interface |
| `EJD-SetRawDataHexCodedInput()` | passes hex-encoded JSON to the interface |

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-SetRawDataInput($XYZ-technischeBezeichnung-JSON$)~
~EJD-LoadData(intern,rawdatainput,jdat)~

~EJD-RawDataOutput(jdat)~
```

> [!WARNING]
>
> The two input tags belong together with the matching name when loading: `EJD-SetRawDataInput()` with `rawdatainput`, `EJD-SetRawDataHexCodedInput()` with `rawdatahexcodedinput`. If they are mixed up, the interface delivers unusable data because hex-encoded characters are read as plain text or vice versa.

> [!WARNING]
>
> `EJD-RawDataOutput()` outputs the data **without HTML encoding**. This is intentional so that valid JSON is produced, but it makes the tag dangerous for third-party data. Never use it to write unchecked third-party data into the visible page content. For debugging, put the output in an HTML comment; in live operation, put it in a script element or an interface.

## Generating a JSON Web Token

`EJD-GenerateJWT()` signs the loaded JSON data and outputs it as a JSON Web Token. This lets you pass data to an external system in a tamper-proof way.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-GenerateJWT(SecretID)~
~EJD-GenerateJWT(SecretID,jdat)~
```

| Parameter | Meaning |
| - | - |
| SecretID | the identifier of an entry in the `<DesignControl>` section of the shop configuration `shop.config` |
| ID | the ID of the JSON data, optional if a default ID is set |

> [!NOTE]
>
> This tag is not described in the previous documentation but exists in the shop. The secret for the signature is the same configuration entry that `DC-FPX_hash()` and `DC-FPX_encrypt()` also use.

Reference: `<DesignControl>` section

## The tags at a glance

| Tag | Single tag | Area tag | Negative area tag | Loop tag |
| - | - | - | - | - |
| `EJD-LoadData()` | yes | – | – | – |
| `EJD-DataOK()` | yes | yes | yes | – |
| `EJD-SetUseID()` | yes | – | – | – |
| `EJD-CreateNewData()` | yes | – | – | – |
| `EJD-SetRealOutputFormat()` | yes | – | – | – |
| `EJD-LastNameAccessed` | yes | yes | yes | – |
| `EJD-LastValueAccessed` | yes | yes | yes | – |
| `EJD-DA-Value()` | yes | yes | yes | – |
| `EJD-DA-TouchValue()` | yes | yes | yes | – |
| `EJD-DA-TouchName()` | yes | yes | yes | – |
| `EJD-DA-NameExists()` | – | yes | yes | – |
| `EJD-DA-ArrayElements()` | yes | yes | yes | – |
| `EJD-DA-TouchArrayElements()` | yes | yes | yes | – |
| `EJD-DA-IsString()` | – | yes | yes | – |
| `EJD-DA-IsNumber()` | – | yes | yes | – |
| `EJD-DA-IsReal()` | – | yes | yes | – |
| `EJD-DA-IsObject()` | – | yes | yes | – |
| `EJD-DA-IsArray()` | – | yes | yes | – |
| `EJD-DA-IsTrue()` | – | yes | yes | – |
| `EJD-DA-IsFalse()` | – | yes | yes | – |
| `EJD-DA-IsNull()` | – | yes | yes | – |
| `EJD-ElementIterator()` | yes | yes | yes | yes |
| `EJD-DA-SetStringValue()` | yes | – | – | – |
| `EJD-DA-SetNumberValue()` | yes | – | – | – |
| `EJD-DA-SetRealValue()` | yes | – | – | – |
| `EJD-DA-SetToTrue()` | yes | – | – | – |
| `EJD-DA-SetToFalse()` | yes | – | – | – |
| `EJD-DA-SetToNull()` | yes | – | – | – |
| `EJD-DA-SetToEmptyObject()` | yes | – | – | – |
| `EJD-DA-SetToEmptyArray()` | yes | – | – | – |
| `EJD-DA-ArrayExtend()` | yes | – | – | – |
| `EJD-DA-DeleteElement()` | yes | – | – | – |
| `EJD-ModificationOK` | yes | yes | yes | – |
| `EJD-ResetModificationOK` | yes | – | – | – |
| `EJD-RawDataOutput()` | yes | yes | yes | – |
| `EJD-SetRawDataInput()` | yes | – | – | – |
| `EJD-SetRawDataHexCodedInput()` | yes | – | – | – |
| `EJD-GenerateJWT()` | yes | – | – | – |

All tags are permitted on all templates. The ID is optional for all tags once it has been set with `EJD-SetUseID()`, with the exception of `EJD-DataOK()` and `EJD-RawDataOutput()`.

## Related topics

* Guide: JSON interface
* Guide: href attribute
* Reference: DC- (loops)
* Reference: DC- (free parameters and session parameters)


## Related topics

- [KLARNA- (Klarna Payments)](https://dokumentation.websale.de/en/v8s/referenz/tags/klarna-payments.md)
- [SHIPTRACK- (shipment tracking)](https://dokumentation.websale.de/en/v8s/referenz/tags/shiptrack-sendungsverfolgung.md)
- [PPP- (PayPal PLUS)](https://dokumentation.websale.de/en/v8s/referenz/tags/ppp-paypal-plus.md)
- [RECAPTCHAV3- (Google reCAPTCHA)](https://dokumentation.websale.de/en/v8s/referenz/tags/recaptchav3-google-recaptcha.md)
- [PPC- (PayPal Checkout)](https://dokumentation.websale.de/en/v8s/referenz/tags/ppc-paypal-checkout.md)


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