tgpay cryptoAPI
crypto-payapiinvoicesrefunds

API-Referenz: Rechnungen und Rückerstattungen

7 Min. LesezeitAktualisiert 2. Nov. 2026

Die Methoden rund um Rechnungen: createInvoice, getInvoices, deleteInvoice, refundInvoice. Die Konventionen (Authentifizierung, Antwortformat, Beträge, spend_id) stehen auf der Seite Händler-API-Referenz; die geführte Anleitung ist Zahlungen mit Rechnungen annehmen.

createInvoice

POST /pay/api/createInvoice – Berechtigung invoices, Limit 60 pro Minute.

ParameterTypPflichtBedeutung
currency_typestringneincrypto (Standard) oder fiat
assetstringKrypto-Modusdas Asset, das berechnet wird, z. B. USDT. Verwende dieses Feld statt fiat
fiatstringFiat-Modusdie Fiat-Währung, in der der Preis angegeben ist (die is_fiat-Zeilen von getCurrencies). Im Krypto-Modus wird dieses Feld ignoriert – für einen Preis in Fiat setze currency_type: "fiat"
accepted_assetsstring / arrayneinnur im Fiat-Modus: die Assets, mit denen der Zahler zahlen darf – ein kommagetrennter String ("USDT,GRAM") oder ein JSON-Array. Weggelassen = alle unterstützten Assets
amountstringja, außer wenn open_amount gesetzt istpositiver Dezimalstring: Asset-Einheiten im Krypto-Modus, Fiat-Einheiten (max. 2 Nachkommastellen) im Fiat-Modus
open_amountbooleanneinErweiterung, nur im Krypto-Modus: kein fester Betrag – der Zahler gibt ihn bei der Zahlung ein (Spenden und Trinkgelder). Schließt sich mit amount gegenseitig aus
descriptionstringneinbis zu 1024 Zeichen, wird dem Zahler angezeigt
hidden_messagestringneinbis zu 2048 Zeichen, wird dem Zahler erst nach der Zahlung gezeigt
payloadstringneinbis zu 4096 Zeichen eigener Daten, die auf der Rechnung und im Webhook zurückgegeben werden
allow_commentsbooleanneinerlaubt dem Zahler, einen Kommentar anzuhängen (Standard true)
allow_anonymousbooleanneinerlaubt dem Zahler, seine Identität zu verbergen (Standard true)
paid_btn_namestringneinButton nach der Zahlung: viewItem, openChannel, openBot oder callback
paid_btn_urlstringneindie http(s)-URL des Buttons, bis zu 512 Zeichen – Pflicht, wenn paid_btn_name gesetzt ist, ohne paid_btn_name wird sie ignoriert
swap_tostringneintauscht empfangene Zahlungen automatisch in dieses Asset. Falls möglich: Lässt sich der Tausch bei der Zahlung nicht ausführen, wird die Zahlung trotzdem ohne Tausch abgeschlossen
expires_inintegerneinSekunden, bis die Rechnung abläuft, bis zu 2678400 (31 Tage); weggelassen oder 0 = Standardlaufzeit, derzeit ebenfalls 31 Tage. Lies expiration_date aus dem Ergebnis
rate_lock_secondsintegerneinErweiterung, nur im Fiat-Modus: schreibt die Umrechnungskurse bei der Erstellung für dieses Zeitfenster fest (siehe unten)

Beschreibung, Inhalte nach der Zahlung und der Button können für Zahlende verborgen bleiben, solange sie geprüft oder noch nicht freigegeben sind. Der Rechnungsbetrag bleibt bezahlbar.

Das Ergebnis – und der Payload des Webhooks invoice_paid – ist das Rechnungsobjekt. Seine wichtigsten Felder:

  • Identität und Zustand: invoice_id, hash (die öffentliche ID in pay_url), status (active / paid / expired), pay_url – der t.me-Link, den du dem Zahler schickst (bot_invoice_url, mini_app_invoice_url, web_app_invoice_url sind Aliasse davon).
  • Beträge: amount (der Nennwert – Fiat-Einheiten auf einer Fiat-Rechnung, sonst Krypto; null, solange eine Rechnung mit freiem Betrag unbezahlt ist), amount_minor (immer kleinste Krypto-Einheiten: bei einer Krypto-Rechnung der Nennwert; bei einer Fiat-Rechnung bis zur Zahlung null, danach die kleinsten Einheiten von paid_asset; bei einer Rechnung mit freiem Betrag bis zur Zahlung null) und auf bezahlten Fiat-Rechnungen paid_asset / paid_amount / paid_fiat_rate – die tatsächlich belastete Kryptowährung, der belastete Betrag und der verwendete Kurs. asset bleibt bei einer Fiat-Rechnung null, auch nach der Zahlung.
  • Gebühr: fee_asset / fee_amount, bei der Zahlung festgehalten – die maßgebliche Zahl für deine Bücher (fee und usd_rate sind veraltete Crypto-Bot-Aliasse). Siehe Gebühren und Limits.
  • Zahler: paid_by_user_id (null, wenn der Zahler Anonymität gewählt hat), paid_anonymously, comment.
  • Rückerstattungen (Erweiterung): refunded_amount / refunded_minor (kumuliert) und refunded_at, festgehalten, sobald die Rechnung vollständig erstattet wurde.
  • Kursfestschreibung (Erweiterung): rate_lock_until und rate_lock_rates – die festgehaltenen Kurse pro Asset, null, wenn keine Festschreibung angefordert wurde.
  • Zeitpunkte und Zahlungsdaten: created_at, paid_at, paid_usd_rate (der bei der Zahlung festgehaltene USD-Kurs).
  • Angaben bei der Erstellung: currency_type, accepted_assets, open_amount, is_anonymous, description, hidden_message, payload, paid_btn_name / paid_btn_url, expiration_date (expires_at ist ein Alias), die Tausch-Felder (swap_to, is_swapped, swapped_to, swapped_rate, swapped_output, …).

Fehler: 400 invalid_currency (im Krypto-Modus fehlt asset; im Fiat-Modus fehlt fiat, es wurde zusätzlich asset gesendet oder open_amount gesetzt), 400 invalid_amount (auch ein Betrag, der bei der Genauigkeit des Assets auf null gerundet wird), 400 unknown_asset, 400 unsupported_fiat, 400 paid_btn_url_required sowie bei Anfragen mit Kursfestschreibung 400 rate_lock_fiat_only, 409 ratelock_disabled, 409 rate_unavailable (kein frischer Kurs für ein akzeptiertes Asset – wiederholen). 400 invalid_request steht für fehlerhafte Parameter: ein unbekannter Wert von currency_type oder paid_btn_name, ein Text über seiner Längengrenze, ein expires_in außerhalb von 0–2678400, ein als JSON-Zahl gesendeter Betrag.

Wie Rechnungen bezahlt werden

Der Zahler zahlt aus dem Guthaben seiner Wallet in der Mini App – sofort und ohne Netzwerkgebühr, sofern genügend Guthaben verfügbar ist und die Zahlung bestätigt wird. Er kann die Rechnung auch aus einer externen Wallet finanzieren: Ist die Option verfügbar, zeigt die App eine Einzahlungsadresse und eine Zahlungsfrist. Die Einzahlung geht in seine eigene Wallet. Die automatische Zahlung erfordert eine Einzahlung an diese Adresse, genügend verfügbares Guthaben, keine Einschränkung ausgehender Zahlungen sowie ein gültiges Zahlungsangebot und eine gültige Rechnung. Eine verspätete Einzahlung bleibt in der Wallet des Zahlers; sie beweist nicht, dass die Rechnung bezahlt wurde. In beiden Fällen siehst du dasselbe: eine Rechnung mit paid und, bei eingerichteter Webhook-URL, ein Ereignis invoice_paid. Zusätzliche Parameter oder Felder musst du nicht verarbeiten.

Bei einer Fiatrechnung wird der Kryptobetrag zum Zahlungszeitpunkt berechnet und auf die kleinste Einheit des gewählten Assets aufgerundet. Davon wird dann die Händlergebühr abgezogen. Ist weder ein gültiger festgeschriebener noch ein aktueller Kurs verfügbar, schlägt die Zahlung auf der Seite des Zahlers fehl, statt zu einem veralteten Kurs abgerechnet zu werden.

Den Kurs auf einer Fiat-Rechnung festschreiben

Übergib rate_lock_seconds, um bei der Erstellung den aktuellen Kurs jedes akzeptierten Assets festzuhalten. Solange die Festschreibung gilt, sieht der Zahler genau die festgehaltenen Beträge, und die Zahlung wird zum festgehaltenen Kurs umgerechnet – du trägst für diesen Zeitraum das Kursrisiko. Zulässig sind 0 bis 86400 Sekunden: 0 bedeutet keine Kursbindung. Andere Werte werden an das unterstützte Zeitfenster angepasst – mindestens 60 Sekunden, höchstens das Plattformmaximum. Werte außerhalb von 0–86400 werden mit 400 invalid_request abgelehnt. Die tatsächliche Frist steht im Ergebnis unter rate_lock_until.

Läuft die Kursfestschreibung ab, bleibt eine noch nicht abgelaufene Rechnung zum Kurs des Zahlungszeitpunkts bezahlbar. Sollen beide Fristen zusammenfallen, wähle expires_in innerhalb der unterstützten Festschreibungsdauer und vergleiche expiration_date mit rate_lock_until in der Antwort.

getInvoices

GET /pay/api/getInvoices – Berechtigung read. Filter: asset, fiat, invoice_ids (kommagetrennt), status (active / paid / expired – expired ist eine Erweiterung; active schließt Rechnungen aus, deren Frist bereits abgelaufen ist), dazu offset / count (Standard 100, max. 1000). Liefert {"items": [invoice, …]}, neueste zuerst.

deleteInvoice

POST /pay/api/deleteInvoice – Berechtigung invoices. Ein Parameter: invoice_id. Löscht eine unbezahlte Rechnung – aktiv oder abgelaufen – und liefert true. Die Rechnung wird entfernt, nicht nur markiert: Sie verschwindet aus getInvoices, ihre pay_url funktioniert nicht mehr, und es wird kein Webhook gesendet. Halte die Löschung bei Bedarf auf deiner Seite fest. Fehler: 404 invoice_not_found, 409 invoice_already_paid – eine bezahlte Rechnung lässt sich nicht löschen, weil das Geld bereits bewegt wurde.

refundInvoice

POST /pay/api/refundInvoice – Berechtigung refunds, Limit 30 pro Minute. Eine Erweiterung gegenüber Crypto Bot: Sie erstattet die tatsächlich gezahlte Krypto ganz oder teilweise aus deinem App-Guthaben an den Zahler. Das gilt auch bei anonymen Zahlungen, ohne die Identität offenzulegen. Bei einer Fiatrechnung gelten paid_asset und paid_amount; die Erstattung ist keine neue Fiatumrechnung.

ParameterTypPflichtBedeutung
invoice_idintegerjadie bezahlte Rechnung
amountstringneinder zu erstattende Kryptobetrag im ursprünglich gezahlten Asset (paid_asset bei Fiatrechnungen). Weggelassen = der gesamte noch nicht erstattete Rest. Teilerstattungen summieren sich höchstens bis zum ursprünglich gezahlten Kryptobetrag
spend_idstringneinIdempotenzschlüssel – nutze einen, damit eine Wiederholung nach einem Timeout das Ergebnis wiedergibt, statt zweimal zu erstatten

Das Ergebnis ist das aktualisierte Rechnungsobjekt mit dem kumulierten refunded_amount / refunded_minor; refunded_at wird festgehalten, sobald die Rechnung vollständig erstattet ist. Der Status bleibt paid. Die Plattformgebühr wird nicht zurückgegeben. Deine App braucht genügend Guthaben im ursprünglichen Zahlungsasset, auch wenn swap_to den Eingang in ein anderes Asset getauscht hat. Jede Rückerstattung löst den optionalen Webhook refund_completed aus.

Fehler: 404 invoice_not_found, 409 invoice_not_paid, 409 already_refunded (es ist nichts mehr zu erstatten), 409 amount_too_big (mehr als der noch nicht erstattete Rest), 409 insufficient_funds, 400 invalid_amount, 400 invalid_request (invoice_id fehlt oder spend_id ist länger als 64 Zeichen), 403 verification_required (ausgehende Vorgänge des Inhabers sind eingeschränkt), 503 merchant_payouts_paused und das spend_id-Paar 409 idempotency_conflict / 409 idempotency_in_progress.