Technische Dokumentation

Webhooks

Webhooks senden bei jedem Ereignis Ihrer Organisation auf Donoor automatisch eine signierte Nachricht an Ihren Server: eingegangene Spende, Erstattung, Mitgliedschaft, gescanntes Ticket, Bestellung, Spendenquittung, Auszahlung… Ihr System wird innerhalb von Sekunden benachrichtigt, ohne dass jemand etwas exportieren muss.

api_version 2026-10-17HTTPS · JSON · HMAC-SHA25628 Ereignisse

Überblick

Ein Webhook ist eine Internetadresse (eine URL), die Ihrer Organisation gehört: die Ihres Servers, Ihres CRM oder eines Tools wie Make oder Zapier. Sobald auf Donoor ein Ereignis eintritt, sendet Donoor an diese Adresse eine HTTPS-POST-Anfrage, die das Ereignis im JSON-Format beschreibt.

Jede Nachricht wird mit einem Secret signiert, das nur Sie kennen: So kann Ihr Server prüfen, dass sie wirklich von Donoor stammt und nicht verändert wurde. Antwortet Ihr Server nicht, versucht Donoor es automatisch rund 28 Stunden lang erneut.

Ein Ereignis tritt ein

Spende, Mitgliedschaft, Ticket…

Donoor sendet eine signierte Nachricht

POST · Donoor-Signature

Ihr Server

prüft, antwortet 200, verarbeitet

Werbung — jede Spende als Conversion an Google Ads, GA4 oder Meta übermitteln, zusammen mit der Ursprungskampagne.

CRM — den Datensatz des Spenders, Mitglieds oder Käufers anlegen oder aktualisieren.

Buchhaltung — Zahlungen, Erstattungen, Spendenquittungen und Bankauszahlungen erfassen.

Automatisierung — Ihr Team benachrichtigen, eine Tabelle befüllen, eine Willkommens-E-Mail auslösen.

Schnellstart

Rechnen Sie mit etwa fünfzehn Minuten, bis Sie Ihre erste Nachricht erhalten.

  1. 1

    Bereiten Sie eine Empfangsadresse vor

    Eine aus dem Internet erreichbare https-Adresse, auf Ihrem Server oder in einem Tool wie Make oder Zapier. Zum Ausprobieren ohne Installation genügt eine kostenlose Adresse von webhook.site.

  2. 2

    Fügen Sie sie in Ihrem Dashboard hinzu

    Einstellungen › Webhooks › Adresse hinzufügen. Geben Sie ihr eine Beschreibung und wählen Sie die Ereignisse aus, die Sie empfangen möchten (standardmäßig alle).

  3. 3

    Kopieren Sie das Secret

    Es beginnt mit whsec_. Bewahren Sie es in der Konfiguration Ihres Servers auf, niemals in einer Webseite oder einem öffentlichen Code-Repository.

  4. 4

    Prüfen Sie die Signatur und antworten Sie mit 200

    Ihr Server prüft den Header Donoor-Signature und antwortet dann innerhalb von 10 Sekunden mit einem 2xx-Code. Kopierfertiger Code in Node.js, PHP und Python steht weiter unten.

  5. 5

    Senden Sie eine Testnachricht

    Schaltfläche Test senden, oder Ereignis simulieren, um jedes der 28 Ereignisse mit fiktiven Daten zu erhalten. Prüfen Sie das Ergebnis anschließend im Zustellprotokoll.

Lieber ein Video?Die Schulung Webhooks zeigt jeden Schritt im Video, von der ersten Einrichtung bis zur Überwachung der Zustellungen.

Gesendet werden nur Ereignisse, die nach dem Hinzufügen Ihrer ersten Adresse eintreten: Frühere Ereignisse werden nicht nachgeliefert. Die Nachrichten enthalten die E-Mail-Adresse und den Namen der Spender: Nur der Verantwortliche und die Administratoren der Organisation können Webhooks verwalten, und der Verantwortliche wird bei jeder hinzugefügten oder geänderten Adresse per E-Mail benachrichtigt.

Liste der Ereignisse

Jede Adresse empfängt die Ereignisse, die Sie ausgewählt haben. Die Spalte „Inhalt“ gibt an, welche Objekte in data enthalten sind; sie werden im Abschnitt Objekte beschrieben.

Zahlungen

TypGesendet, wenn…Inhalt
payment.succeededEine Zahlung wird bestätigt: einmalige oder monatliche Spende (erste Zahlung und jede Verlängerung), Mitgliedschaft, Ticket, Shop-Bestellung, QR-Code, Spendenaktion, Tap to Pay.paymentattribution
payment.failedEine Karte oder Lastschrift wird abgelehnt, zum Beispiel bei der Verlängerung einer monatlichen Spende.paymentattribution
payment.refundedEine Zahlung wird ganz oder teilweise erstattet. Eine Nachricht pro Erstattung.paymentrefundattribution
dispute.openedEin Spender widerspricht einer Zahlung bei seiner Bank.paymentdisputeattribution
dispute.closedDie Zahlungsanfechtung ist abgeschlossen, gewonnen oder verloren.paymentdisputeattribution

Monatliche Spenden

TypGesendet, wenn…Inhalt
subscription.createdEin Spender startet eine monatliche Spende.subscriptionattribution
subscription.past_dueDie Abbuchung dieses Monats ist fehlgeschlagen: Die monatliche Spende wartet auf Zahlung.subscriptionattribution
subscription.reactivatedEine unbezahlte monatliche Spende ist wieder beglichen.subscriptionattribution
subscription.canceledEine monatliche Spende wird beendet.subscriptionattribution

Bestellungen (Mitgliedschaften, Ticketverkauf, Shop)

TypGesendet, wenn…Inhalt
order.confirmedEine Mitgliedschaft, Tickets oder ein Shop-Kauf sind bestätigt, auch wenn sie kostenlos sind.order
order.pending_approvalEin Mitgliedsantrag wartet auf Ihre Freigabe.order
order.rejectedSie haben einen Mitgliedsantrag abgelehnt.order
order.canceledEine Bestellung wird storniert.order
order.expiredEine Bestellung wurde nicht rechtzeitig bezahlt und ist abgelaufen.order
order.fulfillment_updatedEine Shop-Bestellung wechselt den Schritt: in Vorbereitung, versendet (mit Sendungsnummer), zugestellt oder abgeholt.order

Mitglieder und Tickets

TypGesendet, wenn…Inhalt
membership.createdEin Mitgliedsausweis wird aktiv.membership
membership.canceledEine Mitgliedschaft wird storniert.membership
ticket.checked_inEin Ticket wird am Eingang Ihrer Veranstaltung gescannt.ticket
ticket.canceledEin Ticket wird storniert.ticket

Erstattungsanfragen

TypGesendet, wenn…Inhalt
refund_request.createdEin Spender oder Käufer bittet Sie um eine Erstattung.refund_request
refund_request.updatedEine Erstattungsanfrage ändert ihren Status: beantwortet, erstattet oder abgelehnt.refund_request

Spendenquittungen

TypGesendet, wenn…Inhalt
fiscal_receipt.issuedFür einen Spender wird eine Spendenquittung ausgestellt.fiscal_receipt
fiscal_receipt.voidedEine Spendenquittung wird storniert, zum Beispiel nach einer Erstattung.fiscal_receipt

Bankauszahlungen

TypGesendet, wenn…Inhalt
payout.paidStripe oder PayPal hat Geld auf das Bankkonto der Organisation überwiesen.payout
payout.failedEine Überweisung auf das Bankkonto der Organisation ist fehlgeschlagen.payout

Formulare und Spendenaktionen

TypGesendet, wenn…Inhalt
form.createdEine Spendenaktion, eine Veranstaltung, ein Mitgliedschaftstarif, ein Shop, ein Zahlungslink oder ein QR-Code wird erstellt.form
campaign.goal_reachedEine Spendenaktion erreicht ihr Ziel.campaign

Konto der Organisation

TypGesendet, wenn…Inhalt
organization.payment_account_updatedDas Stripe- oder PayPal-Konto der Organisation wird aktiviert oder gesperrt.payment_account

Test

TypGesendet, wenn…Inhalt
test.pingTestnachricht, vom Dashboard aus gesendet.message

Eine bezahlte Bestellung löst zwei Ereignisse aus: order.confirmed (die Bestellung) und payment.succeeded (das Geld). Um Ihre Conversions zu messen, verwenden Sie nur payment.succeeded; um Ihre Anmeldungen zu verwalten, nur order.confirmed. Abonnieren Sie für jede Adresse nur die Ereignisse, die sie benötigt.

Nachrichten werden in der Regel weniger als zwei Minuten nach dem Ereignis gesendet: Donoor wartet, bis alle Angaben endgültig sind (ausgezahlter Betrag, Gebühren…), bevor gesendet wird.

Aufbau einer Nachricht

Jede Nachricht ist eine POST-Anfrage, deren UTF-8-kodierter JSON-Inhalt immer dieselbe Hülle hat. Nur der Inhalt von data ändert sich je nach Ereignistyp. Die Feldnamen sind englisch, wie bei Stripe oder HelloAsso.

FeldTypBeschreibung
idstringEindeutige Kennung des Ereignisses (evt_…). Sie bleibt bei jeder Wiederholung und jedem erneuten Senden gleich: Damit können Sie ein Duplikat ignorieren.
objectstringImmer event.
typestringTyp des Ereignisses, zum Beispiel payment.succeeded.
api_versionstringVersion des Nachrichtenformats. Sie ändert sich nur bei einer inkompatiblen Änderung.
createdstring (ISO 8601)Erstellungsdatum des Ereignisses, in UTC.
livemodebooleantrue für ein echtes Ereignis; false für eine Simulation oder in der Testumgebung. Zählen Sie eine Nachricht mit livemode false niemals als echte Zahlung.
organizationobjectDie betroffene Organisation: id (Donoor-Nummer) und name.
dataobjectDie ereignisspezifischen Objekte: payment, order, ticket… (siehe Objekte).

Beispielnachrichten

{
  "id": "evt_9mK2xQpL4vR8sT1w",
  "object": "event",
  "type": "payment.succeeded",
  "api_version": "2026-10-17",
  "created": "2026-10-17T14:02:11.000Z",
  "livemode": true,
  "organization": {
    "id": 1234,
    "name": "Les Amis du Quartier"
  },
  "data": {
    "payment": {
      "id": 32631,
      "conversion_id": "32631",
      "order_id": null,
      "status": "succeeded",
      "amount": 50.6,
      "amount_cents": 5060,
      "net_amount": 49.3,
      "fees_covered_amount": 0.6,
      "provider_fee_amount": 1.3,
      "currency": "EUR",
      "refunded_amount": 0,
      "kind": "donation",
      "channel": "online",
      "form": null,
      "recurring": {
        "interval": "month",
        "sequence": "first",
        "subscription_id": 812
      },
      "payment_provider": "stripe",
      "payment_method": "card",
      "wallet": "apple_pay",
      "provider_reference": "pi_3UQZvoFXPodLa3BZ2HKqlaEw",
      "donor": {
        "email": "amina.k@exemple.fr",
        "name": "Amina K.",
        "anonymous": false
      },
      "created": "2026-10-17T14:01:02.000Z"
    },
    "attribution": {
      "parameters": {
        "utm_source": "google",
        "utm_medium": "cpc",
        "utm_campaign": "ramadan-2027",
        "gclid": "Cj0KCQjw8eTFBhCXARIsAIkiuOz"
      },
      "landing_page": "https://www.mon-association.org/faire-un-don",
      "marketing_consent": true
    }
  }
}

Objekte

Die Objekte, die in data vorkommen können. Ein Feld ohne Wert ist null. Datumsangaben sind im Format ISO 8601, in UTC.

Alle Beträge sind in Euro mit zwei Dezimalstellen angegeben; die Felder …_cents enthalten denselben Betrag in Cent. Die Beträge sind die der Organisation: Die freiwillige Unterstützung, die ein Spender Donoor gibt, ist nie enthalten.

idintegerDonoor-Kennung der Zahlung.
conversion_idstringConversion-Kennung, die an Google und Meta übermittelt wird. Entspricht id bei einer Spende und der Bestellnummer bei einer Mitgliedschaft, einem Ticket oder einem Shop-Kauf. Sie ist auch die transaction_id, die das Widget in den dataLayer schreibt.
order_idstring | nullKennung der zugehörigen Bestellung (Mitgliedschaft, Ticketverkauf, Shop), sonst null.
statusstringsucceeded, failed, refunded, partially_refunded oder disputed.
amountnumberFür die Organisation gezahlter Betrag, einschließlich der vom Spender übernommenen Gebühren. Dies ist der Wert, der als Conversion gesendet wird.
amount_centsintegerDerselbe Betrag, in Cent.
net_amountnumber | nullBetrag, den Stripe oder PayPal nach Abzug ihrer Gebühren tatsächlich an die Organisation auszahlen. null, solange der Anbieter ihn nicht mitgeteilt hat.
fees_covered_amountnumberAnteil der Gebühren, den der Spender übernehmen wollte (sonst 0).
provider_fee_amountnumber | nullVon Stripe oder PayPal einbehaltene Gebühren, wie von ihnen angegeben.
currencystringWährung, ISO-4217-Code in Großbuchstaben (EUR).
refunded_amountnumberBereits erstatteter Gesamtbetrag dieser Zahlung.
kindstringArt der Zahlung: donation, membership, ticket oder shop.
channelstringKanal: online (Spendenseite, Widget), campaign (Spendenaktion), qr_code, tap_to_pay oder offline (manuell erfasste Zahlung).
formobject | nullDas Ursprungsformular: type (campaign, event, membership_plan, shop, qr_code), id und title. null bei einer Spende über die Spendenseite.
recurringobject | nullBei einer monatlichen Spende: interval, sequence (first für die erste Zahlung, danach renewal) und subscription_id. Sonst null.
payment_providerstringstripe, paypal oder manual.
payment_methodstring | nullVom Anbieter angegebene Zahlungsmethode: card, sepa_debit, card_present (Tap to Pay), paypal…
walletstring | nullapple_pay oder google_pay, wenn der Spender damit bezahlt hat, sonst null.
provider_referencestring | nullReferenz der Zahlung beim Anbieter (pi_… bei Stripe, PayPal-Bestellnummer).
donorobjectDer Spender: email, name und anonymous (true, wenn er auf der öffentlichen Seite anonym bleiben wollte; Sie erhalten seine Kontaktdaten trotzdem).
createdstring (ISO 8601)Datum der Zahlung.

HTTP-Header

Jede Anfrage enthält diese Header. Bei HTTP-Headernamen wird die Groß- und Kleinschreibung nicht beachtet: Ihr Server kann sie in Kleinbuchstaben erhalten.

HeaderBeschreibung
Content-Typeapplication/jsonDer Inhalt ist UTF-8-kodiertes JSON.
User-AgentDonoor-Webhooks/1.0 (+https://donoor.org/developpeurs/webhooks)Identifiziert Donoor. Verwenden Sie ihn nicht zur Authentifizierung: Maßgeblich ist allein die Signatur.
Donoor-Signaturet=1792300000,v1=f0f590ea41b7…Zeitstempel und Signatur der Nachricht (siehe Signatur prüfen).
Donoor-Event-Idevt_9mK2xQpL4vR8sT1wIdentisch mit dem Feld id des Inhalts: praktisch, um ein Duplikat schon vor dem Lesen des JSON zu verwerfen.
Donoor-Event-Typepayment.succeededIdentisch mit dem Feld type des Inhalts.
Donoor-Delivery-Attempt1Nummer des Versuchs: 1 für die erste Zustellung, bis zu 8.

Signatur prüfen

Jeder kann eine Anfrage an Ihre Adresse senden: Prüfen Sie daher immer die Signatur, bevor Sie einer Nachricht vertrauen. Der Header Donoor-Signature enthält den Zeitstempel des Versands (t, in Sekunden) und eine oder zwei v1-Signaturen. Jede Signatur ist ein hexadezimal kodierter HMAC-SHA256 des Textes „Zeitstempel + Punkt + roher Inhalt“, berechnet mit Ihrem Secret.

Donoor-Signature: t=1792300000,v1=f0f590ea41b7f691921bb57c47f593d785d4e4d7d6c14f947848cb9d2d471bdf
  1. 1

    Lesen Sie den ROHEN Inhalt der Anfrage Byte für Byte, vor jeder JSON-Dekodierung.

  2. 2

    Lesen Sie t und alle v1-Werte aus dem Header Donoor-Signature aus.

  3. 3

    Berechnen Sie HMAC-SHA256 mit Ihrem Secret (einschließlich whsec_) über t + „.“ + Inhalt und vergleichen Sie das Ergebnis mit jedem v1-Wert über einen zeitkonstanten Vergleich. Nur einer muss übereinstimmen.

  4. 4

    Lehnen Sie die Nachricht ab, wenn t mehr als 5 Minuten von Ihrer Uhr abweicht: So kann eine abgefangene Nachricht später nicht erneut abgespielt werden.

// Node.js (Express) — der ROHE Inhalt ist für die Signatur unerlässlich
import crypto from "node:crypto";
import express from "express";

const SECRET = process.env.DONOOR_WEBHOOK_SECRET; // whsec_…
const app = express();

app.post("/webhooks/donoor", express.raw({ type: "application/json" }), (req, res) => {
  const entete = req.get("Donoor-Signature") ?? "";
  const t = /t=(\d+)/.exec(entete)?.[1];
  const signatures = [...entete.matchAll(/v1=([0-9a-f]{64})/g)].map((m) => m[1]);
  const attendue = crypto.createHmac("sha256", SECRET).update(`${t}.${req.body}`).digest("hex");

  const valide = signatures.some((s) =>
    crypto.timingSafeEqual(Buffer.from(s, "hex"), Buffer.from(attendue, "hex")));
  const recent = t && Math.abs(Date.now() / 1000 - Number(t)) < 300;
  if (!valide || !recent) return res.status(400).end();

  const evenement = JSON.parse(req.body.toString("utf8"));
  res.status(200).end(); // schnell antworten, danach verarbeiten
  traiter(evenement);    // Ereignis verarbeiten; ignorieren, wenn seine id bereits bekannt ist
});

Prüfbeispiel

Um Ihren Code zu testen, ohne auf eine echte Nachricht zu warten: Mit diesen Werten müssen Sie genau diese Signatur erhalten.

Secretwhsec_5wQpK9mZ2vX7rT4yN8bH3jL6fD1sA0cE
Zeitstempel (t)1792300000
Roher Inhalt{"id":"evt_doc0exemple0signature","object":"event","type":"test.ping"}
Erwartete v1-Signaturf0f590ea41b7f691921bb57c47f593d785d4e4d7d6c14f947848cb9d2d471bdf

Der häufigste Fehler: das JSON zu signieren, nachdem es dekodiert und erneut kodiert wurde. Schon ein Leerzeichen oder eine andere Reihenfolge der Schlüssel ändert die Signatur. Signieren Sie den Inhalt immer genau so, wie er empfangen wurde.

Secret ändern

Falls Ihr Secret von jemand anderem gesehen worden sein könnte, ersetzen Sie es: Einstellungen › Webhooks › Secret › Secret ändern.

24 Stunden lang werden die Nachrichten mit dem alten UND dem neuen Secret signiert: Der Header enthält dann zwei v1-Werte. Hinterlegen Sie das neue Secret in diesem Zeitraum auf Ihrem Server; danach funktioniert nur noch das neue.

Donoor speichert das Secret verschlüsselt. Es wird nur den Verantwortlichen und Administratoren der Organisation angezeigt.

Zulässige Adressen

  • Nur https-Adressen mit gültigem Zertifikat.
  • Port 443 (der Standard) oder 8443.
  • Die Adresse muss aus dem Internet erreichbar sein: Lokale oder private Adressen (localhost, internes Netzwerk) werden abgelehnt.
  • Weiterleitungen werden nicht verfolgt: Eine 3xx-Antwort gilt als Fehlschlag. Geben Sie die endgültige Adresse an.
  • Donoor sendet nicht von einer festen Liste von IP-Adressen: Filtern Sie nicht nach IP, sondern prüfen Sie die Signatur.

Auf eine Nachricht antworten

Antworten Sie innerhalb von 10 Sekunden mit einem 2xx-Code (200, 201, 204…). Der Inhalt Ihrer Antwort wird nicht ausgewertet, aber ihr Anfang wird zur Fehlersuche in Ihrem Zustellungsprotokoll angezeigt.

Erst antworten, dann verarbeiten: Speichern Sie die Nachricht, antworten Sie mit 200 und führen Sie lange Verarbeitungen (Aufruf von Google Ads, E-Mail-Versand…) anschließend im Hintergrund aus.

Antwort Ihres ServersWas Donoor tut
2xxErfolg: Die Nachricht wird im Protokoll als erfolgreich markiert.
3xxFehlschlag (Weiterleitung nicht verfolgt): neuer Versuch später.
4xx, 5xxFehlschlag: neuer Versuch später.
keine AntwortMehr als 10 Sekunden, Verbindung abgelehnt oder ungültiges Zertifikat: Fehlschlag, neuer Versuch später.

Wiederholungen und Pausieren

Schlägt eine Zustellung fehl, versucht Donoor es automatisch erneut: insgesamt 8 Versuche über rund 28 Stunden.

  1. 1. Zustellung
  2. +1 min
  3. +5 min
  4. +30 min
  5. +2 h
  6. +5 h
  7. +10 h
  8. +10 h
  • Nach dem 8. Versuch wird die Nachricht aufgegeben und die Organisation per E-Mail benachrichtigt (höchstens eine E-Mail pro Adresse und Tag).
  • Eine Adresse, die 3 Tage lang keine Nachricht annimmt, wird automatisch pausiert, mit einer E-Mail. Sie lässt sich im Dashboard mit einem Klick wieder aktivieren.
  • Jede Nachricht im Protokoll kann 30 Tage lang manuell erneut gesendet werden: Schaltfläche Erneut senden.

Duplikate und Reihenfolge

Dasselbe Ereignis kann mehr als einmal eintreffen: Ihr Server hat die Nachricht verarbeitet, aber seine Antwort ging verloren, oder jemand hat auf Erneut senden geklickt. Das Ereignis behält dann dieselbe id: Speichern Sie die bereits verarbeiteten id und ignorieren Sie die, die Sie schon kennen.

Die Reihenfolge des Eintreffens ist nicht garantiert: Bei einer Wiederholung kann eine Erstattung vor der ursprünglichen Zahlung eintreffen. Verlassen Sie sich auf das Feld created und den Status der Objekte, nicht auf die Reihenfolge des Empfangs.

Für eine Werbe-Conversion genügt conversion_id: Google und Meta ignorieren selbst eine Conversion, die bereits mit derselben Kennung empfangen wurde.

Limits

Adressen pro Organisation5
Maximale Antwortzeit10 Sekunden
Versuche pro Nachricht8, über rund 28 Std.
Automatisches Pausierennach 3 Tagen ohne Erfolg
Testnachrichten20 pro Stunde
Simulationen60 pro Stunde
Manuelles erneutes Senden100 pro Stunde
Nachrichten pro Tag20.000 pro Organisation
Aufbewahrung des Zustellungsprotokolls30 Tage
Aufbewahrung der Herkunftsdaten400 Tage

Ihre Kampagnen messen

Die Nachricht payment.succeeded liefert Ihnen den Betrag, die Währung, die Conversion-Kennung und die Parameter der ursprünglichen Anzeige. Ihr Server gibt die Conversion anschließend an die Werbeplattform weiter: Das ist auch dann zuverlässig, wenn der Browser Cookies oder Tracker blockiert.

Google Analytics 4

Senden Sie ein purchase-Ereignis über das Measurement Protocol: transaction_id = conversion_id, value = amount, currency = currency.

Google Ads

Mit gclid (oder gbraid / wbraid) in attribution.parameters: Importieren Sie eine Offline-Conversion über die Google Ads API, mit order_id = conversion_id, um Duplikate zu vermeiden. Erweiterte Conversions können die mit SHA-256 gehashte E-Mail-Adresse des Spenders verwenden.

Meta (Facebook, Instagram)

Über die Conversions API: event_name = Purchase, event_id = conversion_id, value und currency; fbc wird aus fbclid gebildet. Die E-Mail-Adresse des Spenders wird mit SHA-256 gehasht gesendet.

Ohne Entwickler

Fügen Sie die Adresse eines Make- oder Zapier-Szenarios ein (Modul „Benutzerdefinierter Webhook“): Anschließend verbinden Sie es mit Google Ads, GA4, Meta, Google Sheets oder Ihrem CRM, ohne Code zu schreiben.

Widget auf Ihrer Website

Erfolgt die Spende im Donoor-Widget, das in Ihre Website eingebunden ist, erhält die Seite zusätzlich das Ereignis donoor_payment im dataLayer von Google Tag Manager, ohne personenbezogene Daten und mit derselben transaction_id wie conversion_id: Browser und Server zählen nur eine Conversion.

CRM und interne Tools

Verwenden Sie donor.email als Schlüssel, um den Datensatz zu finden, kind, um zu erkennen, ob es sich um eine Spende, eine Mitgliedschaft, ein Ticket oder einen Kauf handelt, und recurring, um Ihre monatlichen Spender zu erkennen.

Beispiel: eine an GA4 übermittelte Spende

POST https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXX&api_secret=…

{
  "client_id": "donoor.32631",
  "events": [{
    "name": "purchase",
    "params": {
      "transaction_id": "32631",   // data.payment.conversion_id
      "value": 50.6,               // data.payment.amount
      "currency": "EUR",           // data.payment.currency
      "campaign": "ramadan-2027"   // data.attribution.parameters.utm_campaign
    }
  }]
}

Herkunft der Zahlungen

Fügen Sie Ihre Tracking-Parameter dem Link Ihrer Anzeigen hinzu, ob er auf Ihre Donoor-Seite oder auf die Seite Ihrer Website mit dem Donoor-Widget führt:

https://donoor.org/pay/mon-association?utm_source=google&utm_campaign=ramadan-2027&gclid=Cj0KCQjw…
  • Alle Parameter des Links bleiben bis zur Zahlung erhalten, auch wenn der Spender die Zahlungsseite in einem neuen Tab öffnet.
  • Sie erscheinen in data.attribution von payment.succeeded sowie der übrigen Ereignisse derselben Zahlung (Erstattung, Zahlungsanfechtung, monatliche Spende).
  • Bei der Verlängerung einer monatlichen Spende ist die Herkunft die der ersten Zahlung.
  • Parameter, die wie sensible Daten aussehen (E-Mail-Adresse, Passwort, Token, Telefonnummer, IBAN…), sowie die technischen Parameter von Donoor werden verworfen. Höchstens 25 Parameter, 300 Zeichen pro Wert.
  • attribution ist null, wenn der Spender nicht über einen Link mit Parametern gekommen ist.

Einwilligung

attribution.marketing_consent gibt an, ob der Spender Werbe-Cookies auf Donoor akzeptiert hat: true, false oder null, wenn unbekannt.

In Europa verlangen Google und Meta, diese Entscheidung zu respektieren (Google-Einwilligungsmodus, DSGVO). Ihre Organisation bleibt für die Verwendung dieser Daten verantwortlich: Senden Sie nicht die E-Mail-Adresse eines Spenders, der abgelehnt hat, und erwähnen Sie diese Verarbeitung in Ihrer Datenschutzerklärung.

Tests, Simulationen und Protokoll

Die Schaltfläche Test senden bei jeder Adresse sendet sofort ein Ereignis test.ping, das wie alle anderen signiert ist. Damit prüfen Sie, ob Ihr Server erreichbar und Ihre Signaturprüfung korrekt ist.

Die Schaltfläche Ereignis simulieren an jeder Adresse sendet ein beliebiges der 28 Ereignisse im exakten Format, mit fiktiven Daten und livemode auf false, nur an diese Adresse. Eine Vorschau zeigt die Nachricht vor dem Senden. Es findet keine Zahlung statt und es werden keine echten Daten gesendet.

Um in Ruhe zu entwickeln, aktivieren Sie im Fenster der Adresse die Option Testadresse: Sie empfängt dann nur Simulationen und Testnachrichten, niemals echte Ereignisse. Verbinden Sie den Entwicklungsserver Ihres Teams damit und behalten Sie eine andere Adresse für die Produktion.

Das Zustellungsprotokoll zeigt jede Nachricht der letzten 30 Tage: Ereignis, Status, Anzahl der Versuche, HTTP-Code und Anfang der Antwort Ihres Servers sowie den genauen gesendeten Inhalt. Filtern Sie nach erfolgreich, fehlgeschlagen oder ausstehend, und senden Sie eine Nachricht mit einem Klick erneut.

Testumgebung

Der Simulator genügt, um Ihre Webhooks zu entwickeln. Um auch den vollständigen Zahlungsablauf zu testen (Spendenseite, Testkarte, Beleg), stellt Donoor unter sandbox.donoor.org eine getrennte Testumgebung bereit. Ihre Seiten werden von Suchmaschinen nicht indexiert.

ProduktionTest
Websitedonoor.orgsandbox.donoor.org
Dashboarddashboard.donoor.orgdashboard-sandbox.donoor.org
Zahlungenechtfiktiv, Karte 4242 4242 4242 4242
livemodetruefalse
E-MailsnormalBetreff mit dem Präfix „[TEST]“
  1. Erstellen Sie über sandbox.donoor.org ein Organisationskonto (Schaltfläche „Meine Organisation registrieren“): Es enthält keine echten Daten.
  2. Verbinden Sie Stripe unter Einstellungen › Spendenprozess. Im Testmodus akzeptiert Stripe fiktive Angaben (SMS-Code: 000000): Ein echtes Bankkonto ist nicht nötig.
  3. Ihre Test-Zahlungsseite ist sofort online, zum Beispiel sandbox.donoor.org/pay/ihre-organisation, ebenso Ihre Test-Spendenaktionen, -Ticketverkäufe und -Shops.
  4. Fügen Sie Ihre Webhook-Adresse unter Einstellungen › Webhooks hinzu, genau wie in der Produktion.
  5. Spenden Sie auf dieser Seite mit der Testkarte 4242 4242 4242 4242 (beliebiges zukünftiges Datum, beliebiger Code): Sie erhalten echte signierte Nachrichten mit livemode auf false. Das Test-Secret unterscheidet sich von dem der Produktion.

Formatversionen

Das Feld api_version gibt die Version des Nachrichtenformats an. Sie ändert sich nur bei einer inkompatiblen Änderung (ein umbenanntes oder entferntes Feld, eine geänderte Bedeutung), die im Voraus angekündigt wird.

Ohne die Version zu ändern, kann Donoor neue Ereignisse und neue Felder hinzufügen: Ihr Code muss alles ignorieren, was er nicht kennt.

VersionÄnderungen
2026-10-17Erste öffentliche Version: 28 Ereignisse, HMAC-SHA256-Signatur, Herkunft der Zahlungen.

Fehlerbehebung

Ich erhalte keine Nachrichten

Prüfen Sie im Dashboard, dass die Adresse Aktiv ist und das erwartete Ereignis ausgewählt ist, und senden Sie dann eine Testnachricht: Das Protokoll zeigt anschließend die Antwort Ihres Servers oder den aufgetretenen Fehler an (Zertifikat, Zeitüberschreitung, nicht erreichbare Adresse). Ihre Firewall muss eingehende Anfragen aus dem Internet zulassen.

Die Signatur stimmt nie überein

In 9 von 10 Fällen wurde der Inhalt vor der Berechnung dekodiert und erneut kodiert: Verwenden Sie den rohen Inhalt. Prüfen Sie außerdem, dass Sie das vollständige Secret verwenden, einschließlich des Präfixes whsec_, und zwar das der richtigen Adresse (jede Adresse hat ihr eigenes Secret). Mit dem Prüfbeispiel oben können Sie Ihren Code testen.

Das Protokoll zeigt eine Antwort 301 oder 302

Ihr Server leitet die Anfrage weiter (oft von http zu https oder zu einer Adresse mit oder ohne abschließenden Schrägstrich). Weiterleitungen werden nicht verfolgt: Geben Sie die genaue endgültige Adresse an.

Ich erhalte dieselbe Zahlung zweimal

Das ist bei einer Wiederholung oder einem erneuten Senden normal: Das Ereignis hat dieselbe id, ignorieren Sie es. Sind die id unterschiedlich, handelt es sich um zwei verschiedene Ereignisse, zum Beispiel order.confirmed und payment.succeeded für dieselbe Bestellung.

Ich erhalte keine Zahlungen aus der Zeit vor dem Hinzufügen meiner Adresse

Das ist so gewollt: Gesendet werden nur Ereignisse, die nach dem Hinzufügen der ersten Adresse eintreten. Für frühere Daten verwenden Sie die Exporte im Dashboard.

Der Betrag entspricht nicht dem, was der Spender gezahlt hat

amount ist der Betrag für die Organisation: Die freiwillige Unterstützung für Donoor ist nicht enthalten, die vom Spender übernommenen Gebühren dagegen schon. Was tatsächlich auf Ihrem Bankkonto ankommt, ist net_amount, nach Abzug der Gebühren von Stripe oder PayPal.

Eine Frage?

Unser Team unterstützt Ihr technisches Team während der Integration.

Schreiben Sie uns