Zum Inhalt springen

Wie geht eine Bestellung raus, die niemand bezahlt hat?

15. Sept. 2026 12 Min. Lesezeit Paymos Tech Paymos Tech
Fünf orange gepunktete Pfade laufen von links heran und enden abrupt vor einer hohen weißen Platte, dahinter steht eine kleinere unberührt

Kurz gefasst

Betrug bei Krypto-Zahlungen lebt in der Lücke zwischen der Behauptung, man habe bezahlt, und dem Moment, in dem die Ware rausgeht. Sieben Angriffe passen in diese Lücke, und keiner braucht eine Schwäche der Blockchain: ein Hash, der keine Rechnung bezahlt; Geld, das die Adresse erreicht und die Rechnung stehen lässt; ein Browser, dem Preis oder Status geglaubt wird; ein gefälschter Callback; ein wiederholter; eine Erstattung an eine fremde Adresse; und das Händlerkonto selbst. Jeder hat eine Kontrolle, die ihn aufhält, und jede Kontrolle hat eine Stelle, an der sie aufhört.

Es fängt fast immer im Support an. Ein Kunde schreibt, er habe bezahlt, hängt einen Screenshot an und fragt, wann geliefert wird.

Betrug gegen eine Krypto-Zahlung kann keine Rückbuchung sein. Ist ein Transfer endgültig, gibt es kein Verfahren, auf das man sich berufen könnte, und keinen Herausgeber, der dem Händler das Geld wieder abzieht. Übrig bleibt das Fenster davor: die Minuten zwischen der Behauptung und dem Moment, in dem ein Lager, ein Lizenzserver oder eine Kollegin handelt.

Sieben Angriffe passen in dieses Fenster. Jeder steht unten neben der Kontrolle, die ihn aufhält, und neben der Stelle, an der diese Kontrolle aufhört — denn eine Kontrolle, die man ohne ihre Grenze beschreibt, wird über diese Grenze hinaus geglaubt. Mit Blockchain hat das wenigste davon zu tun: eine gefälschte Nachricht, ein Browser, dem geglaubt wird, eine umgelenkte Auszahlung. Dieselben Tricks wie gegen ein Anmeldeformular, nur gegen eine Zahlung gerichtet.

Was beweist ein Transaktions-Hash?

Dass es den Transfer gibt. Sonst nichts.

Genau darin liegt die Falle. Kopieren Sie den Hash in einen Block-Explorer, und es kommt ein echter Transfer zurück, mit Betrag und Token-Symbol daneben. Keines der drei verbindet ihn mit Ihrer Rechnung, und das Symbol wiegt am wenigsten: In EIP-20 sind name und symbol optional, und der Standard weist Schnittstellen ausdrücklich an, sich nicht darauf zu verlassen, dass diese Werte überhaupt vorhanden sind.

Dieses Symbol ist eine Zeichenkette, die sich der Autor eines Vertrags ausgesucht hat.

Die Kontrolle ist der Zustand der Rechnung. Gutgeschrieben wird eine Zahlung, wenn ein Transfer die Adresse dieser Rechnung erreicht und bis zu der Tiefe bestätigt ist, die für sein Netzwerk und seine Größe gilt — auf Ethereum zwei Blöcke bis 100 $, zweiunddreißig oberhalb von 10.000 $, während sechs Netzwerke bei Netzwerkfinalität abrechnen statt bei einer Blockzahl.

Jeder erkannte Transfer steht auf der Checkout-Seite, während der Zahler zusieht, unbestätigte eingeschlossen.

Tiefe ist eine Abwägung gegen absolute Finalität und kein Beweis dafür. Fällt ein bereits gutgeschriebener Transfer später durch eine Reorganisation aus der Kette, bleibt die Gutschrift des Händlers unangetastet, und den Verlust trägt die Plattform.

Die Rechnung beantwortet, ob Geld angekommen ist. Ob diese Bestellung rausgehen soll, beantwortet sie nie.

Wer bestimmt den Preis: Ihr Server oder die Seite des Käufers?

Wenn der Betrag aus der Seite kommt, nennt der Käufer den Preis. Das Low-Code-SDK löst ihn aus fünf Quellen in fester Reihenfolge auf, und die fünf sind nicht gleich sicher. Eine price_id verweist auf einen Preis, der auf dem Server liegt; die Anfrage trägt dann überhaupt keinen Betrag. Ein amount_selector dagegen liest das .value eines Eingabefelds.

Auf einer Seite, die der Käufer bearbeiten kann, ist das eine Preisangabe des Käufers. MITRE führt die Klasse als CWE-602: ein Server, der sich für einen Schutz, der ihm selbst gilt, auf den Client verlässt.

Die zweite Hälfte desselben Fehlers betrifft den Zustand. Manche Anbindungen markieren die Bestellung auf der Rückkehr-URL als bezahlt oder an einem JavaScript-Ereignis aus dem Checkout-Overlay. Fünf solcher Ereignisse gibt es, alles CustomEvents auf window, und sie berichten, was das Overlay getan hat.

Für einen Ladebalken taugt das. Als Zahlungswahrheit nicht, denn wer eine Konsole öffnen kann, löst sie selbst aus.

Den Preis auf den Server zu ziehen, macht einen Checkout nicht sicher. Es nimmt eine Entscheidung aus der Reichweite. Ein Warenkorb, dessen Summe je Bestellung wechselt, braucht weiterhin Ihre eigene Preislogik, und der bezahlte Zustand muss weiterhin von einer Stelle kommen, auf die der Käufer nicht schreiben kann.

Warum kommt Geld an, ohne dass die Bestellung schließt?

Weil ein Transfer die Adresse erreichen und trotzdem keine Rechnung bezahlen kann.

Vier der Formen kann ein Käufer von Hand herstellen: ein Transfer nach Ablauf des Zahlungsfensters, einer gegen eine bereits bezahlte, abgelaufene oder stornierte Rechnung, einer in einem anderen Asset — USDC gegen eine in USDT ausgestellte Rechnung — und einer auf eine Adresse, an der gerade keine Rechnung hängt. Gutgeschrieben wird jeder davon, abzüglich der üblichen Abwicklungsgebühr.

Die Rechnung rührt sich dabei nicht. Ein Webhook läuft ebenfalls nicht los: Eine Gutschrift dieser Art hat überhaupt kein Ereignis, und ein System, das nur am Ereignisstrom hängt, erfährt nie davon. Ein Mensch erfährt es schon — der Hinweis geht per E-Mail und an die Glocke im Dashboard —, und auf der Guthabenseite steht dazu ein eigener Block mit Grund, Betrag, Gebühr sowie Absender und Hash, sofern sie bekannt sind.

Damit schreibt der Käufer einen wahren Satz. Schauen Sie auf Ihr Guthaben, das Geld ist da. Es ist da. Wer die Ankunft bestätigt und daraufhin liefert, schließt etwas, das die Rechnung weiterhin als unbezahlt führt. Deshalb steht dieser Angriff so weit oben: Er braucht keine Fälschung, sondern nur einen hilfsbereiten Menschen mit Zugriff auf die richtige Seite.

Zugunsten des Händlers geht ein Fall aus, der den vier Formen oben zunächst gleicht. Kommt dasselbe Asset über ein anderes angenommenes Netzwerk, zählt es eins zu eins auf die Rechnung, sofern deren Adresse dieses Netzwerk annimmt. Nicht jede tut das, und Geld über eine Kette, die die Adresse nicht abdeckt, bleibt liegen, wo es gelandet ist.

Die Grenze ist hart. Das Geld hat den Händler erreicht, und etwas davon zurückzuschicken ist eine ausgehende Überweisung, die jemand auslösen muss. Eine Selbstbedienung für Zahler gibt es nicht, und auf der Zahlungsebene wird keine Rückgabe versprochen.

An eine Callback-URL schreiben kann jeder

Sie ist eine Adresse im offenen Internet, und sie nimmt JSON entgegen.

Ein gefälschtes invoice.paid braucht keinen Zugang zu irgendetwas: die richtige Form, die richtige Rechnungs-ID und einen Handler, der den Körper liest. CWE-345 ist der Eintrag dafür — ein Produkt, das Herkunft oder Echtheit der Daten nicht ausreichend prüft und deshalb ungültige Daten annimmt.

Jede Zustellung ist mit HMAC-SHA256 signiert, und der Header X-Webhook-Signature ist zusammengesetzt: ein Zeitstempel und ein oder mehrere v1-Werte. Während eines Wechsels des Geheimnisses trägt er 24 Stunden lang zwei, und jeder der beiden darf passen — deshalb liest ein Empfänger v1 als Liste und nicht als Feld.

Was genau gehasht wird und wie der zeitkonstante Vergleich je Sprache aussieht, steht auf der Seite zur Signaturprüfung; hier geht es um die Vertrauensentscheidung, nicht um den Code.

Dann kommt die Wiedereinspielung (Replay), und die überrascht regelmäßig. X-Webhook-Timestamp steht auf jeder Zustellung, und ausgehend wird kein eigenes Fenster erzwungen — die Toleranz gehört dem, der prüft.

Die Dokumentation bittet um Ablehnung jenseits von 300 Sekunden, und die offiziellen SDKs setzen fünf Minuten als Voreinstellung, sodass eine Anbindung auf einem SDK die Prüfung erbt.

Ein von Hand gegen den HMAC allein geschriebener Prüfer nimmt eine mitgeschnittene Zustellung eine Woche später an, und die Signatur darauf ist echt.

Ein Ereignis, zwei Zustellungen, zwei Lieferungen

Die meisten Doppel sind kein Angriff. Deshalb ist dieser Handler so leicht falsch gebaut. Ein Versuch, der in sein Zeitlimit von zehn Sekunden läuft, wird wiederholt; ein Zyklus umfasst elf Versuche von einer Minute bis acht Stunden, insgesamt rund sechzehn Stunden, und ein gescheitertes Ereignis lässt sich von Hand nachsenden.

Dazu kommt die Verteilung: Zwei Endpunkte auf derselben Kategorie ergeben zwei Zustellungen einer einzigen geschäftlichen Tatsache.

Ein Angreifer muss nur eine mitgeschnittene Zustellung noch einmal schicken.

In einer Anfrage reisen zwei Kennungen, und die Kontrolle besteht darin, jeder ihre eigene Aufgabe zu geben. X-Webhook-Id — das evt_… — ist die Zustellkennung, darüber fangen Sie Doppel ab. Das inv_… in data ist die geschäftliche Kennung, über alle Endpunkte und alle Zustandswechsel hinweg dieselbe, und darüber verbuchen Sie die Bestellung.

Vertauscht scheitert es in beide Richtungen: Über die Zustellkennung geschlüsselt, verbuchen zwei Endpunkte eine Zahlung zweimal; über die Rechnungs-ID dedupliziert, fällt das paid weg, das auf confirming folgt. Den Handler Schritt für Schritt führt der Artikel zur Webhook-Idempotenz.

Abgefangen wird der zweite Lauf, nicht die zweite Ankunft. Zugestellt wird weiter, solange der Zyklus läuft, und ein erschöpfter Zyklus lässt das Ereignis scheitern, nicht den Endpunkt.

Ein confirming, das Stunden auf der Leiter verbracht hat, kann auch nach dem paid landen, das ihm gefolgt war. Wer anwendet, was zuletzt ankam, schiebt eine bezahlte Bestellung rückwärts.

Wohin geht die Erstattung?

An die Adresse, die der Bearbeiter eingefügt hat.

Dieser Angriff kostet nichts und berührt Ihre Systeme nie. Eine Erstattungsanfrage kommt herein und bringt ihr Ziel gleich mit — aus einem Kundenpostfach, in dem jemand anders mitliest, oder von einer Kollegin, der man es eingeredet hat.

Die Kontrolle ist die Freigabeliste. Eine Auszahlung darf nur ein Ziel nennen, das bereits daraufsteht, und eine leere Liste deaktiviert Auszahlungen vollständig. Einträge sind nach Adresse und Netzwerkgruppe geschlüsselt statt nach einzelnem Netzwerk: Eine EVM-Adresse einmal freigegeben, und dieser eine Eintrag deckt jedes EVM-Auszahlungsnetzwerk. Entfernen ist ein Widerruf und kein Löschen — die Zeile bleibt stehen, damit das Prüfprotokoll vollständig bleibt.

Eine Adresse hinzuzufügen ist eine privilegierte Aktion und landet in diesem Protokoll.

An zwei Stellen hört das auf. Die erneute Authentifizierung bei einer Änderung der Liste ist nicht bedingungslos: Für ein Konto ohne zweiten Faktor entfällt sie, weil sie einen vorhandenen Faktor verstärkt und keinen erzeugen kann.

Als Schutz, den Sie bereits haben, ist sie keiner. Sie kommt in dem Moment dazu, in dem jemand TOTP oder einen Passkey einrichtet.

Die zweite Stelle ist die Größe einer einzelnen Freigabe. Bis zu tausend Adressen gehen in einer Anfrage unter einer einzigen erneuten Authentifizierung auf die Liste, und ein CSV-Import nutzt das aus: eine Benachrichtigung für die ganze Datei statt einer je Adresse.

Bequemlichkeit und Reichweite sind hier dieselbe Zahl. Lesen Sie also die Liste. Wem das Wallet am anderen Ende gehört, steht ohnehin nirgends darin: Ein Händler darf die Adresse eines Kunden mit Absicht freigeben.

Wer Anspruch hat, bis wann und wer zustimmt, gehört in eine Erstattungsrichtlinie.

Wenn der Angreifer schon angemeldet ist

Jede Kontrolle oben gehorcht dem Konto, das sie eingerichtet hat. Aus dem Dashboard heraus lässt sich die Callback-URL ändern, das Webhook-Geheimnis wechseln und die Freigabeliste bearbeiten. Keiner der sechs Angriffe davor wird noch gebraucht, sobald die Sitzung jemand anderem gehört.

Ein Passwort zum Abphishen gibt es auf dem Konto nicht. Angemeldet wird über einen Magic Link per E-Mail, Google, Telegram-OIDC, wo es freigeschaltet ist, oder einen Passkey; TOTP steht als zweiter Faktor daneben.

Für diesen Angriff ist der Passkey der stärkste der vier, weil er an seinen Entstehungsort gebunden ist: WebAuthn bindet eine Anmeldeinformation an die Gegenstelle, bei der sie registriert wurde, und der Authenticator schreibt den Ursprung in jede Antwort. Spielt jemand diese Antwort anderswo wieder ein, trägt sie den falschen Ursprung.

Eine täuschend echte Domain sammelt damit nichts Brauchbares ein.

Die erneute Authentifizierung steht vor drei Aktionen — den zweiten Faktor abschalten, die Freigabeliste ändern, die IP-Liste eines API-Schlüssels bearbeiten — und jeder Geltungsbereich ist ein eigenes Ticket: Ein Code, den jemand für die eine Aktion abfängt, autorisiert die nächste nicht.

Ein Auszahlungsschlüssel trägt außerdem eine Bedingung, die es für einen Zahlungsschlüssel gar nicht gibt: Bleibt seine IP-Liste leer, zählt er nicht als unbeschränkt, sondern fällt schon bei der Authentifizierung durch.

Kein Passwort heißt nicht keine Sitzung. Ein Magic Link landet in einem Postfach, und das Postfach wird als Erstes übernommen; der zweite Faktor schließt diesen Weg, und eingerichtet ist er bei niemandem von allein. Nachlesen lassen sich hinterher die eigenen protokollierten Aktionen und der Anmeldeverlauf; das vollständige Protokoll der Plattform bleibt beim Betreiber.

Welche Hälfte davon müssen Sie selbst bauen?

Die sieben Kontrollen liegen nicht auf derselben Seite der Schnittstelle.

Drei halten unabhängig davon, was jemand tut: der Zustand der Rechnung, die Freigabeliste vor einer Auszahlung und die Weigerung, eine Rechnung auf einen Transfer hin zu schließen, der sie nicht bezahlt hat. Die anderen vier gibt es nur, wenn Ihr Code sie baut — Signatur und Zeitstempel prüfen, über die Zustellkennung deduplizieren, den Preis auf dem Server halten und den zweiten Faktor einrichten, der die erneute Authentifizierung überhaupt einschaltet. Jedes davon ist ein Nachmittag Arbeit.

Ein Fall liegt außerhalb dieser Liste. Eine Signatur sagt, dass ein Schlüssel den Transfer autorisiert hat, nie dass sein Inhaber das wollte, und nichts auf der Händlerseite unterscheidet ein gestohlenes Wallet von einem guten Kunden. Das ist ein Prozess im Support und eine Entscheidung über Lieferbedingungen, keine technische Kontrolle, und keine Sicherheitsseite wird das je schließen.

Sieben Angriffe, ihre Kontrolle und wer sie bauen muss (September 2026)
AngriffWas ihn aufhältWo die Kontrolle endetWer sie baut
Zahlungsnachweis kommt vom KäuferDer Zustand der Rechnung, gutgeschrieben ab der gültigen TiefeOb die Bestellung rausgehen soll, bleibt eine kaufmännische FragePaymos
Geld erreicht die Adresse, zahlt aber keine RechnungDie Rechnung rückt nicht; die Gutschrift kommt mit ihrem GrundKein Webhook, also hört eine reine Ereignis-Anbindung nichts davonPaymos
Preis oder Status entstehen im BrowserPreis auf dem Server halten, Status vom Server lesenEin wechselnder Warenkorb braucht trotzdem Ihre eigene PreislogikIhr Code
Gefälschter CallbackSignatur nach HMAC-SHA256, zeitkonstant verglichen, v1 als ListeWiedereinspielung — das Zeitfenster wählt der EmpfängerIhr Code
Ein Ereignis, mehrfach zugestelltDoppel über X-Webhook-Id abfangen, Bestellung über die ID in dataDie Zustellungen kommen weiter; gestoppt wird nur der zweite LaufIhr Code
Erstattung an eine mitgelieferte AdresseAuszahlung nur an freigegebene Ziele, leere Liste sperrt allesEine Freigabe kann tausend Adressen auf einmal eintragenPaymos
Der Angreifer ist bereits angemeldetKein Passwort zum Abphishen; Passkeys, TOTP, Bestätigung je AktionDer zweite Faktor ist freiwillig, und ohne ihn wird nicht gefragtBeide

Häufige Fragen

Was ist Betrug bei Krypto-Zahlungen?

Der Versuch, Ware, Guthaben oder eine Auszahlung für Geld zu bekommen, das nie gegen die Bestellung abgerechnet wurde. Auf einer Blockchain gibt es keine Rückabwicklung, also muss der Versuch vor der Lieferung landen statt Wochen danach.

Beweist ein Transaktions-Hash, dass eine Rechnung bezahlt ist?

Nein. Ein Hash beweist, dass es einen Transfer auf einer Kette gibt. Ob er die Adresse dieser Rechnung erreicht hat, in einem angenommenen Asset, vor Ablauf des Zahlungsfensters und bis zur nötigen Bestätigungstiefe, beantwortet der Zustand der Rechnung.

Warum ist Geld eingegangen, ohne dass die Rechnung als bezahlt gilt?

Weil der Transfer die Adresse erreicht hat, ohne die Rechnung zu bezahlen: nach Ablauf des Zahlungsfensters, gegen eine bereits bezahlte oder stornierte Rechnung oder in einem anderen Asset. Das Guthaben nimmt ihn abzüglich der üblichen Abwicklungsgebühr auf, die Rechnung bleibt stehen, und ein Webhook läuft dafür nicht los.

Kann jemand einen Zahlungs-Webhook fälschen?

An eine Callback-URL schreiben kann jeder, und genau deshalb trägt jede Zustellung eine Signatur nach HMAC-SHA256 über den unveränderten Rohkörper. Vergleichen Sie zeitkonstant, lesen Sie die v1-Werte im Header als Liste und prüfen Sie den Zeitstempel — die Signatur allein hält keine Wiedereinspielung auf.

Verlangt Paymos einen zweiten Faktor, bevor eine Auszahlungsadresse dazukommt?

Nur dort, wo für den Zugang bereits TOTP oder ein Passkey hinterlegt ist. Die erneute Authentifizierung verstärkt einen zweiten Faktor, sie erzeugt keinen; ein Zugang ohne zweiten Faktor wird nicht gefragt. Die Freigabeliste selbst gilt immer, und eine leere Liste deaktiviert Auszahlungen vollständig.

Wie verhindere ich, dass ein doppelter Webhook zweimal ausliefert?

Über die Zustellkennung, nicht über die Rechnung. Jede Zustellung trägt in X-Webhook-Id ein eigenes evt_…; sehen Sie eines zum zweiten Mal, ist die Arbeit schon getan. Verbucht wird die Bestellung über die Rechnungs-ID in data. Wer die Bestelltabelle über die Zustellkennung schlüsselt, verbucht zwei Endpunkte als zwei Zahlungen.

Wann eine eigene Betrugsprüfung NICHT passt

  • Kam das Geld im falschen Asset oder nach Ablauf des Fensters an, ist das Abgleicharbeit und kein Betrugsfall. Die Guthabenseite nennt den Grund bereits; ein Bewertungsmodell fügt einer ablesbaren Tatsache nichts hinzu.
  • Verkaufen Sie an benannte Kunden auf Rechnung, ist die Identität die Kontrolle, die Sie längst haben. Eine Prüfung davor erzeugt vor allem eine Warteschlange für Bestellungen, die Sie ohnehin ausgeliefert hätten.
  • Liegen Ihre Preise auf dem Server und wartet die Auslieferung auf einen geprüften Endzustand der Rechnung, sind die sieben Angriffe hier bereits geschlossen. Eine geschlossene Tür zu bewerten, kauft Ihnen Fehlalarme.
  • Macht Ihnen ein gestohlenes Wallet Sorgen, das bei Ihnen bezahlt, sieht das auf Ihrer Seite niemand. Die Kette prüft einen Schlüssel und nicht den Menschen dahinter, und daran ändert keine Prüfung vor der Lieferung etwas.

Quellen

  1. 1. EIP-20 — Token Standard (accessed 2026-09-15)
  2. 2. CWE-602 — Client-Side Enforcement of Server-Side Security (accessed 2026-09-15)
  3. 3. CWE-345 — Insufficient Verification of Data Authenticity (accessed 2026-09-15)
  4. 4. W3C — Web Authentication: An API for accessing Public Key Credentials Level 2 (accessed 2026-09-15)
  5. 5. Paymos — Signaturen prüfen (accessed 2026-09-15)
  6. 6. Paymos — Sicherheit (accessed 2026-09-15)

Zuletzt geprüft 15. Sept. 2026

#betrug#webhooks#sicherheit#zahlungsrisiko
Teilen