tgpay cryptoAPI
crypto-payapiinvoicesrefunds

Riferimento API: fatture e rimborsi

6 min di letturaAggiornata il 22 ago 2026

I metodi delle fatture: createInvoice, getInvoices, deleteInvoice, refundInvoice. Le convenzioni comuni (autenticazione, busta, importi, spend_id) stanno nella pagina Riferimento della Merchant API; la guida passo passo è Incassare con le fatture.

createInvoice

POST /pay/api/createInvoice — ambito invoices, limite 60 al minuto.

ParametroTipoObbligatorioDescrizione
currency_typestringanocrypto (predefinito) oppure fiat
assetstringain modalità cryptol’asset da addebitare, per esempio USDT. Non si può usare insieme a fiat
fiatstringain modalità fiatla valuta fiat in cui è il prezzo (le righe is_fiat di getCurrencies)
accepted_assetsstringa / arraynosolo in modalità fiat: gli asset con cui chi paga può pagare — una stringa separata da virgole ("USDT,GRAM") o un array JSON. Se lo ometti, tutti gli asset supportati
amountstringasì, a meno che tu non usi open_amountstringa decimale positiva: unità dell’asset in modalità crypto, unità di valuta (al massimo 2 decimali) in modalità fiat
open_amountbooleanonoestensione, solo in modalità crypto: nessun importo fisso, lo digita chi paga al momento (donazioni e mance). Non si può usare insieme ad amount
descriptionstringanofino a 1024 caratteri, mostrata a chi paga
hidden_messagestringanofino a 2048 caratteri, si svela a chi paga solo dopo il pagamento
payloadstringanofino a 4096 caratteri di dati tuoi, che ti rimandiamo indietro nella fattura e nel webhook
allow_commentsbooleanonopermette a chi paga di allegare un commento (predefinito true)
allow_anonymousbooleanonopermette a chi paga di non farsi riconoscere (predefinito true)
paid_btn_namestringanoil pulsante dopo il pagamento: viewItem, openChannel, openBot o callback
paid_btn_urlstringanol’URL http(s) del pulsante: obbligatorio quando c’è paid_btn_name
swap_tostringanoconverte da solo i pagamenti ricevuti in questo asset. Non è garantito: se al momento del pagamento lo scambio non si può fare, il pagamento riesce comunque, non convertito
expires_ininteronosecondi prima che la fattura scada, fino a 2678400 (31 giorni); assente o 0 = mai
rate_lock_secondsinteronoestensione, solo in modalità fiat: blocca i tassi di conversione alla creazione per questa finestra (vedi sotto)

Il risultato — e il payload del webhook invoice_paid — è l’oggetto fattura. I suoi campi principali:

  • Identità e stato: invoice_id, hash (l’id pubblico dentro pay_url), status (active / paid / expired), pay_url — il link t.me che mandi a chi paga (bot_invoice_url, mini_app_invoice_url, web_app_invoice_url ne sono alias).
  • Importi: amount (il valore nominale: unità di valuta su una fattura fiat, cripto altrimenti; null finché una fattura a importo libero non è pagata), amount_minor, e sulle fatture fiat pagate paid_asset / paid_amount / paid_fiat_rate, cioè la cripto effettivamente addebitata e il tasso usato.
  • Commissione: fee_asset / fee_amount, registrati al pagamento: per la tua contabilità fa fede quella (fee e usd_rate sono alias deprecati di Crypto Bot). Vedi commissioni e limiti.
  • Chi ha pagato: paid_by_user_id (null quando ha scelto l’anonimato), paid_anonymously, comment.
  • Rimborsi (estensione): refunded_amount / refunded_minor (cumulativi) e refunded_at, registrato quando il rimborso è completo.
  • Blocco del tasso (estensione): rate_lock_until e rate_lock_rates, cioè i tassi fissati per ogni asset; null se non era stato chiesto nessun blocco.
  • Come l’hai creata: description, hidden_message, payload, paid_btn_name / paid_btn_url, expiration_date (expires_at ne è alias) e i campi dello scambio (swap_to, is_swapped, swapped_to, swapped_rate, swapped_output, …).

Errori: 400 invalid_currency (asset e fiat confusi), 400 invalid_amount, 404 unknown_asset, 400 unsupported_fiat, 400 paid_btn_url_required, e per le richieste di blocco del tasso 400 rate_lock_fiat_only, 409 ratelock_disabled, 409 rate_unavailable (nessun tasso fresco per un asset accettato: ritenta).

Come vengono pagate le fatture

Chi paga lo fa dal saldo del suo portafoglio nella Mini App: all’istante e senza commissione di rete. Può anche coprire la fattura da un portafoglio esterno: l’app gli mostra un indirizzo di deposito, il suo trasferimento arriva sul suo portafoglio e la fattura si salda da sola appena è arrivato. In tutti e due i casi tu vedi la stessa cosa: una normale fattura paid e un webhook invoice_paid. Non ci sono parametri o campi in più da gestire.

Su una fattura fiat l’importo in cripto si calcola al momento del pagamento, arrotondato a tuo favore, così non ricevi mai meno del valore nominale in valuta. Se non c’è un tasso fresco, il pagamento non va a buon fine dal lato di chi paga invece di chiudersi a un tasso vecchio.

Bloccare il tasso su una fattura fiat

Passa rate_lock_seconds per fissare alla creazione il tasso attuale di ogni asset accettato. Finché il blocco è attivo, chi paga vede esattamente gli importi fissati e il pagamento converte al tasso fissato: per quella finestra il rischio di cambio te lo prendi tu. Il server riporta sempre la finestra tra i 60 secondi e il massimo della piattaforma (adesso 15 minuti).

Quando il blocco scade, la fattura resta pagabile e torna in silenzio alla conversione al momento del pagamento. Se vuoi che la fattura scada insieme alla quotazione, metti expires_in allo stesso valore.

getInvoices

GET /pay/api/getInvoices — ambito read. Filtri: asset, fiat, invoice_ids (separati da virgola), status (active / paid / expiredexpired è un’estensione; active esclude le fatture già oltre la scadenza), più offset / count. Restituisce {"items": [fattura, …]}, dalla più recente.

deleteInvoice

POST /pay/api/deleteInvoice — ambito invoices. Un parametro solo: invoice_id. Annulla una fattura non pagata e restituisce true. Errori: 404 invoice_not_found, 409 invoice_already_paid — una fattura pagata non si elimina, i soldi si sono già mossi.

refundInvoice

POST /pay/api/refundInvoice — ambito refunds, limite 30 al minuto. È un’estensione rispetto a Crypto Bot: restituisce l’importo nominale di una fattura pagata — o una sua parte — dal saldo della tua app a chi l’aveva pagata, anche a chi ha pagato in forma anonima e senza rivelare chi fosse.

ParametroTipoObbligatorioDescrizione
invoice_idinterola fattura pagata
amountstringanol’importo da rimborsare, nell’asset della fattura. Se lo ometti, tutto il residuo non ancora rimborsato. I rimborsi parziali si sommano fino all’importo nominale
spend_idstringanochiave di idempotenza: usane una, così un tentativo andato in timeout ripete la risposta invece di rimborsare due volte

Il risultato è l’oggetto fattura aggiornato, con i cumulativi refunded_amount / refunded_minor; refunded_at viene registrato quando la fattura è rimborsata del tutto. Lo stato resta paid. La commissione della piattaforma non torna indietro. Ogni rimborso fa partire il webhook facoltativo refund_completed.

Errori: 404 invoice_not_found, 409 invoice_not_paid, 409 already_refunded (non è rimasto niente da rimborsare), 409 amount_too_big (più del residuo non rimborsato), 409 insufficient_funds, 400 invalid_amount, e la coppia dello spend_id: 409 idempotency_conflict / 409 idempotency_in_progress.