Einleitung

Diese Dokumentation beschreibt die allgemeine API von Thermengutscheine.at. Zur Nutzung der API ist eine API Key notwendig, der von der Firma "Webhotels" seinen Partnerunternehmen zur Verfügung gestellt wird. Bei Fragen wenden Sie sich bitte direkt Webhotels

Allgemeines

Verwendung der API

Bei dieser API handelt es sich um ein REST-API (siehe dazu auch Wikipedia. Derzeit werden folgendene HTTP Methoden (Verbs) eingesetzt:

  • GET = Holen einer einzelnen Ressource oder einer Liste von Ressourcen.
  • POST = Durchführen einer bestimmten Aktion.

Alle REQUEST Urls beginnen mit der API Version (zB. v1), der anzusprechenden Ressource (zB. "coupon") und der durchzuführenden Aktion oder Teilressource (zB. "validate"). Hier einige Beispiel Url:

  • /v1/api/version
  • /v1/coupon/validate
  • /v1/coupon/useit

Folgende Dinge gilt es zu beachten:

  • Alle API Requests müssen Authentifiziert werden.
  • Es dürfen nur oben genannten HTTP Methoden verwendet werden.
  • POST Request Daten müssen als "Content-Type: application/x-www-form-urlencoded" übertragen werden.

Authentifizierung

Alle API Requests müssen mit Ihrem API-Token authentifiziert werden. Den API-Token erhalten sie von Thermengutscheine.at (siehe oben). Dieser Token ist:

  • Ein mittels Zufallsprinzip generierter, in der Regel 128 Zeichen langer String.
  • Bei jedem Request an die API mitzugeben.
  • Geheim und sollte daher auch nicht weitergegeben oder ungesichert gespeichert/aufgeschrieben werden.
  • Identifizierend, dh. dieser Token gilt nur für Sie (bzw. Ihr Unternehmen) und alle Aktionen die Sie damit durchführen, werden als von Ihnen durchgeführt angesehen.

Um nun einen Request zu authentifizieren, müssen Sie ihn lediglich in den HTTP Header als "Authorization: Token XYZ" schreiben, wobei XYZ für Ihren Token steht. Siehe folgendes Beispiel eines Requests:

    GET /v1/api/version HTTP/1.1
    Host: api.thermengutscheine.at
    Authorization: Token ThisIsMySecriptToken1234
    Accept: application/json
    Content-Type: application/x-www-form-urlencoded

Rückgabewerte

Alle Rückgabewerte können sowohl als JSON als auch XML angefordert werden. Hier muss lediglich der HTTP Header "Accept" bei jedem Request entsprechend gesetzt werden.

JSON

Möchte man JSON Antworten haben, so wird der "Accept" Header bei jedem Request wie folgt gesetzt (siehe Beispiel):

    GET /v1/api/version HTTP/1.1
    Host: api.thermengutscheine.at
    Authorization: Token ThisIsMySecriptToken1234
    Accept: application/json

Die Antwort des obigen Requests würde dann wie folgt aussehen:

    {
        "result": {
            "provider": "Thermengutscheine.at",
            "version": "v1"
        }
    }

XML

Möchte man XML Antworten haben, so wird der "Accept" Header bei jedem Request wie folgt gesetzt (siehe Beispiel):

    GET /v1/api/version HTTP/1.1
    Host: api.thermengutscheine.at
    Authorization: Token ThisIsMySecriptToken1234
    Accept: application/xml

Die Antwort des obigen Requests würde dann wie folgt aussehen:

    <?xml version="1.0" encoding="utf-8"?>
    <xml>
        <result>
            <provider>Thermengutscheine.at</provider>
            <version>v1</version>
        </result>
    </xml>

Ressource - API

Die API Ressource ist die einzige Ressource die auch ohne API Key angesprochen werden kann und bietet neben dieser Hilfe Seite einige Hilfs-Funktionen.

Ressource Beschreibung
GET

/v1/api/version
Liefert einige Informationen zur API.

Beispiel-Rückgabe:
{
    "result": {
        "provider": "Thermengutscheine.at",
        "version": "v1"
    }
}

Ressource - Gutscheine

Die Gutschein API dient zur Überprüfung und Einbuchung/Einlösung von Gutscheinen.

Methoden

Ressource Beschreibung
POST

/v1/coupon/validate
Dient zur Überprüfung eines Gutscheincodes auf Gültigkeit und liefert im Erfolgsfall Informationen über den Gutschein:
  • code: Gutschein-Code
  • current_value: RestAktueller-Wert
  • price: Gutschein-Nennwert
  • currency: Immer €
  • pin: Boolean; Wenn true, dann wird ein PIN für das Einlösen benötigt, wenn false, dann wird kein PIN für das Einlösen benötigt.
  • pin_valid: Boolean; Wenn der GS keinen PIN hat, dann ist dieser Wert immmer true. Hat der GS einen PIN (siehe Feld `pin`), dann ist dieses Feld nur true, wenn der (optionale) Parameter `pin` richtig ist.
  • valid_till: Gültigkeit des Gutscheins

Parameter
  • code: Pflicht; string; Code der Überprüft werden soll
  • pin: Optionaler; string; Möchte man auch den PIN Code des GS's überprüfen, kann der PIN Code mit geschickt werden. Hat der GS keinen PIN Code oder der User benötigt generell keinen PIN-Code, so wird dieser Parameter ignoriert.

Beispiel-Rückgabe:
{
    "result": {
        "code": "1000000000000001",
        "current_value": 9.90,
        "price": 20,
        "currency": "€",
        "pin": true,
        "pin_valid": true,
        "valid_till": "2021-07-05"
    }
}
POST

/v1/coupon/useit
Der Gutschein wird (sofern er gültig ist) mit dem angegeben Wert belastet und liefert im Erfolgsfall Informationen über den Gutschein:
  • log_id: Die ID der Einbuchung (nützlich bei Stornos)
  • code: Gutschein-Code
  • current_value: RestAktueller-Wert
  • price: Gutschein-Nennwert
  • currency: Immer €
  • valid_till: Gültigkeit des Gutscheins

Parameter
  • code: Pflicht; string; Code der überprüft werden soll
  • pin: Optionaler; string; Pflicht bei GS mit PIN. Achtung: Siehe PIN-Code
  • value: Pflicht; decimal; Der Wert der abgebucht werden soll

Beispiel-Rückgabe:
{
    "result": {
        "log_id": 4711,
        "used_value": -7.50,
        "code": "1000000000000001",
        "current_value": 9.90,
        "price": 20,
        "currency": "€",
        "valid_till": "2021-07-05",
        "einbuchung_cooldown": 8
    }
}
GET

/v1/coupon/log
Listet alle Einbuchungen und Stornos des aktuellen Users des heutigen Tages auf.

Beispiel-Rückgabe:
{
    "result": [
        {
            "log_id": 1,
            "event_type": "einbuchung.useit",
            "code": "12345",
            "price": 50,
            "used_value": -0.2,
            "date": "2024-10-03 19:31:54"
        },
        {
            "log_id": 2,
            "event_type": "einbuchung.storno",
            "code": "12345",
            "price": 50,
            "used_value": 0.01,
            "date": "2024-10-03 20:04:21"
        }
    ]
}
POST

/v1/coupon/storno
Storniert eine erfolgte Einbuchung. Achtung: Stornos sind nur für Buchungen des selben Tages möglich.
Parameter
  • log_id: Pflicht; int; Log-ID id der zu stornierenden Einbuchung.

Beispiel-Rückgabe:
{
    "result": {
        "log_id": "115",
        "action": "storno",
        "storno_value": 0.2,
        "coupon": {
            "code": "998577849939562",
            "current_value": "0.20",
            "price": 50,
            "currency": "€",
            "valid_till": "2021-07-28"
        }
    }
}

PIN-Code

Die Eingabe des Gutschein-Pin Codes ist nur beim Einlösen (/v1/coupon/useit) über die Api notwendig. In ganz besonderen Fällen kann die Notwendigkeit der Eingabe des PIN-Codes aber für einen API-User deaktiviert werden (bitte bei Thermengutscheine.at nachfragen).

PIN Codes zum Gutschein wurden nachträglich eingeführt, dh. es sind bereits Gutscheine im Umlauf, die noch keinen PIN-Code besitzen. Bei diesen kann der PIN-Code "000000" (6 mal die Null) verwendet werden. Bei User die keinen PIN Code benötigen, wird der PIN immer ignoriert.

Gutschein Überprüfung

Bei der GS Überprüfung (/v1/coupon/validate) ergeben sich folgende Szenarian im Bezug auf den PIN:

  • Sie schicken eine Anfrage mit einem gültigen GS code aber OHNE pin:
    • GS hat keinen Pin, dann ist pin=false und pin_valid=true
    • GS hat einen Pin, dann ist pin=true und pin_valid=true
  • Sie schicken eine Anfrage mit einem gültigen GS code und mit pin:
    • GS hat keinen Pin, dann ist pin=false und pin_valid=true
    • GS hat einen Pin und dieser stimmt mit gesendete pin überein, dann ist pin=true und pin_valid=true
    • GS hat einen Pin und dieser stimmt NICHT mit gesendete pin überein, dann ist pin=true und pin_valid=false

Fehlercodes

Sollte ein Fehler auftreten, so wird dieser in folgendem Format übermittelt (Beispiel):

{
    "error": 1234,
    "message": "Fehlermeldungstext",
    "data": "zusätzliche Daten zur Fehlermeldung"
}

Dabei sind die 3 bis 5-stellige Fehlernummer (`error`) und die Nachricht (`message`) Pflichtfelder und die Zusatzdaten (`data`) sind optional. Es können unter anderem folgende Fehler auftreten:

FehlerBeschreibung
999Fehler beim verbuchen eines Coupons
2051Sie wurden aufgrund zu vieler Gutschein-Überprüfungen blockiert. Hier wird zusätzlich zur Fehlermeldung auch separat (Feld `data`) die Uhrzeit mitgeben, ab wann wieder geprüft werden kann.
2052Dieser Fehler kann mehrere Ursachen haben - bitte `message` beachten. z.B. Der Gutschein wurde bereits vollständig eingelöst oder die Nummer ist nicht gültig
2053Die eingegebene Gutscheinnummer ist leider nicht gültig.
2054Bitte geben Sie eine gültige Gutscheinnummer ein
2055Bitte geben Sie einen gültigen PIN-Code ein
2088GUTSCHEIN BITTE PER POST SCHICKEN! Bei dem Gutschein mit der Nummer XXXXX handelt es sich um einen Gutschein, der online nicht eingebucht werden kann. Wenn es sich um einen der hier abgebildeten Gutscheinarten handelt, ist der Gutschein nach wie vor gültig und kann zur Abrechnung per Post an WEBHOTELS geschickt werden.
11001Missing post parameter: %s
11002Missing get parameter: %s

Sicherheit

Um Missbrauch der API vorzubeugen und das System abzusichern, wird folgender Prozess verwendet:

  • Wenn ein ungültiger/stornierter/eingelöster Gutscheincode überprüft oder eingelöst wird, so wird ein Zähler gestartet, der bei jedem weiteren ungültigen Versuch um eins erhöht wird.
  • Sobald dieser Zähler eine bestimmte Höhe erreicht hat, wird der entsprechende User (=API Key) für eine bestimmte Zeit blockiert, dh. er kann keine Gutscheincodes überprüfen oder einlösen.
  • Wurde ein User blockiert, so kann er erst wieder nach Ablauf der Blockade Frist (in der Regel wenige Minuten) wieder Gutscheine prüfen/einbuchen. Nach dieser Frist wird auch der Zähler wieder auf 0 gesetzt.
  • Sobald ein gültiger Gutschein erfolgreich eingebucht/eingelöst (nicht nur überprüft) wird, wird der Zähler ebenfalls auf 0 gesetzt.

Spezialfall One-Step

Bei unserem Partner Blackhawk setzen wir bei einigen unserer Gutscheine ein One-Step Verfahren ein. Dabei ist im Barcode des Gutscheins auch noch unser GTIN-13 Code und 3 Nullen integriert. Der Barcode ist dabei wie folgt aufgebaut:

  • 13 Stellen GTIN-13
  • 3 Stellen „NULL“
  • 16 Stellen - die eigentliche Gutscheinnummer

Bei diesen Gutscheinen ist es möglich, sowohl den vollen Barcode laut Barcode Scanner (32 Stellen) als auch nur den GS Code (die letzten 16 Stellen) zu übermitteln. Die API ignoriert bei diesen (und nur bei diesen) Gutscheinen die ersten 16 Stellen und liefert im Erfolgsfall nur den eigentlichen GS Code zurück.

Das bedeutet, dass ein validate/useit sowohl gegen den Code "91900010173410001234567890123456" als auch gegen den Code "1234567890123456" das selbe Ergebnis liefert:

{
    "result": {
        "code": "1234567890123456",
        "current_value": 9.90,
        "price": 20,
        "currency": "€",
        "pin": true,
        "pin_valid": true,
        "valid_till": "2025-07-05"
    }
}