tgpay cryptoAPI
crypto-payapiinvoicesrefunds

API-Referenz: Rechnungen und Rückerstattungen

6 Min. LesezeitAktualisiert 9. Okt. 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)
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 – Pflicht, wenn paid_btn_name gesetzt ist
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. 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 und auf bezahlten Fiat-Rechnungen paid_asset / paid_amount / paid_fiat_rate – die tatsächlich berechnete Kryptowährung und der verwendete Kurs.
  • 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.
  • Angaben bei der Erstellung: 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 (Asset und Fiat verwechselt), 400 invalid_amount, 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).

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. Der Server passt die angeforderte Dauer an den unterstützten Bereich an. 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. Liefert {"items": [invoice, …]}, neueste zuerst.

deleteInvoice

POST /pay/api/deleteInvoice – Berechtigung invoices. Ein Parameter: invoice_id. Storniert eine unbezahlte Rechnung und liefert true. Fehler: 404 invoice_not_found, 409 invoice_already_paid – eine bezahlte Rechnung lässt sich nicht löschen, das Geld ist bereits bewegt worden.

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 und das spend_id-Paar 409 idempotency_conflict / 409 idempotency_in_progress.