Salta ai contenuti

Riferimento API Pagamenti

Payments API Reference

Complete reference for the Payment Gateway REST API.

Base URL

https://api.sanpay.io/api/v1

Authentication

All API requests require authentication via Bearer token:

Authorization: Bearer YOUR_API_KEY

Payments

Create Payment

POST /payments

Create a new payment request.

Request Body
Field Type Required Description
fiatAmountnumberImporto in valuta fiat (es. 99.99)
fiatCurrencystringCodice valuta fiat: USD, EUR, ecc.
coinIdstring (UUID)ID specifico della moneta. Se omesso con allowUserSelection: true, il cliente sceglie.
chainIdstringIdentificatore blockchain (es. BTC, ETH)
metadataobjectCoppie chiave-valore personalizzate (ritornate nei webhook)
externalIdstringIl tuo ID ordine/riferimento interno
callbackUrlstringURL per webhook e redirect dopo il pagamento
ttlSecondsintegerTempo di vita in secondi (default: 1800)
allowUserSelectionbooleanPermetti al cliente di scegliere la crypto (default: false)
confirmationsintegerConferme blockchain richieste
isTestnetbooleanUsa modalità testnet (default: false)
idempotencyKeystringChiave unica per prevenire pagamenti duplicati
Example
curl -X POST https://api.sanpay.io/api/v1/payments \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fiatAmount": 99.99,
    "fiatCurrency": "USD",
    "chainId": "BTC",
    "externalId": "order_12345",
    "callbackUrl": "https://example.com/webhook"
  }'
Response 201 Created
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "PENDING_ASSIGNMENT",
  "requestedFiatAmount": 99.99,
  "fiatCurrency": "USD",
  "requestedCryptoAmount": "0.00250000",
  "coinSymbol": "BTC",
  "address": null,
  "qrData": null,
  "paymentUrl": "https://pay.sanpay.io/p/a1b2c3d4",
  "fxRateUsed": "39996.00",
  "fxLockedAt": "2024-01-15T11:00:00Z",
  "fxLockedUntil": "2024-01-15T11:30:00Z",
  "expiresAt": "2024-01-15T11:30:00Z",
  "createdAt": "2024-01-15T11:00:00Z"
}

Get Payment

GET /payments/{paymentId}

Retrieve a payment by ID.

Response 200 OK
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "CONFIRMED",
  "requestedFiatAmount": 99.99,
  "fiatCurrency": "USD",
  "requestedCryptoAmount": "0.00250000",
  "coinSymbol": "BTC",
  "address": "bc1qxy2kgdygjrsqvzq3rj...",
  "txHash": "abc123def456...",
  "confirmations": 6,
  "confirmedAt": "2024-01-15T11:15:00Z",
  "createdAt": "2024-01-15T11:00:00Z"
}

Payment Statuses

Status Description
PENDING_ASSIGNMENTPagamento creato, in attesa di assegnazione indirizzo
PENDING_SELECTIONIn attesa che il cliente selezioni la crypto (selezione differita)
AWAITING_PAYMENTIndirizzo assegnato, in attesa che il cliente invii i fondi
DETECTEDTransazione vista nella mempool (0 conferme)
PARTIALLY_PAIDPagamento parziale ricevuto, in attesa del restante
CONFIRMINGTransazione ricevuta, in attesa delle conferme richieste
CONFIRMEDPagamento confermato con le conferme blockchain richieste
CONFIRMED_PARTIALImporto parziale confermato
SETTLEDPagamento completamente processato — stato finale di successo
PARTIALLY_SETTLEDImporto parziale regolato
EXPIREDFinestra di pagamento scaduta senza pagamento
EXPIRED_PARTIALFinestra di pagamento scaduta con pagamento parziale ricevuto
CANCELLEDPagamento annullato dal commerciante
REFUND_PENDING_ADDRESSRimborso avviato, in attesa dell'indirizzo di rimborso del cliente
REFUND_PROCESSINGTransazione di rimborso in elaborazione
REFUNDEDRimborso completato con successo
REFUND_FAILEDTransazione di rimborso fallita
REFUND_EXPIREDRaccolta indirizzo di rimborso scaduta
REORG_DETECTEDRiorganizzazione blockchain rilevata — pagamento in revisione

List Payments

GET /payments

List all payments for your account.

Query Parameters
Field Type Description
statusstringFilter by status
externalIdstringFilter by order ID
sincestringISO 8601 timestamp
untilstringISO 8601 timestamp
limitintegerMax results (default: 20, max: 100)
offsetintegerPagination offset
Response 200 OK
{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "status": "SETTLED",
      "requestedFiatAmount": 99.99,
      "fiatCurrency": "USD",
      "requestedCryptoAmount": "0.00250000",
      "coinSymbol": "BTC",
      "createdAt": "2024-01-15T11:00:00Z"
    }
  ],
  "pagination": {
    "total": 156,
    "limit": 20,
    "offset": 0
  }
}

Checkout Sessions

Create Checkout Session

POST /checkout/sessions

Create a hosted checkout session.

Request Body
Field Type Required Description
fiatAmountnumberImporto in valuta fiat
fiatCurrencystringCodice valuta fiat: USD, EUR, ecc.
descriptionstringDescrizione ordine
externalIdstringIl tuo ID ordine interno per correlazione
successUrlstringURL di reindirizzamento in caso di successo
cancelUrlstringURL di reindirizzamento in caso di annullamento
customerEmailstringPre-compilazione email cliente
ttlSecondsintegerTempo di vita in secondi (default: 1800)
Response 201 Created
{
  "id": "cs_xyz789",
  "url": "https://checkout.sanpay.io/cs_xyz789",
  "expiresAt": "2024-01-15T12:00:00Z"
}

Refunds

Create Refund

POST /payments/{paymentId}/refunds

Record a refund for a payment.

Request Body
Field Type Required Description
amountstringRefund amount in crypto
txHashstringRefund transaction hash
reasonstringReason for refund
Response 201 Created
{
  "id": "ref_abc123",
  "paymentId": "pay_abc123",
  "amount": "0.00250000",
  "currency": "BTC",
  "txHash": "abc123...",
  "status": "completed",
  "createdAt": "2024-01-16T10:00:00Z"
}

Webhooks

Payment events are delivered to your webhook URL:

Event Description
PAYMENT_CREATEDRichiesta di pagamento creata
PAYMENT_ADDRESS_ASSIGNEDIndirizzo crypto assegnato al pagamento
PAYMENT_DETECTEDTransazione vista nella mempool
PAYMENT_CONFIRMATION_UPDATEConteggio conferme aggiornato
PAYMENT_CONFIRMEDPagamento ha raggiunto le conferme richieste
PAYMENT_SETTLEDPagamento completamente regolato — evento finale di successo
PAYMENT_EXPIREDFinestra di pagamento scaduta
PAYMENT_EXPIRED_PARTIALPagamento scaduto con importo parziale ricevuto
PAYMENT_CANCELLEDPagamento annullato dal commerciante
PAYMENT_REFUND_INITIATEDProcesso di rimborso avviato
PAYMENT_REFUND_COMPLETEDRimborso completato con successo
PAYMENT_REFUND_FAILEDTransazione di rimborso fallita
PAYMENT_TX_UNMATCHEDTransazione ricevuta ma non corrispondente
PAYMENT_REORGRiorganizzazione blockchain rilevata
PAYMENT_LATE_DETECTEDPagamento rilevato dopo la scadenza

Webhook Payload

{
  "eventId": "evt-a1b2c3d4-e5f6",
  "eventType": "PAYMENT_CONFIRMED",
  "timestamp": "2024-01-15T11:15:00Z",
  "tenantId": "your-tenant-id",
  "paymentRequestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "address": "bc1qxy2kgdygjrsqvzq3rj...",
  "coinSymbol": "BTC",
  "chainId": "BTC",
  "status": "CONFIRMED",
  "confirmations": 6,
  "requiredConfirmations": 3,
  "requestedFiatAmount": 99.99,
  "fiatCurrency": "USD",
  "requestedCryptoAmount": "0.00250000"
}

Error Responses

{
  "error": {
    "code": "PAYMENT_EXPIRED",
    "message": "The payment request has expired",
    "details": {
      "paymentId": "pay_abc123",
      "expiredAt": "2024-01-15T11:30:00Z"
    }
  }
}

Payment Error Codes

Code Status Description
PAYMENT_NOT_FOUND404Payment does not exist
PAYMENT_EXPIRED400Payment has expired
INVALID_AMOUNT400Invalid amount format
UNSUPPORTED_CURRENCY400Currency not supported
RATE_LIMITED429Too many requests

Annulla Pagamento

POST /payments/{paymentId}/cancel

Annulla una richiesta di pagamento. Solo i pagamenti con stato `AWAITING_PAYMENT` o `PENDING_SELECTION` possono essere annullati. I pagamenti con transazioni rilevate non possono essere annullati.

Response 200 OK
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "CANCELLED",
  "cancelledAt": "2026-01-15T11:20:00Z",
  "reason": "Richiesta di annullamento dal cliente"
}

Ottieni Sessione Checkout

GET /checkout/sessions/{sessionId}

Recupera una sessione checkout tramite ID.

Response 200 OK
{
  "id": "cs_xyz789",
  "status": "completed",
  "paymentId": "pay_abc123",
  "amount": "99.99",
  "currency": "USD",
  "successUrl": "https://example.com/success",
  "cancelUrl": "https://example.com/cancel",
  "expiresAt": "2024-01-15T12:00:00Z",
  "createdAt": "2024-01-15T11:00:00Z"
}

Scadenza Sessione Checkout

DELETE /checkout/sessions/{sessionId}

Fa scadere immediatamente una sessione checkout. La sessione non potrà più essere utilizzata per il pagamento.

Response 200 OK
{
  "id": "cs_xyz789",
  "status": "expired",
  "expiredAt": "2024-01-15T11:30:00Z"
}

Elenco Rimborsi

GET /payments/{paymentId}/refunds

Elenca tutti i rimborsi per uno specifico pagamento.

Response 200 OK
{
  "data": [
    {
      "id": "ref_abc123",
      "paymentId": "pay_abc123",
      "amount": "0.00125000",
      "currency": "BTC",
      "status": "completed",
      "reason": "Richiesta cliente",
      "createdAt": "2024-01-16T10:00:00Z"
    }
  ],
  "pagination": {
    "total": 1,
    "limit": 20,
    "offset": 0
  }
}

Ottieni Rimborso

GET /refunds/{refundId}

Recupera un rimborso tramite ID.

Response 200 OK
{
  "id": "ref_abc123",
  "paymentId": "pay_abc123",
  "amount": "0.00125000",
  "currency": "BTC",
  "txHash": "abc123def456...",
  "status": "completed",
  "reason": "Richiesta cliente",
  "createdAt": "2024-01-16T10:00:00Z"
}

I link di pagamento sono URL riutilizzabili che permettono ai clienti di pagare qualsiasi importo. Ideali per donazioni, mance o fatture.

POST /payment-links

Crea un link di pagamento riutilizzabile.

Request Body
Campo Tipo Obbligatorio Descrizione
namestringNome visualizzato per il link di pagamento
amountstringImporto fisso (se omesso, il cliente inserisce l'importo)
currencystringCodice valuta fiat: USD, EUR, ecc.
descriptionstringDescrizione mostrata al cliente
redirectUrlstringURL di reindirizzamento dopo il pagamento
metadataobjectCoppie chiave-valore personalizzate
Response 201 Created
{
  "id": "plink_abc123",
  "name": "Abbonamento Premium",
  "url": "https://pay.sanpay.io/l/plink_abc123",
  "amount": "99.99",
  "currency": "USD",
  "active": true,
  "createdAt": "2024-01-15T11:00:00Z"
}

GET /payment-links

Elenca tutti i link di pagamento del tuo account.

Query Parameters
Campo Tipo Descrizione
activebooleanFiltra per stato attivo
limitintegerMax risultati (default: 20, max: 100)
offsetintegerOffset paginazione
Response 200 OK
{
  "data": [
    {
      "id": "plink_abc123",
      "name": "Abbonamento Premium",
      "url": "https://pay.sanpay.io/l/plink_abc123",
      "amount": "99.99",
      "currency": "USD",
      "active": true,
      "paymentsCount": 42,
      "totalCollected": "4199.58",
      "createdAt": "2024-01-15T11:00:00Z"
    }
  ],
  "pagination": {
    "total": 5,
    "limit": 20,
    "offset": 0
  }
}

GET /payment-links/{linkId}

Recupera un link di pagamento tramite ID.


DELETE /payment-links/{linkId}

Disattiva un link di pagamento. L'URL del link non accetterà più pagamenti.

Response 200 OK
{
  "id": "plink_abc123",
  "active": false,
  "deactivatedAt": "2024-01-20T15:00:00Z"
}

Tassi di Cambio

Ottieni tassi di cambio delle criptovalute in tempo reale.

Ottieni Tassi di Cambio

GET /exchange-rates

Recupera i tassi di cambio attuali per le criptovalute supportate.

Query Parameters
Campo Tipo Descrizione
basestringValuta fiat base (default: USD)
symbolsstringSimboli crypto separati da virgola (es. BTC,ETH)
Response 200 OK
{
  "base": "USD",
  "timestamp": "2024-01-15T11:00:00Z",
  "rates": {
    "BTC": "0.000025",
    "ETH": "0.00045",
    "USDT": "1.0001",
    "USDC": "0.9999"
  }
}

Account

Ottieni Saldo Account

GET /account/balance

Recupera i saldi attuali del tuo account per tutte le criptovalute.

Response 200 OK
{
  "balances": [
    {
      "currency": "BTC",
      "available": "1.25000000",
      "pending": "0.05000000",
      "total": "1.30000000"
    },
    {
      "currency": "ETH",
      "available": "15.50000000",
      "pending": "0.00000000",
      "total": "15.50000000"
    }
  ],
  "updatedAt": "2024-01-15T11:00:00Z"
}

Rate Limiting

Le richieste API sono rate-limited per garantire un utilizzo equo. Le informazioni sui rate limit sono incluse negli header di risposta.

Header Rate Limit

Header Descrizione
X-RateLimit-LimitRichieste massime consentite per finestra
X-RateLimit-RemainingRichieste rimanenti nella finestra corrente
X-RateLimit-ResetTimestamp Unix di reset della finestra

Rate Limit Predefiniti

Endpoint Limite Finestra
POST /payments1001 minuto
GET /payments3001 minuto
POST /checkout/sessions1001 minuto
GET /exchange-rates601 minuto

Idempotenza

Usa chiavi di idempotenza per ripetere richieste in sicurezza senza rischiare operazioni duplicate.

Uso delle Chiavi di Idempotenza

Includi un campo `idempotencyKey` nel corpo della richiesta con un valore univoco (es. UUID) per le richieste POST:

curl -X POST https://api.sanpay.io/api/v1/payments \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fiatAmount": 99.99, "fiatCurrency": "USD", "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000"}'

Comportamento Idempotenza

  • Le chiavi sono valide per 24 ore dalla prima richiesta
  • Richieste successive con la stessa chiave restituiscono la risposta originale
  • Le chiavi sono associate alla tua API key
  • Raccomandiamo l'uso di UUID v4 per le chiavi di idempotenza

Esempi SDK

Ecco esempi di creazione pagamento nei linguaggi di programmazione più popolari:

Node.js

const response = await fetch('https://api.sanpay.io/api/v1/payments', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.SANPAY_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    fiatAmount: 99.99,
    fiatCurrency: 'USD',
    externalId: 'ORDER-12345',
    description: 'Piano Premium'
  })
});
const payment = await response.json();

Python

import requests

response = requests.post(
    'https://api.sanpay.io/api/v1/payments',
    headers={
        'Authorization': f'Bearer {os.environ["SANPAY_API_KEY"]}',
        'Content-Type': 'application/json'
    },
    json={
        'fiatAmount': 99.99,
        'fiatCurrency': 'USD',
        'externalId': 'ORDER-12345',
        'description': 'Piano Premium'
    }
)
payment = response.json()

PHP

$ch = curl_init('https://api.sanpay.io/api/v1/payments');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . getenv('SANPAY_API_KEY'),
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'fiatAmount' => 99.99,
        'fiatCurrency' => 'USD',
        'externalId' => 'ORDER-12345',
        'description' => 'Piano Premium'
    ])
]);
$payment = json_decode(curl_exec($ch), true);