Sviluppa con l’API Vouchereto
Una piccola API REST per un solo compito: prendere un voucher, bloccarlo per un cliente e trasformarlo in saldo sulla tua piattaforma.
- URL di base
- api.vouchereto.com/v1
- Test e produzione
- Chiavi vch_test_… e vch_live_…
- Autenticazione
- Chiave Bearer + HMAC-SHA256
- Formato
- JSON · importi in unità minori
Il tuo primo riscatto
Ottieni le chiavi
Crea una chiave di test nel portale esercenti. Vedi la chiave completa una sola volta; la sua ultima parte è anche il segreto con cui firmi le richieste.
Prenota il voucher
Invia il codice, la valuta e il riferimento del tuo cliente. Il voucher viene bloccato per quel cliente e non può essere usato altrove.
Accredita, poi cattura
Accredita il saldo dal tuo lato, poi cattura. Se la ricarica fallisce, annulla invece di catturare e il voucher viene rilasciato.
Ascolta i webhook
Registra un endpoint per ricevere eventi firmati per catture, annullamenti, scadenze e checkout.
POST /v1/redemptions
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213
Vouchereto-Signature: t=1790500000,v1=9c1e5f07…
Content-Type: application/json
{ "code": "7K2M-9QXR-4HTB-2WNZ", "customer_ref": "acct_48213", "currency": "USD" }
# 201 Created
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "reserved",
"amount_minor": 5000, "currency": "USD", "voucher_last4": "2WNZ",
"customer_ref": "acct_48213", "livemode": false,
"expires_at": "2026-09-27T14:12:00Z", "captured_at": null }
# Credit the customer first, then capture. Irreversible.
POST /v1/redemptions/5f0c2a7e-…/capture
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213-capture
Vouchereto-Signature: t=1790500012,v1=4b7d2e91…
# 200 OK
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "captured",
"captured_at": "2026-09-27T14:02:31Z", … }
# The top-up failed: release the voucher back to the customer
POST /v1/redemptions/5f0c2a7e-…/cancel
Authorization: Bearer vch_test_…
Idempotency-Key: topup-88213-cancel
Vouchereto-Signature: t=1790500015,v1=77aa01c3…
# 200 OK
{ "id": "5f0c2a7e-…", "object": "redemption", "status": "cancelled", … }
// Vouchereto-Signature: t=<unix>,v1=<hex HMAC-SHA256(secret, t + "." + rawBody)>
// secret = the whsec_… signing secret of your webhook endpoint
import crypto from "node:crypto";
export function verifyWebhook(rawBody, header, secret) {
const parts = header.split(",").map((p) => p.trim().split("="));
const t = Number(parts.find(([k]) => k === "t")?.[1]);
const sigs = parts.filter(([k]) => k === "v1").map(([, v]) => Buffer.from(v, "hex"));
if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
const expected = crypto.createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return sigs.some((s) => s.length === expected.length && crypto.timingSafeEqual(s, expected));
}
Il ciclo di vita di un riscatto
- catturatoIl voucher è stato speso. Irreversibile.
- annullatoL’hai annullato tu. Il voucher è di nuovo attivo.
- prenotazione scadutaNon catturato in tempo (15 minuti per impostazione predefinita). Il voucher è di nuovo attivo.
Su cosa basare l’integrazione
Firma delle richieste
Ogni richiesta include un header Vouchereto-Signature: un timestamp e un HMAC-SHA256 di timestamp, metodo, percorso e corpo, calcolato con il segreto della tua chiave API. Accettiamo uno scarto di orologio fino a 300 secondi.
// Sign every request with the secret part of your API key (the text after the last "_")
const t = Math.floor(Date.now() / 1000);
const payload = `${t}.${method} ${pathWithQuery}\n${body}`;
const v1 = crypto.createHmac("sha256", keySecret).update(payload).digest("hex");
headers["Vouchereto-Signature"] = `t=${t},v1=${v1}`;
Idempotenza
Ogni POST richiede un header Idempotency-Key. Se ripeti una richiesta con la stessa chiave ricevi la risposta originale, contrassegnata con Idempotent-Replayed: true. Le chiavi vengono conservate per almeno 30 giorni.
Voucher della sandbox
Con una chiave di test, POST /v1/sandbox/vouchers crea un voucher di test nello stato che richiedi (active, reserved, redeemed, expired, risk_hold o void) e ne restituisce il codice. Le chiavi di test vedono solo dati di test.
Eventi webhook
| Evento | Quando viene inviato |
|---|---|
| redemption.captured | Un voucher prenotato è stato catturato. Puoi mantenere il saldo accreditato. |
| redemption.cancelled | Una prenotazione è stata annullata. Il voucher è di nuovo attivo. |
| redemption.expired | Una prenotazione è scaduta senza cattura. |
| checkout.completed | Un checkout ospitato è stato pagato e il voucher applicato. |
| checkout.expired | Una sessione di checkout ospitato è scaduta senza pagamento. |
| checkout.failed | Un checkout pagato è stato stornato, per esempio dopo un rimborso. |
Errori
| Stato | Codice | Cosa dire al cliente |
|---|---|---|
| 404 | VOUCHER_INVALID | Non abbiamo trovato quel codice. Controllalo e riprova. |
| 409 | VOUCHER_ALREADY_REDEEMED | Questo voucher è già stato usato. |
| 409 | VOUCHER_RESERVED | Questo voucher è in uso in un altro pagamento in questo momento. |
| 422 | VOUCHER_EXPIRED | Questo voucher è scaduto. |
| 422 | UNIVERSAL_NOT_ACCEPTED | Non accettiamo voucher universali. Usa un voucher per questo sito. |
| 422 | CURRENCY_MISMATCH | Questo voucher è in un’altra valuta. |
| 429 | TOO_MANY_INVALID_ATTEMPTS | Troppi tentativi. Attendi qualche minuto e riprova. |
Gli errori seguono RFC 7807 (application/problem+json) con un codice stabile e un request_id.
Questa pagina riassume l’API. Il riferimento completo con ogni campo è pubblicato su www.vouchereto.com/docs/reference.
Bloccato su qualcosa?
Scrivi a [DEVELOPER SUPPORT EMAIL]. Uno sviluppatore legge ogni messaggio.
- Specifica OpenAPI
- Collection Postman
- Stato dell’API · [URL]
- Changelog