# API Pagamenti

> Crea e gestisci sessioni di pagamento in criptovaluta con l'API Pagamenti di 2328.io.

L'API Pagamenti consente di creare sessioni di pagamento, reindirizzare i clienti a un checkout ospitato e tracciare lo stato dei pagamenti.

## Creare un pagamento

Crea una sessione di pagamento e restituisce un URL a cui il cliente può effettuare il pagamento.

### Parametri della richiesta

| Campo | Tipo | Obbligatorio | Descrizione | Valori |
|-------|------|----------|-------------|--------|
| `amount` | decimal | sì | Importo del pagamento nella valuta, es. `100.00` |  |
| `currency` | string | sì | Valuta fiat (USD, EUR, RUB, …) o criptovaluta (USDT, TRX, BTC, …) | `USD`, `EUR`, `RUB`, `KZT`, `UAH`, `UZS`, `USDT`, `USDC`, `BTC`, `ETH`, `GRAM`, `SOL`, `TRX`, `BNB`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `order_id` | string | sì | Il tuo ID ordine, es. `ORDER-12345` (fino a 128 caratteri) |  |
| `to_currency` | string | no | Criptovaluta preselezionata | `USDT`, `USDC`, `BTC`, `ETH`, `GRAM`, `SOL`, `TRX`, `BNB`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `network` | string | no\* | Codice di rete (obbligatorio se `to_currency` è impostato o se `currency` è una criptovaluta) | `TRX-TRC20`, `ETH-ERC20`, `BASE`, `BSC-BEP20`, `AVAX-C`, `POL-MATIC`, `TON`, `SOL`, `BTC`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `url_return` | string | no | URL di reindirizzamento dopo il pagamento, es. `https://your-site.com/return` |  |
| `url_success` | string | no | Alternativa a `url_return` |  |
| `url_callback` | string | sì | URL per le notifiche webhook, es. `https://your-site.com/webhook` |  |
| `invite_code` | string | no | Codice del referrer |  |
| `fee_split` | decimal | no | Quota della commissione del merchant trasferita al pagatore, 0–100 (%). 0 = il merchant paga interamente, 100 = il pagatore paga interamente. Sovrascrive l'impostazione a livello di progetto. **Esempio: `30`** (il pagatore copre il 30% della commissione). |  |
| `price_markup` | decimal | no | Maggiorazione o sconto sull'importo della fattura, da −99 a 100 (%). Sovrascrive l'impostazione a livello di progetto. **Esempio: `5`** (+5%) o `-10` (sconto del 10%). |  |
| `description` | string | no | Descrizione opzionale della fattura (max 200 caratteri). Mostrata al pagatore nella pagina di pagamento. **Esempio: `Premium plan — Order #12345`**. |  |
| `ttl_seconds` | int | no | Durata della fattura in secondi, da `300` (5 minuti) a `86400` (24 ore). Trascorso questo periodo la fattura scade e non può più essere pagata. Predefinito: `3600` (1 ora). **Esempio: `3600`**. |  |

### Risposta

```json
{
  "state": 0,
  "result": {
    "uuid": "abc123-def456-...",
    "order_id": "ORDER-12345",
    "amount": "100.00",
    "currency": "USD",
    "amount_usd": "100.00",
    "exchange_rate": null,
    "url": "https://2328.io/pay/abc123-def456-...",
    "tg_deeplink": "https://t.me/my2328bot?start=pay_abc123-def456-...",
    "expires_at": "2026-01-11T21:00:00Z",
    "created_at": "2026-01-11T20:00:00Z",
    "payer_currency": "USDT",
    "payer_amount": "100.50",
    "network": "TRX-TRC20",
    "address": "TXYZabc123...",
    "payment_status": "check",
    "txid": null,
    "payment_amount": null,
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

- Reindirizza il cliente a `result.url` per completare il pagamento.
- `tg_deeplink` — deeplink al bot Telegram per il pagamento tramite Telegram MiniApp.
- `qr` — codice QR codificato in Base64 (data URI) dell'indirizzo di deposito. Presente quando un indirizzo è già assegnato (quando `network` è impostato insieme a `to_currency`, o quando `currency` è una criptovaluta); altrimenti `null`.
- `txid`, `payment_amount` — `null` finché il cliente non paga. Vengono valorizzati una volta che la transazione è rilevata on-chain. Resta in ascolto del webhook `payment_status: paid` per sapere quando.
- `exchange_rate` — `null` se la conversione non è ancora applicabile (es. il tasso fiat → crypto non è stato bloccato). Viene valorizzato una volta scelta una valuta del pagatore.

> Use your project UUID and the endpoint-appropriate API key from the merchant dashboard.

#### Interactive request: `POST /v1/payment`
  - `amount` (decimal, required)
  - `currency` (enum, required): USD,EUR,RUB,KZT,UAH,UZS,USDT,USDC,BTC,ETH,GRAM,SOL,TRX,BNB,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `order_id` (string, required)
  - `to_currency` (enum): USDT,USDC,BTC,ETH,GRAM,SOL,TRX,BNB,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `network` (enum): TRX-TRC20,ETH-ERC20,BASE,BSC-BEP20,AVAX-C,POL-MATIC,TON,SOL,BTC,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `url_return` (string)
  - `url_success` (string)
  - `url_callback` (string, required)
  - `invite_code` (string)
  - `fee_split` (decimal)
  - `price_markup` (decimal)
  - `description` (string)
  - `ttl_seconds` (integer)

## Checkout ospitato, H2H e importi esatti di criptovaluta

Lo stesso endpoint supporta tre forme distinte di fattura. Scegline una deliberatamente; non mescolare la loro semantica di importo.

### Checkout ospitato con scelta del pagatore

Invia `amount`, `currency`, `order_id` e `url_callback`, ma ometti `to_currency` e `network`. La risposta contiene `result.url`; `address`, `qr` e talvolta i campi del pagatore rimangono `null` fino a quando il pagatore non seleziona una direzione sulla pagina ospitata.

```json
{
  "amount": "125.00",
  "currency": "EUR",
  "order_id": "ORDER-2026-1042",
  "url_callback": "https://merchant.example/webhooks/2328",
  "url_return": "https://merchant.example/orders/ORDER-2026-1042"
}
```

### Fattura H2H a indirizzo diretto

Invia sia `to_currency` che `network`. 2328.io crea la fattura blockchain durante la chiamata API, quindi una risposta riuscita può essere resa all'interno del tuo checkout senza reindirizzare il cliente.

```json
{
  "amount": "100.00",
  "currency": "USD",
  "to_currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "ORDER-2026-1043",
  "url_callback": "https://merchant.example/webhooks/2328"
}
```

Rendi questi valori esattamente come restituiti:

- `payer_amount` e `payer_currency` — l'istruzione di pagamento;
- `network` e `address` — l'unica destinazione per questa fattura;
- `qr` — un URI di dati per lo stesso indirizzo;
- `expires_at` — la scadenza della fattura;
- `url` — un utile fallback ospitato quando il checkout personalizzato non può completarsi.

> **DANGER:** Non generare o sostituire mai un indirizzo, riutilizzare un indirizzo da un'altra fattura, o calcolare `payer_amount` da un prezzo di mercato pubblico. La risposta dell'API è autorevole.

### Fattura per un importo preciso di criptovaluta

Metti la criptovaluta in `currency` quando la fattura stessa è denominata in criptovaluta:

```json
{
  "amount": "25.000000",
  "currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "ORDER-2026-1044",
  "url_callback": "https://merchant.example/webhooks/2328"
}
```

Il valore richiesto di criptovaluta è conservato in `payer_currency` / `payer_amount`. Il servizio può anche mantenere internamente una valutazione in USD per contabilizzazione e campi di tasso; non sostituire l'istruzione esatta sulla criptovaluta con quella valutazione. Conserva le stringhe decimali restituite, inclusa la precisione finale.

Per una criptovaluta con una sola rete supportata, la rete può essere selezionata automaticamente. Fornire `network` esplicitamente è comunque consigliato per un'integrazione deterministica. Per asset multi-rete come le stablecoin, invialo sempre.

## Idempotenza e tentativi

`order_id` è limitato al progetto commerciante autenticato e funge da chiave di idempotenza per la creazione. Se un pagamento esiste già, l'API restituisce quella sessione con `state: 0`.

> **WARNING:** Un nuovo tentativo con lo stesso `order_id` non significa **not** "aggiorna questa fattura." Campi come importo modificato, valuta, callback, markup, TTL o direzione potrebbero essere ignorati perché viene restituita la sessione esistente. Conserva la prima richiesta e respingi tentativi conflittuali nella tua applicazione.

Algoritmo di creazione raccomandato:

1. Inserisci il tuo tentativo di pagamento locale e l'unico `order_id` in una singola transazione di database.
2. Invia la richiesta API firmata.
3. Conserva il `uuid` restituito e la risposta completa.
4. Se il risultato HTTP viene perso, ripeti la stessa richiesta o interroga `/v1/payment/info` tramite `order_id`.
5. Non creare mai un secondo ordine locale semplicemente perché la richiesta a monte è scaduta.

## Casi limite di pagamento

| Situazione | Gestione corretta |
|-----------|------------------|
| `address` / `qr` è `null` | La direzione del pagatore non è stata inizializzata. Reindirizzare a `url`, oppure creare una nuova fattura H2H correttamente specificata con un nuovo `order_id`. |
| Errore di convalida HTTP `400` | Leggere il campo a livello di `errors`; non riprovare con input invariato. |
| HTTP `429` | Riprovare con backoff esponenziale jitterato e mantenere lo stesso `order_id`. |
| HTTP `503` / `direction_disabled` | Aggiornare `/v1/directions`; nascondere temporaneamente la direzione o riprovare più tardi. |
| Timeout della richiesta del client | Trattare il risultato come sconosciuto. Interrogare tramite `order_id` prima di creare qualsiasi altra cosa. |
| `underpaid_check` | Memorizza l'evento parziale e attendi un ricarico o uno stato successivo. Non accreditare due volte quando arrivano altri txid. |
| `underpaid` | Stato finale di sotto-pagamento. Applica la tua politica di esecuzione/revisione manuale configurata all'importo effettivamente accreditato. |
| `overpaid` | Pagamento riuscito con fondi in eccesso. Esegui in modo idempotente e conserva gli importi effettivi per la riconciliazione/politica di rimborso. |
| `aml_lock` | Non eseguire o rilasciare fondi automaticamente; indirizza al flusso di lavoro compliance/supporto. |
| `cancel` | La fattura è scaduta o è stata annullata. Non presumere che un trasferimento tardivo on-chain sia impossibile; riconcilia qualsiasi evento successivo con il supporto. |

L'URL di ritorno del browser è solo per la navigazione. Un cliente può aprirlo senza pagare, chiuderlo dopo aver pagato o riaprirlo più tardi. Solo uno stato API/webhook verificato può completare l'ordine del commerciante.

## Informazioni sul pagamento

Ottieni lo stato corrente del pagamento tramite `uuid` o `order_id`.

### Parametri della richiesta

| Campo | Tipo | Obbligatorio | Descrizione | Valori |
|-------|------|----------|-------------|--------|
| `uuid` | string | sì\* | UUID del pagamento (da `result.uuid` alla creazione) |  |
| `order_id` | string | sì\* | Il tuo ID ordine |  |

> **INFO:** È richiesto almeno uno tra `uuid` e `order_id`.

#### Interactive request: `POST /v1/payment/info`
  - `uuid` (string)
  - `order_id` (string)

## Elenco dei pagamenti

Ottieni un elenco di tutti i pagamenti con filtri e paginazione.

### Parametri della richiesta

| Campo | Tipo | Obbligatorio | Descrizione | Valori |
|-------|------|----------|-------------|--------|
| `status` | string | no | Filtra per stato del pagamento (vedi [References](/docs/references)) | `pending`, `check`, `paid`, `underpaid_check`, `underpaid`, `overpaid`, `cancel` |
| `date_from` | date | no | Data di inizio (YYYY-MM-DD), es. `2026-01-01` |  |
| `date_to` | date | no | Data di fine (YYYY-MM-DD), es. `2026-01-31` |  |
| `page` | int | no | Numero di pagina, default `1` |  |
| `per_page` | int | no | Elementi per pagina, default `15`, max `5000` |  |

#### Interactive request: `POST /v1/payment/list`
  - `status` (enum): pending,check,paid,underpaid_check,underpaid,overpaid,cancel
  - `date_from` (string)
  - `date_to` (string)
  - `page` (integer)
  - `per_page` (integer)