Sign in
Pagamenti e prelievi/Payout API

API Prelievi

Invia prelievi dal saldo merchant a qualsiasi indirizzo blockchain.

L'API Prelievi consente di prelevare in modo programmatico fondi dal saldo merchant verso qualsiasi indirizzo blockchain.

Per tutti gli endpoint Prelievi, devi utilizzare una Payout API key separata per generare la firma sign. Questa chiave è diversa dalla tua API key normale e deve essere generata nelle impostazioni del progetto.

Creare un prelievo

Crea una richiesta di prelievo dal saldo merchant.

POST/v1/payout

Parametri della richiesta

CampoTipoObbligatorioDescrizione
currencystringValuta del prelievo (vedi References)
networkstringCodice di rete (vedi References)
amountstringImporto del prelievo
to_addressstringIndirizzo blockchain del destinatario
order_idstringnoChiave di idempotenza — univoca all'interno di un progetto. Un POST ripetuto con lo stesso order_id non crea un nuovo prelievo — viene restituito quello esistente
url_callbackstringnoURL per i webhook di prelievo. Ometti per disabilitare i webhook per questo prelievo
memostring | nullnoDestination tag / memo. Attualmente utilizzato solo dalle reti TON e SOL; max 255 caratteri
from_currencystringnoSaldo di origine da addebitare e convertire automaticamente in currency al momento del prelievo. Ti permette di prelevare in asset volatili (BTC, ETH, …) mantenendo il saldo in una stablecoin come USDT — non devi detenere tu stesso la cripto volatile. Passa "USDT" per addebitare il saldo USDT
fee_optionstringnoModalità di addebito delle commissioni. deduct (default) — commissioni di rete + piattaforma sottratte da amount, il destinatario riceve amount - fees. add — commissioni aggiunte sopra, il merchant viene addebitato di amount + fees, il destinatario riceve esattamente amount

Idempotenza. All'interno di un progetto, un prelievo è univoco per order_id. Reinviare lo stesso POST con lo stesso order_id è sicuro — l'API restituisce il prelievo esistente invece di crearne un duplicato. Passa sempre un order_id per i prelievi in produzione.

Esempi di richiesta

Shell
curl -X POST https://api.2328.io/api/v1/payout \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE" \
  -d '{"currency":"TRX","network":"TRX-TRC20","amount":"1.00","to_address":"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t","order_id":"9ed25264-8be4-439f-acf5-2a8732538d27","url_callback":"https://your-site.com/webhook/payout","memo":null,"fee_option":"deduct"}'

Esempio di risposta

JSON
{
  "state": 0,
  "result": {
    "uuid": "019dea62-1727-72aa-ac2c-eaf2ade193ef",
    "order_id": "9ed25264-8be4-439f-acf5-2a8732538d27",
    "status": "pending",
    "currency": "TRX",
    "network": "TRX-TRC20",
    "amount": "1.00",
    "merchant_amount": "1",
    "network_amount": "0.89",
    "amount_usd": "0.33",
    "to_address": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
    "memo": null,
    "txid": null,
    "block_number": null,
    "error_type": null,
    "created_at": "2026-05-02T23:29:50+03:00",
    "updated_at": "2026-05-02T23:29:50+03:00"
  }
}

Commissioni. Default fee_option: deduct — le commissioni di rete + piattaforma vengono sottratte da amount (il destinatario riceve amount - fees). Passa fee_option: add per addebitare le commissioni sopra — il destinatario riceve esattamente amount e il merchant viene addebitato di amount + fees.

Calcolare un prelievo

Stima importi e commissioni del prelievo senza creare un prelievo né addebitare il saldo. Usalo per mostrare all'utente l'importo esatto che riceverà (o pagherà) prima della conferma.

POST/v1/payout/calc

Parametri della richiesta

Identici a Creare un prelievo — stessi campi, stessa firma. order_id, url_callback, to_address e memo sono accettati ma ignorati: nessun prelievo viene salvato e nessun callback viene inviato.

Esempio di richiesta

Shell
curl -X POST https://api.2328.io/api/v1/payout/calc \
  -H "Content-Type: application/json" \
  -H "User-Agent: MyShop/1.0 (+https://myshop.example)" \
  -H "project: YOUR_PROJECT_UUID" \
  -H "sign: YOUR_HMAC_SIGNATURE" \
  -d '{"currency":"USDT","network":"TRX-TRC20","amount":"100","fee_option":"add"}'

Esempio di risposta

JSON
{
  "state": 0,
  "result": {
    "currency": "USDT",
    "network": "TRX-TRC20",
    "amount": "100",
    "fee_option": "add",
    "merchant_amount": "103.00000000",
    "network_amount": "100",
    "total_fee": "3.00000000",
    "total_fee_usd": "3.00000000"
  }
}

Solo anteprima. Questo endpoint è in sola lettura — nessun saldo viene addebitato e nessun record di prelievo viene creato. Chiamalo tutte le volte che ti servono per mostrare il dettaglio delle commissioni nella tua UI.

Stato del prelievo

Ottieni lo stato di una richiesta di prelievo.

GET/v1/payout/status/{uuid}

Parametri di percorso

CampoTipoObbligatorioDescrizione
uuidstringUUID del prelievo (da result.uuid alla creazione)

Esempio di risposta

JSON
{
  "state": 0,
  "result": {
    "uuid": "019dff1f-0dbd-7277-8d45-271e7775388f",
    "order_id": "4dfdcc84402b1185b71cbe399321533e",
    "status": "completed",
    "currency": "TRX",
    "network": "TRX-TRC20",
    "amount": "3.00",
    "merchant_amount": "3.00",
    "network_amount": "3.00",
    "amount_usd": "1.04",
    "to_address": "THauRv5tcucQRohXg8NiyGTk16DX1XQG5x",
    "memo": null,
    "txid": "9242e533703704ef3eaba840f70b4a26333e72c943377ee375fea17badb53def",
    "block_number": null,
    "error_type": null,
    "created_at": "2026-05-07T00:08:38+03:00",
    "updated_at": "2026-05-07T00:08:54+03:00",
    "from_currency": "USDT",
    "debited_amount": "1.050735",
    "debited_currency": "USDT"
  }
}

Per questa richiesta GET la firma viene calcolata da un body vuoto: hash_hmac('sha256', base64_encode(''), $apiKey)

Campi della risposta

Campi restituiti in result da POST /v1/payout e GET /v1/payout/status/{uuid}:

CampoTipoDescrizione
uuidstringUUID del prelievo assegnato dal sistema
order_idstringIl tuo identificatore interno del prelievo (univoco all'interno del progetto)
statusstringStato corrente del prelievo (vedi sotto)
currencystringValuta del prelievo
networkstringCodice di rete
amountstringImporto del prelievo come richiesto
merchant_amountstringImporto addebitato dal saldo merchant
network_amountstringImporto effettivamente inviato on-chain (dopo commissioni di rete + piattaforma)
amount_usdstringEquivalente in USD dell'importo del prelievo
to_addressstringIndirizzo blockchain del destinatario
memostring | nullDestination tag / memo (TON, SOL). null altrimenti
txidstring | nullHash della transazione blockchain. null finché la transazione non viene inviata
block_numberint | nullNumero del blocco in cui è inclusa la transazione. null finché non è inclusa
error_typestring | nullMotivo del fallimento quando status = failed (vedi Tipi di errore sotto). null altrimenti
created_atstring (ISO 8601)Ora di creazione del prelievo
updated_atstring (ISO 8601)Ora dell'ultimo cambio di stato
from_currencystring | nullSaldo di origine da cui è stato addebitato il prelievo quando è stata usata la conversione automatica (es. USDT per un prelievo in BTC). null se non c'è stata alcuna conversione
debited_amountstring | nullImporto effettivamente addebitato dal saldo di origine dopo la conversione. Presente solo quando viene utilizzata la conversione automatica
debited_currencystring | nullValuta di debited_amount — il saldo da cui sono stati addebitati i fondi

Stati del prelievo

Il campo status può assumere i seguenti valori:

StatoDescrizione
pendingCreato, in attesa di elaborazione
completedCompletato con successo — txid è impostato
failedErrore di invio — vedi error_type
cancelledAnnullato

Tipi di errore

Quando status = failed, il campo error_type ne descrive il motivo:

CodiceDescrizione
aml_riskPrelievo bloccato dai controlli di rischio AML (l'indirizzo del destinatario è stato segnalato come ad alto rischio)

Notifiche webhook

Quando lo stato di un prelievo cambia, il sistema invia un webhook POST all'URL url_callback passato al momento della creazione del prelievo. Se url_callback non è stato fornito, non viene inviato alcun webhook per quel prelievo.

  • Method: POST
  • Content-Type: application/json
  • Signature: campo sign nel body della richiesta, calcolato con la Payout API key (la stessa chiave utilizzata per firmare le richieste di prelievo).

Il payload rispecchia l'oggetto result di GET /v1/payout/status/{uuid} più un campo sign per la verifica.

Payload

JSON
{
  "uuid": "019dff1f-0dbd-7277-8d45-271e7775388f",
  "order_id": "4dfdcc84402b1185b71cbe399321533e",
  "status": "completed",
  "currency": "TRX",
  "network": "TRX-TRC20",
  "amount": "3.00",
  "merchant_amount": "3.00",
  "network_amount": "3.00",
  "amount_usd": "1.04",
  "to_address": "THauRv5tcucQRohXg8NiyGTk16DX1XQG5x",
  "memo": null,
  "txid": "9242e533703704ef3eaba840f70b4a26333e72c943377ee375fea17badb53def",
  "block_number": null,
  "error_type": null,
  "created_at": "2026-05-07T00:08:38+03:00",
  "updated_at": "2026-05-07T00:08:54+03:00",
  "from_currency": "USDT",
  "debited_amount": "1.050735",
  "debited_currency": "USDT",
  "sign": "925ad7bf3d6841864101f7cc2c7e30652e70a06cdb04dbe07a0129480000ce4a"
}

Verifica della firma. Utilizza lo stesso algoritmo dei webhook di pagamento, ma firma con la tua Payout API key invece dell'API key normale. Rimuovi il campo sign, codifica in JSON il payload rimanente, codificalo in Base64, quindi calcola hash_hmac('sha256', $base64, $payoutApiKey) e confronta con il sign ricevuto.