← Tutti i tutorial

TUTORIAL 4 / 9

Crea un checkout. Verifica il pagamento.

Crea fatture dal tuo backend ed elabora notifiche di pagamento verificate.

Cosa otterrai

Un flusso di pagamento lato server con protezione per nuovi tentativi e duplicati.

1. Prepara ID e accesso

Inizia con un negozio abilitato e metodi di pagamento testati. In Impostazioni → Accesso API, crea una credenziale di lettura/scrittura limitata al progetto necessario. Conserva il token sul backend, mai nel codice browser o in un repository pubblico.

Copia ID API del progetto e ID API del negozio dal riquadro del negozio Generale → ID API . Sono UUID, non l'identificatore leggibile del progetto o il tuo numero d'ordine. Usa il tuo hostname API.

In Negozio → IPN, crea un segreto di firma prima di fornire un ipn_url. Il tuo ricevitore HTTPS deve essere raggiungibile dal VPS commerciante.

2. Crea una fattura

Sostituisci i segnaposto e invia questa richiesta dal backend. Gli importi sono stringhe decimali, non calcoli in virgola mobile.

curl --fail-with-body --request POST \
  'https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices' \
  --header 'Authorization: Bearer YOUR_MERCHANT_API_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: order-1042-attempt-1' \
  --data '{
  "amount": "10.00",
  "currency": "EUR",
  "order_id": "order-1042",
  "description": "Example order",
  "ipn_url": "https://shop.example.com/payments/wholly-ipn",
  "metadata": {
    "cart_id": "cart-1042"
  }
}'

Salva data.invoice_id con il tuo ordine, poi reindirizza il cliente a links.checkout. Usa una chiave di idempotenza univoca per un nuovo tentativo di pagamento. In caso di timeout, riprova con stessa credenziale, stessa chiave e identici byte del corpo.

Omettere payment_methods usa i metodi accettati dal negozio. Puoi restringerli per fattura con slug delle blockchain e simboli; non abilita mai un asset non accettato. Tutti i campi delle richieste ed esempi di risposta →

3. Scegli IPN, webhook o entrambi

IPN segue il ciclo di vita della fattura. Imposta l'URL IPN predefinito del negozio o sostituiscilo con ipn_url per una fattura. I webhook iscrivono un endpoint a eventi selezionati, per esempio invoice.settled.

Usano lo stesso formato di firma, ma segreti diversi: IPN usa il segreto IPN del negozio; ogni endpoint webhook ha il proprio segreto. Nessuno dei due usa il token bearer API per firmare.

Se entrambi consegnano alla tua app, aspettati notifiche sovrapposte. Non accreditare un ordine due volte.

4. Verifica e salva la notifica

  1. Leggi l'esatto corpo grezzo della richiesta prima dell'analisi JSON. Verifica Wholly-Signature con il segreto corrispondente e controlli di timestamp/replay. Gli SDK ufficiali forniscono verificatori.
  2. Convalida l'identità di progetto, negozio, fattura ed evento del corpo firmato. Le intestazioni di consegna non firmate non sono una fonte di autenticazione.
  3. Memorizza l'evento in modo persistente con un valore univoco di event_id, poi restituisci rapidamente HTTP 2xx. Elabora gli ordini in un worker in background.
  4. Recupera la fattura attuale dal tuo host API configurato, non da un host arbitrario fornito in una richiesta. Confronta progetto, negozio, importo, valuta e riferimento ordine salvati.

PHP · Python · JavaScript / TypeScript · Specifiche della firma ed esempi di ricevitori

5. Evadi una volta, al regolamento

Per un ricevitore basato sugli eventi , gestisci event_type = invoice.settled, poi verifica l'attuale status = settled e la tua politica delle eccezioni. Evadi una sola volta usando una transazione del database/un vincolo univoco sull'ordine.

Tipo di evento e stato sono diversi

Una blockchain con finalizzazione rapida può inviare sia payment.received e invoice.settled con status = settled. Su un'altra blockchain, payment.received può ancora indicare processing. Nessuno dei due flussi è un errore.

Deduplica gli eventi per event_id, non solo per sequenza: tipi di eventi diversi possono condividere una sequenza. I gestori SDK basati sullo stato invece accorpano le revisioni delle fatture e controllano lo stato indipendentemente dal tipo di evento. Non combinare quell'accorpamento con un filtro per tipo di evento. Entrambi gli approcci richiedono comunque protezione dai duplicati a livello di ordine.

Esamina requires_review e le risoluzioni manuali prima di evadere. amount_status = paid da solo non prova la conferma. I campi dell'asset pagato al livello superiore riepilogano il regolamento; payment_info contiene le ricezioni dettagliate e i dati del preventivo. Tutti gli stati, eventi e regole delle eccezioni →

6. Prova nuovi tentativi e recupero

Prova un piccolo pagamento, una consegna duplicata, una fattura scaduta e un ricevitore temporaneamente non disponibile. Ripetere un evento non deve creare un secondo accredito dell'ordine. Gestisci gli eventi fuori ordine senza sovrascrivere stati più recenti.

Esamina Negozio → IPN / Webhook → Cronologia → Dettagli, oppure le sezioni di consegna in Dettagli fattura. Il reinvio riutilizza l'evento registrato, non un nuovo regolamento.

Un credito di elaborazione basso sospende IPN/webhook mentre i pagamenti continuano. Riconcilia gli ordini in sospeso tramite l'API e gestisci le consegne conservate dopo il ripristino. Non evadere mai da un reindirizzamento del browser o da uno screenshot del cliente.