API Abbonamenti
🤖 Spiega con l'intelligenza artificiale
L’API Abbonamenti consente di creare e gestire gli abbonamenti dei clienti e i flussi di checkout degli abbonamenti. Fornisce endpoint per generare link di checkout, elencare e recuperare abbonamenti e annullare abbonamenti.
I flussi di abbonamento supportati includono:
- Creare abbonamento (link di checkout):
POST /v1/subscriptions— restituisce un URL di checkout ospitato per completare il pagamento e creare l’abbonamento. - Elencare gli abbonamenti:
GET /v1/subscriptions— elenco paginato per il chiamante (cliente o sviluppatore). - Recuperare abbonamento per ID:
GET /v1/subscriptions/{subscription_id}— ottieni i dettagli dell’abbonamento. - Elencare per piano (chiave pubblica):
GET /v1/subscriptions/{key_plan}— abbonamenti associati a una determinata chiave pubblica del piano. - Annullare l’abbonamento:
DELETE /v1/subscriptions/{subscription_id}— annulla un abbonamento esistente.
Note
Autenticazione: L’API Abbonamenti supporta l’autenticazione tramite Chiave API via HTTP Basic Auth dove la chiave API è il nome utente e la password è vuota.
Esempio chiave di test: sk_test_51O62xYzAbcDef123 (Base64 per sk_test_51O62xYzAbcDef123: è c2tfdGVzdF81MU82MnhZekFiY0RlZjEyMzo=).
Creare un abbonamento (link di checkout)¶
Endpoint
POST /v1/subscriptions
Crea un abbonamento locale in sospeso e restituisce un URL di checkout ospitato. Il client (frontend) deve reindirizzare il cliente a questo URL per completare il pagamento. L’attivazione dell’abbonamento è asincrona — i webhook notificheranno il tuo sistema quando l’abbonamento diventa attivo.
Importante: Usa la chiave di test sk_test_51O62xYzAbcDef123 per lo sviluppo locale. Non esporre le chiavi live nel codice lato client.
Campi della richiesta
| Parametro | Descrizione | Tipo | Obbligatorio |
|---|---|---|---|
plan_id | Identificatore locale del prezzo/piano utilizzato per creare l’abbonamento | string | true |
customer_id | Identificatore del cliente esistente (se omesso, può essere creato un flusso ospite/una tantum) | string | condizionale |
quantity | Numero di unità per la fatturazione ricorrente | integer | false |
trial_days | Periodo di prova in giorni (opzionale) | integer | false |
return_url | URL a cui l’utente verrà reindirizzato dopo il checkout (obbligatorio) | string | true |
cURL (Basic Auth - abbreviazione)
curl -X POST 'https://api.4geeks.io/v1/subscriptions' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Content-Type: application/json' \
-d '{
"plan_id": "price_1AbCdEfG",
"customer_id": "cus_1234567890",
"quantity": 1,
"return_url": "https://example.com/subscription-result"
}'
cURL (Header di autorizzazione manuale)
curl -X POST 'https://api.4geeks.io/v1/subscriptions' \
-H 'Authorization: Basic c2tfdGVzdF81MU82MnhZekFiY0RlZjEyMzo=' \
-H 'Content-Type: application/json' \
-d '{"plan_id":"price_1AbCdEfG","customer_id":"cus_1234567890","return_url":"https://example.com/subscription-result"}'
Python (requests)
import requests
from requests.auth import HTTPBasicAuth
BASE = 'https://api.4geeks.io'
API_KEY = 'sk_test_51O62xYzAbcDef123'
payload = {
'plan_id': 'price_1AbCdEfG',
'customer_id': 'cus_1234567890',
'quantity': 1,
'return_url': 'https://example.com/subscription-result'
}
resp = requests.post(f"{BASE}/v1/subscriptions", auth=HTTPBasicAuth(API_KEY, ''), json=payload)
print(resp.status_code)
print(resp.json())
JavaScript (fetch, Node.js o browser moderni)
const apiKey = 'sk_test_51O62xYzAbcDef123';
const auth = 'Basic ' + Buffer.from(`${apiKey}:`).toString('base64');
fetch('https://api.4geeks.io/v1/subscriptions', {
method: 'POST',
headers: {
'Authorization': auth,
'Content-Type': 'application/json'
},
body: JSON.stringify({
plan_id: 'price_1AbCdEfG',
customer_id: 'cus_1234567890',
quantity: 1,
return_url: 'https://example.com/subscription-result'
})
})
.then(r => r.json())
.then(console.log)
.catch(console.error)
Angular HttpClient (TypeScript)
import { HttpClient, HttpHeaders } from '@angular/common/http';
const apiKey = 'sk_test_51O62xYzAbcDef123';
const headers = new HttpHeaders({
'Authorization': `Basic ${btoa(apiKey + ':')}`,
'Content-Type': 'application/json'
});
const payload = {
plan_id: 'price_1AbCdEfG',
customer_id: 'cus_1234567890',
return_url: 'https://example.com/subscription-result'
};
this.http.post('https://api.4geeks.io/v1/subscriptions', payload, { headers })
.subscribe(console.log, console.error);
Postman
- Metodo: POST
- URL:
https://api.4geeks.io/v1/subscriptions - Autorizzazione: Basic Auth — Username:
sk_test_51O62xYzAbcDef123, Password: (lascia vuoto) - Corpo: raw JSON con
plan_id,customer_id,return_url.
Risposta di successo (201 Created)
{
"code": 201,
"title": "Abbonamento creato",
"content": "URL di checkout generato. Reindirizza il cliente per completare il pagamento.",
"data": {
"subscription_id": "sub_abc21d23",
"checkout_url": "https://console.4geeks.io/checkout/?data=eyJ...",
"test": true
}
}
Nota: L’
checkout_urlè un URL utilizzabile una sola volta per la sessione di checkout. Memorizza ilsubscription_idrestituito per riconciliare webhook e callback.
Recuperare un abbonamento¶
Endpoint
GET /v1/subscriptions/{subscription_id}
Recupera un abbonamento tramite il suo ID. La risposta include i dettagli del piano, lo stato, la prossima data di fatturazione, le informazioni sul cliente e i dati del periodo di prova quando applicabile.
Parametro di percorso
| Parametro | Descrizione | Tipo | Obbligatorio |
|---|---|---|---|
subscription_id | Identificatore dell’abbonamento (es. sub_abc21d23) | string | true |
Esempio di richiesta
curl -X GET 'https://api.4geeks.io/v1/subscriptions/sub_abc21d23' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Risposta (200 OK)
{
"subscription_id": "sub_abc21d23",
"plan_id": "price_1AbCdEfG",
"customer_id": "cus_1234567890",
"status": "active",
"current_period_start": "2025-12-01T00:00:00Z",
"current_period_end": "2026-01-01T00:00:00Z",
"next_billing_date": "2026-01-01",
"trial_end": null,
"created_at": "2025-12-01T12:00:00Z",
"test": true
}
Errore (404 Not Found)
Elencare gli abbonamenti¶
Endpoint
GET /v1/subscriptions
Restituisce un elenco paginato di abbonamenti per il chiamante. Quando viene chiamato con un token cliente (o chiave limitata) restituisce gli abbonamenti di quel cliente; quando viene chiamato con una chiave sviluppatore restituisce gli abbonamenti per i piani di quello sviluppatore.
Parametri di query
| Parametro | Descrizione | Tipo | Obbligatorio |
|---|---|---|---|
page | Numero di pagina (default: 1) | integer | false |
page_size | Elementi per pagina (default: 10) | integer | false |
status | Filtra per stato (active, canceled, trialing) | string | false |
plan_id | Filtra per ID del piano | string | false |
test | Filtra per modalità test (true/false) | boolean | false |
Esempio di richiesta
curl -X GET 'https://api.4geeks.io/v1/subscriptions?page=1&page_size=10' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Risposta (200 OK)
{
"count": 12,
"current_page": 1,
"total_pages": 2,
"results": [
{
"subscription_id": "sub_abc21d23",
"plan_id": "price_1AbCdEfG",
"customer_id": "cus_1234567890",
"status": "active",
"next_billing_date": "2026-01-01",
"test": true
}
]
}
Elencare gli abbonamenti per chiave pubblica del piano¶
Endpoint
GET /v1/subscriptions/{key_plan}
Restituisce gli abbonamenti associati a una chiave pubblica del piano. Questo endpoint è utile per elencare gli abbonati di un determinato piano pubblico.
Parametro di percorso
| Parametro | Descrizione | Tipo | Obbligatorio |
|---|---|---|---|
key_plan | Chiave pubblica del piano (es. plan_abcdef) | string | true |
Esempio di richiesta
curl -X GET 'https://api.4geeks.io/v1/subscriptions/plan_abcdef' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Risposta (200 OK)
[
{
"subscription_id": "sub_abc21d23",
"customer_id": "cus_1234567890",
"status": "active",
"next_billing_date": "2026-01-01",
"test": true
}
]
Annullare l’abbonamento¶
Endpoint
DELETE /v1/subscriptions/{subscription_id}
Annulla un abbonamento e tenta di annullare la fatturazione esterna dove applicabile. L’annullamento può anche attivare webhook ed email di notifica.
Esempio di richiesta
curl -X DELETE 'https://api.4geeks.io/v1/subscriptions/sub_abc21d23' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Risposta (200 OK)
{
"code": 200,
"title": "Abbonamento annullato",
"content": "L'abbonamento è stato annullato con successo.",
"subscription_id": "sub_abc21d23"
}
Errori
| Stato | Motivo | Descrizione |
|---|---|---|
| 400 | Bad Request | Richiesta non valida o malformata (es. plan_id non valido). |
| 401 | Unauthorized | Chiave API mancante o non valida. |
| 403 | Forbidden | Il chiamante non dispone dei permessi per annullare l’abbonamento di destinazione. |
| 404 | Not Found | Abbonamento non trovato. |
| 409 | Conflict | L’annullamento non può essere completato (es. conflitto di riconciliazione della fatturazione). |
| 500 | Server Error | Errore interno durante l’elaborazione dell’annullamento. |
Gestione degli errori (comune)¶
400 Bad Request
{
"error": {"code": 400, "type": "bad_request", "message": "Campo obbligatorio mancante: plan_id"}
}
401 Unauthorized
{
"error": {"code": 401, "type": "unauthorized", "message": "Chiave API non valida o header Authorization mancante"}
}
403 Forbidden
404 Not Found
500 Internal Server Error
Migliori pratiche di sicurezza¶
- Usa HTTPS in produzione. Gli esempi sopra utilizzano l’URL di sviluppo locale per comodità.
- Memorizza le chiavi API nelle variabili d’ambiente o in un secret manager (non codificarle nel codice né eseguirne il commit).
- Usa le chiavi di test per lo sviluppo e le chiavi live solo per la produzione.
- Ruota regolarmente le chiavi API e rimuovi quelle inutilizzate.
- Valida l’host e lo schema di
return_urlper prevenire vulnerabilità di open redirect. - Affidati ai webhook per confermare l’attivazione dell’abbonamento — non presumere il successo solo dal reindirizzamento del checkout.
Risoluzione dei problemi¶
Problema: Ricevo 401 Unauthorized - Verifica di inviare Authorization: Basic <base64(chiave:)> o di usare curl -u 'sk_test_...:'. - Conferma che la chiave API non sia stata ruotata.
Problema: L’URL di checkout restituisce un errore o è vuoto - Assicurati che return_url sia valido e accessibile. - Controlla i log del server e l’elaborazione dei webhook per eventuali errori.
Problema: Gli eventi webhook non arrivano - Verifica che l’endpoint del webhook sia raggiungibile pubblicamente e utilizzi HTTPS in produzione. - Conferma il segreto di firma del webhook e la verifica della firma da parte tua.
FAQ¶
D: Cosa viene restituito dopo la creazione di un abbonamento?
R: Un subscription_id e un checkout_url (checkout ospitato). L’URL di checkout deve essere visitato per completare il pagamento e l’attivazione.
D: Gli abbonamenti vengono attivati in modo sincrono?
R: No. Gli abbonamenti vengono attivati in modo asincrono. Usa i webhook per rilevare quando l’abbonamento diventa active.
D: Posso usare le chiavi API nel codice frontend?
R: Non inserire chiavi API live nel codice lato client. Per le integrazioni web, genera il checkout ospitato lato server e restituisci l’URL di checkout al client.
- Hai ancora domande? Richiedi supporto..
- Check out the changelog.