tgpay cryptoAPI
crypto-payapiinvoicesrefunds

Riferimento API: fatture e rimborsi

7 min di letturaAggiornata il 9 ott 2026

I metodi delle fatture: createInvoice, getInvoices, deleteInvoice, refundInvoice. Le convenzioni comuni (autenticazione, struttura delle risposte, 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 inserisce 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 = durata predefinita. Leggi expiration_date nella risposta
rate_lock_secondsinteronoestensione, solo in modalità fiat: blocca i tassi di conversione alla creazione per questa finestra (vedi sotto)

Descrizione, contenuti dopo il pagamento e pulsante possono restare nascosti durante la revisione o finché non vengono approvati. L’importo della fattura resta pagabile.

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, 400 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 aggiornato 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, purché il saldo sia sufficiente e il pagamento venga confermato. Può anche versare i fondi da un portafoglio esterno: se l’opzione è disponibile, l’app mostra un indirizzo di deposito e un termine per il pagamento. Il deposito viene accreditato sul portafoglio di chi paga. Il pagamento automatico richiede un deposito a quell’indirizzo, saldo disponibile sufficiente, nessuna restrizione sui pagamenti in uscita e richiesta di pagamento e fattura non scadute. Un deposito in ritardo resta nel portafoglio di chi paga: non dimostra che la fattura sia stata pagata. In entrambi i casi ricevi una normale fattura paid e, se è configurato un URL per i webhook, un evento 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, arrotondando per eccesso all’unità minima dell’asset scelto. La commissione del commerciante viene poi sottratta da quell’importo. Se non è disponibile un tasso bloccato ancora valido né un tasso aggiornato, il pagamento non riesce, anziché essere eseguito a un tasso non più valido.

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 adatta la durata richiesta all’intervallo consentito. Leggi rate_lock_until nella risposta per conoscere il termine effettivo.

Quando il blocco scade, una fattura non ancora scaduta resta pagabile al tasso del momento del pagamento. Per far coincidere i due termini, scegli un valore di expires_in nell’intervallo consentito per il blocco e confronta expiration_date con rate_lock_until nella risposta.

getInvoices

GET /pay/api/getInvoices — ambito read. Filtri: asset, fiat, invoice_ids (separati da virgola), status (active / paid / expired — expired è 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 tutte o parte delle cripto effettivamente pagate, dal saldo della tua app a chi ha pagato, anche in forma anonima e senza rivelarne l’identità. Per una fattura in valuta fiat, usa paid_asset e paid_amount: il rimborso non comporta una nuova conversione dalla valuta fiat.

ParametroTipoObbligatorioDescrizione
invoice_idinterosìla fattura pagata
amountstringanol’importo in cripto da rimborsare, nell’asset pagato in origine (paid_asset per le fatture fiat). Se lo ometti, tutto il residuo non ancora rimborsato. I rimborsi parziali si sommano fino all’importo in cripto pagato in origine
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 viene restituita. La tua app deve avere un saldo sufficiente nell’asset del pagamento originale, anche se swap_to ha convertito l’incasso in un altro asset. 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.