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
fiatAmountnumber✅Importo in valuta fiat (es. 99.99)
fiatCurrencystring✅Codice valuta fiat: USD, EUR, ecc.
coinIdstring (UUID)❌ID specifico della moneta. Se omesso con allowUserSelection: true, il cliente sceglie.
chainIdstring❌Identificatore blockchain (es. BTC, ETH)
metadataobject❌Coppie chiave-valore personalizzate (ritornate nei webhook)
externalIdstring❌Il tuo ID ordine/riferimento interno
callbackUrlstring❌URL per webhook e redirect dopo il pagamento
ttlSecondsinteger❌Tempo di vita in secondi (default: 1800)
allowUserSelectionboolean❌Permetti al cliente di scegliere la crypto (default: false)
confirmationsinteger❌Conferme blockchain richieste
isTestnetboolean❌Usa modalità testnet (default: false)
idempotencyKeystring❌Chiave 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
fiatAmountnumber✅Importo in valuta fiat
fiatCurrencystring✅Codice valuta fiat: USD, EUR, ecc.
descriptionstring❌Descrizione ordine
externalIdstring❌Il tuo ID ordine interno per correlazione
successUrlstring✅URL di reindirizzamento in caso di successo
cancelUrlstring✅URL di reindirizzamento in caso di annullamento
customerEmailstring❌Pre-compilazione email cliente
ttlSecondsinteger❌Tempo 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
amountstring✅Refund amount in crypto
txHashstring❌Refund transaction hash
reasonstring❌Reason 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
namestring✅Nome visualizzato per il link di pagamento
amountstring❌Importo fisso (se omesso, il cliente inserisce l'importo)
currencystring✅Codice valuta fiat: USD, EUR, ecc.
descriptionstring❌Descrizione mostrata al cliente
redirectUrlstring❌URL di reindirizzamento dopo il pagamento
metadataobject❌Coppie 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);