Handbuch zur Belohnungsdefinition reward-definition-guide

Inhaltsverzeichnis

Erste Schritte mit Herausforderungen im Zusammenhang mit der Treue

Wenn eine Challenge-Aufgabe, ein Meilenstein oder eine Challenge abgeschlossen und ein Belohnungswert konfiguriert wurde gibt die Plattform eine Belohnung aus, indem sie den HTTP-Endpunkt Ihres Belohnungsanbieters mit einer JSON-Payload aufruft. Eine Belohnungsdefinition beschreibt, welche Belohnung ausgegeben werden soll, und bietet einen JSONata-Ausdruck - rewardJsonata - der die genaue Payload formt, die Ihr Anbieter erwartet.

In diesem Handbuch wird beschrieben, wie Sie einen Belohnungsanbieter konfigurieren, Belohnungsdefinitionen erstellen, den rewardJsonata Ausdruck schreiben und verstehen, welcher Kontext zur Auswertungszeit für ihn verfügbar ist.

Modell mit zwei Ebenen

Die Belohnungen sind in zwei Stufen organisiert:

Reward Provider  (endpoint, auth, headers)
└── Reward Definition  (denomination, rewardJsonata)
└── Reward Definition
└── ...

Ein Belohnungsanbieter stellt ein einzelnes externes Belohnungssystem dar und enthält die URL des Versandendpunkts, die Authentifizierung und alle benutzerdefinierten HTTP-Kopfzeilen. Ein Anbieter kann mehrere Belohnungsdefinitionen besitzen, die jeweils einen anderen Belohnungstyp oder eine andere von diesem Anbieter angebotene Bezeichnung beschreiben (z. B. „50 Sterne“, „Doppelsterne“, „Gratis-Artikel„).

Eine Challenge verweist auf den Anbieter und die Definition per GUID. Wenn eine Belohnung ausgegeben wird, bewertet die Plattform den rewardJsonata Ausdruck der Definition und sendet das Ergebnis an den Endpunkt des Anbieters.

Belohnungsanbieter- und Definitionsfelder

Felder des Belohnungsanbieters
table 0-row-4 1-row-4 2-row-4 3-row-4 4-row-4 5-row-4 6-row-4 7-row-4 8-row-4 html-authored
Feld Typ Erforderlich Beschreibung
guid String Nein (vom System zugewiesen) Eindeutige Kennung. Schreibgeschützt.
name String Ja Anzeigename, innerhalb der Organisation eindeutig.
desc String Nein Lesbare Beschreibung des Anbieters.
enabled Boolean Nein Wenn false, wird der Versand
Belohnungen für alle Definitionen unter diesem Anbieter ausgesetzt.
url String Ja HTTP-Endpunkt, der die Belohnungs-Payload erhält.
Die Plattform sendet die ausgewertete
rewardJsonata an diese URL.
additionalHeaders Object Nein Benutzerdefinierte HTTP-Kopfzeilen, die in jede Versandanfrage
werden sollen (z. B. API-Schlüssel
Inhaltsüberschreibungen).
maxRatePerSecond Integer Nein Optionales Ratenlimit pro Anbieter (1-5000).
Null bedeutet unbegrenzt.
enableMTLS Boolean Nein Ob der Endpunkt gegenseitiges TLS erfordert.
Felder zur Belohnungsdefinition
table 0-row-4 1-row-4 2-row-4 3-row-4 4-row-4 5-row-4 6-row-4 7-row-4 html-authored
Feld Typ Erforderlich Beschreibung
guid String Nein (vom System zugewiesen) Eindeutige Kennung. Schreibgeschützt.
name String Ja Anzeigename, innerhalb des Anbieters eindeutig.
denomination String Nein Die Einheit der Belohnung, die in der Anzeige verwendet wird
in Ausdrücken verfügbar ist als
reward.denomination
(z. B. "Stars", "Points", "Miles").
desc String Nein Beschreibung der Belohnung,
Ausdrücke als reward.desc verfügbar.
enabled Boolean Nein Wenn false, ist diese Definition inaktiv
gibt keine Belohnungen aus.
isDefault Boolean Nein Markiert dies als die Sandbox-weite Standard
Belohnungsdefinition. Es kann immer nur
eine Standarddefinition für alle Anbieter vorhanden sein. Wenn
einen neuen Standard festlegen, wird der vorherige Standard gelöscht.
Wird zum automatischen Ausfüllen von Belohnungsdetails für
Herausforderungen zum Zeitpunkt der Veröffentlichung verwendet.
rewardJsonata String Ja JSONata-Ausdruck, der zum Zeitpunkt
Belohnungsproblems ausgewertet wird Erhält den vollständigen
und muss die JSON-Payload
POST an den Anbieter zurückgeben.

Der Belohnungskontext

Wenn rewardJsonata ausgewertet wird, erhält es ein einzelnes Stammobjekt, das alles über das Belohnungsereignis Bekannte enthält. Alle Pfade in Ihrem Ausdruck sind relativ zu diesem Stamm.

{
  "rewardContext": {
    "rewardValue": "50",
    "source":      "challenge"
  },
  "reward": {
    "name":         "500 Stars",
    "desc":         "Issue 500 Stars to the member",
    "denomination": "Stars",
    "enabled":      true
  },
  "task": { ... },
  "milestone": { ... },
  "challenge": { ... },
  "timestamp": "2026-02-10T00:29:22.538+00:00"
}
Kontextfelder
table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 5-row-2 6-row-2 7-row-2 8-row-2 9-row-2 10-row-2 11-row-2 12-row-2 13-row-2 14-row-2 15-row-2 16-row-2
Feld Beschreibung
rewardContext.rewardValue Die Zeichenfolge des Belohnungswerts, die für die Herausforderung, Aufgabe oder den Meilenstein konfiguriert wurde, die/der diese Ausgabe ausgelöst hat.
rewardContext.source Was die Belohnung ausgelöst hat: "task", "challenge" oder "milestone".
reward Die Belohnungsdefinition selbst — name, desc, denomination.
task Die abgeschlossene Aufgabe, einschließlich ihrer accumulators, schedule und reward.
task.accumulators.spend Gesamtzahl der von der Aufgabe kumulierten qualifizierten Ausgaben.
task.accumulators.qty Gesamtzahl der von der Aufgabe kumulierten qualifizierten Elemente.
task.accumulators.item_list Alle qualifizierten Elemente, die auf die Aufgabe angewendet wurden. Jeder Eintrag hat item, transactionId, timestamp, utcOffset, locationId.
task.accumulators.item_list[-1] Das zuletzt angewendete Element (JSONata-negativer Index). Nützlich für die Suche nach der letzten Transaktions-ID oder dem letzten Zeitstempel.
task.schedule.currentStreak Aktuelle Anzahl aufeinander folgender Besuche (für Streak-Herausforderungen).
task.schedule.currentVisits Besuchsanzahl insgesamt (für Besuchsherausforderungen).
milestone Der Meilenstein, der diese Belohnung ausgelöst hat, oder null, wenn nicht eine Meilensteinbelohnung. Enthält count und reward.rewardValue.
challenge.profileId Die Treue-ID des Mitglieds.
challenge.kvpCustom Benutzerdefinierte Schlüssel-Wert-Paare, die für die Challenge konfiguriert sind. Ein gängiges Muster für die Übergabe von Kampagnen-IDs, Produktnamen oder anbieterspezifischen Metadaten.
challenge.name Name der Herausforderung.
challenge._id Challenge-ID.
timestamp ISO 8601-Zeitstempel der Belohnungsausgabe.

Schreiben des rewardJsonata-Ausdrucks

Der Ausdruck empfängt den Belohnungskontext als Eingabe und muss ein JSON-Objekt zurückgeben - die an den Endpunkt des Anbieters gepostete Payload. Die Form dieses Objekts hängt vollständig von der API des Anbieters ab. Sie ordnen Kontextfelder welcher Struktur auch immer der Anbieter erwartet.

Einfache feste Payload

Der einfachste Fall: Der Provider benötigt eine Punktzahl und eine Mitglieds-ID, die beide aus dem Kontext bekannt sind.

code language-jsonata
{
  "memberId":   challenge.profileId,
  "points":     $number(rewardContext.rewardValue),
  "currency":   reward.denomination
}

Ausgabe:

code language-json
{
  "memberId": "ADB-0000030",
  "points":   50,
  "currency": "Stars"
}

rewardContext.rewardValue ist immer eine Zeichenfolge. Verwenden Sie $number(), um sie zu konvertieren, wenn Ihr Anbieter einen numerischen Wert erwartet.

Verwenden von kvpCustom für anbieterspezifische Metadaten

Anbieter benötigen häufig Felder wie Kampagnen-IDs oder Quellsystem-Codes, die für jede Challenge-Ausführung spezifisch sind. Speichern Sie diese beim Verfassen der Herausforderung in challenge.kvpCustom und referenzieren Sie sie dann im Ausdruck. So bleibt der Ausdruck kampagnenübergreifend wiederverwendbar.

code language-jsonata
{
  "memberId":         challenge.profileId,
  "points":           $number(rewardContext.rewardValue),
  "campaignId":       challenge.kvpCustom.campaignId,
  "transactionSource": "AJO"
}

Sie können auch reward.kvpCustom für Konstanten verwenden, die für einen bestimmten Belohnungstyp und nicht pro Herausforderung festgelegt sind.

Verwenden der Daten des Aufgabenakkumulators

Aufgabenakkumulatoren halten Aufzeichnungen über jedes qualifizierte Ereignis bereit. Verwenden Sie item_list[-1] , um auf das zuletzt angewendete Element zuzugreifen - seine transactionId und timestamp sind für Audit-Trails und Deduplizierung auf Anbieterseite nützlich.

code language-jsonata
{
  "memberId":       challenge.profileId,
  "points":         $number(rewardContext.rewardValue),
  "transactionId":  task.accumulators.item_list[-1].transactionId,
  "transactionDate": task.accumulators.item_list[-1].timestamp
}
Erstellen einer Textnachricht

Bei benachrichtigungsbasierten Anbietern (Slack, SMS, E-Mail) können Sie eine Nachrichtenzeichenfolge direkt mit dem & Verkettungsoperator von JSONata erstellen:

code language-jsonata
{
  "text": "You just earned " & rewardContext.rewardValue & " " & reward.denomination & "!"
}

Ausgabe:

code language-json
{
  "text": "You just earned 50 Stars!"
}

Beispiele

Beispiel 1: Einfacher Punktanbieter

Szenario: grundlegende Treuepunkte-API erwartet eine Mitglieder-ID und einen Punktbetrag.

Belohnungsdefinition:

code language-json
{
  "name":         "Standard Points",
  "denomination": "Points",
  "desc":         "Award loyalty points",
  "enabled":      true,
  "rewardJsonata": "{\"memberId\": challenge.profileId, \"pointQuantity\": $number(rewardContext.rewardValue), \"denomination\": reward.denomination}"
}

Formatierter Ausdruck:

code language-jsonata
{
  "memberId":      challenge.profileId,
  "pointQuantity": $number(rewardContext.rewardValue),
  "denomination":  reward.denomination
}

Payload an Provider gepostet:

code language-json
{
  "memberId":      "ADB-0000030",
  "pointQuantity": 50,
  "denomination":  "Points"
}
Beispiel 2: Provider-Payload mit Kampagnen-Metadaten

Szenario: Anbieter benötigt einen strukturierten Prämiensatz, der Auditfelder, Kampagnenverweise und Mitgliederbeschreibungen enthält. Kampagnenspezifische Werte werden in challenge.kvpCustom gespeichert, sodass dieselbe Belohnungsdefinition über Kampagnen hinweg funktioniert, ohne den Ausdruck zu bearbeiten.

Challenge-kvpCustom (festgelegt bei der Bearbeitung der Challenge):

code language-json
{
  "parentCampaignId": "CAMP-2026-Q1",
  "productName":      "Loyalty Program"
}

Belohnungsdefinition:

code language-json
{
  "name":         "Stars — Campaign Award",
  "denomination": "Stars",
  "desc":         "Issue Stars for completing a qualifying purchase",
  "enabled":      true,
  "rewardJsonata": "{\"awardPoints\":[{\"idType\":\"externalId\",\"id\":challenge.profileId,\"transactionId\":task.accumulators.item_list[-1].transactionId,\"transactionDate\":task.accumulators.item_list[-1].timestamp,\"originalTransactionId\":task.accumulators.item_list[-1].transactionId,\"transactionSource\":\"AJO\",\"channelSource\":\"Web\",\"parentCampaignId\":challenge.kvpCustom.parentCampaignId,\"productName\":challenge.kvpCustom.productName,\"memberAwardDescription\":reward.desc,\"pointQuantity\":$number(rewardContext.rewardValue)}]}"
}

Formatierter Ausdruck:

code language-jsonata
{
  "awardPoints": [
    {
      "idType":                "externalId",
      "id":                    challenge.profileId,
      "transactionId":         task.accumulators.item_list[-1].transactionId,
      "transactionDate":       task.accumulators.item_list[-1].timestamp,
      "originalTransactionId": task.accumulators.item_list[-1].transactionId,
      "transactionSource":     "AJO",
      "channelSource":         "Web",
      "parentCampaignId":      challenge.kvpCustom.parentCampaignId,
      "productName":           challenge.kvpCustom.productName,
      "memberAwardDescription": reward.desc,
      "pointQuantity":         $number(rewardContext.rewardValue)
    }
  ]
}

Payload an Provider gepostet:

code language-json
{
  "awardPoints": [
    {
      "idType":                "externalId",
      "id":                    "ADB-0000030",
      "transactionId":         "b4fa0e89-f4bb-41ce-b370-fb97f9c52f1a",
      "transactionDate":       "2026-02-08T00:12:00.000+00:00",
      "originalTransactionId": "b4fa0e89-f4bb-41ce-b370-fb97f9c52f1a",
      "transactionSource":     "AJO",
      "channelSource":         "Web",
      "parentCampaignId":      "CAMP-2026-Q1",
      "productName":           "Loyalty Program",
      "memberAwardDescription": "Issue Stars for completing a qualifying purchase",
      "pointQuantity":         50
    }
  ]
}
Beispiel 3 — Meilenstein-Belohnung

Szenario: Streak Challenge gibt alle N Besuche eine Meilensteinbelohnung aus. Der Ausdruck enthält die Meilensteinanzahl und den aktuellen Stream für den anbieterseitigen Kontext.

Formatierter Ausdruck:

code language-jsonata
{
  "memberId":       challenge.profileId,
  "points":         $number(rewardContext.rewardValue),
  "milestoneCount": milestone.count,
  "currentStreak":  task.schedule.currentStreak,
  "denomination":   reward.denomination,
  "source":         rewardContext.source
}

Payload an Provider gepostet (beim zweiten Meilenstein des Besuchs):

code language-json
{
  "memberId":       "ADB-0000030",
  "points":         20,
  "milestoneCount": 2,
  "currentStreak":  2,
  "denomination":   "Stars",
  "source":         "milestone"
}

Wenn rewardContext.source "milestone" wird, wird das milestone mit count und reward.rewardValue befüllt. Wenn die Quelle "task" oder "challenge" ist, wird milestone null.

API-Referenz

Prämienanbieter
code language-http
POST   /loyalty/metadata/config/rewards/providers
GET    /loyalty/metadata/config/rewards/providers
GET    /loyalty/metadata/config/rewards/providers/{providerId}
PUT    /loyalty/metadata/config/rewards/providers/{providerId}
DELETE /loyalty/metadata/config/rewards/providers/{providerId}

Für alle Anfragen sind x-gw-ims-org-id und x-sandbox-name Kopfzeilen erforderlich.

Anbieter erstellen:

code language-http
POST /loyalty/metadata/config/rewards/providers
x-gw-ims-org-id: {ORG_ID}
x-sandbox-name: {SANDBOX}
Content-Type: application/json

{
  "name":    "My Points Provider",
  "desc":    "Issues loyalty points via REST",
  "enabled": true,
  "url":     "https://rewards.example.com/award",
  "additionalHeaders": {
    "x-api-key": "YOUR_API_KEY"
  }
}
Prämiendefinitionen
code language-http
POST   /loyalty/metadata/config/rewards/definitions/{providerId}
GET    /loyalty/metadata/config/rewards/definitions/{providerId}
GET    /loyalty/metadata/config/rewards/definitions/{providerId}/{rewardId}
PUT    /loyalty/metadata/config/rewards/definitions/{providerId}/{rewardId}
DELETE /loyalty/metadata/config/rewards/definitions/{providerId}/{rewardId}

Erstellen Sie eine Belohnungsdefinition:

code language-http
POST /loyalty/metadata/config/rewards/definitions/{providerId}
x-gw-ims-org-id: {ORG_ID}
x-sandbox-name: {SANDBOX}
Content-Type: application/json

{
  "name":         "50 Stars",
  "denomination": "Stars",
  "desc":         "Award 50 Stars on task completion",
  "enabled":      true,
  "rewardJsonata": "{ \"memberId\": challenge.profileId, \"points\": $number(rewardContext.rewardValue) }"
}

Validierung von Ausdrücken

rewardJsonata Ausdrücke werden zum Zeitpunkt der Veröffentlichung auf Syntax überprüft. Wenn der Ausdruck ungültig ist, gibt die API einen 422 mit einer Beschreibung des Analysefehlers zurück.

Um einen Ausdruck vor der Veröffentlichung zu entwickeln und zu testen, verwenden Sie den JSONata Exerciser. Fügen Sie das Belohnungskontext-JSON als Eingabedokument und Ihren Ausdruck ein, um zu überprüfen, ob die Ausgabe mit den Erwartungen Ihres Anbieters übereinstimmt. Ein repräsentativer Belohnungskontext für jeden Trigger (task, milestone, challenge) wird in den obigen Beispielen gezeigt.

Häufige Fehler

Fehler
Ergebnis
Korrigieren
rewardContext.rewardValue als Zahl ohne Konversion verwendet
Nicht übereinstimmender Typ, wenn der Anbieter das Feld als numerisch validiert
Mit $number(rewardContext.rewardValue) umschließen
challenge.kvpCustom.someKey gibt null zurück
Schlüssel wurde bei der Bearbeitung der Anfrage nicht festgelegt
Stellen Sie sicher, dass der Schlüssel bei jeder Herausforderung, die diese Definition verwendet, in kvpCustom vorhanden ist
task.accumulators.item_list[-1] ist null
Vor der Vergabe der Belohnung wurden keine Elemente angewendet (Nicht-Kaufereignis)
Schützen Sie stattdessen mit einem bedingten oder verwenden Sie timestamp aus dem Kontext .
milestone Zugriff, wenn die Quelle "task" oder "challenge" ist
milestone ist null; Ausdruck löst NULL-Felder aus oder erzeugt sie
rewardContext.source vor dem Zugriff auf milestone prüfen oder milestone nur in Definitionen verwenden, die an Meilenstein-Prämien angehängt sind
Ausdruck gibt ein Array anstelle eines Objekts zurück
Anbieter erhält unerwartete Payload-Struktur
Wrap array-returned-Ausdrücke in einem äußeren Objekt: { "items": [...] }
recommendation-more-help
journey-optimizer-help