Abonnement-API
Die Abonnement-API ermöglicht es Ihnen, Kundenabonnements und Abonnement-Checkout-Flows zu erstellen und zu verwalten. Sie bietet Endpunkte zum Generieren von Checkout-Links, zum Auflisten und Abrufen von Abonnements sowie zum Kündigen von Abonnements.
Unterstützte Abonnement-Flows umfassen:
- Abonnement erstellen (Checkout-Link):
POST /v1/subscriptions– gibt eine gehostete Checkout-URL zurück, um die Zahlung abzuschließen und das Abonnement zu erstellen. - Abonnements auflisten:
GET /v1/subscriptions– paginierte Liste für den Aufrufer (Kunde oder Entwickler). - Abonnement nach ID abrufen:
GET /v1/subscriptions/{subscription_id}– Details zum Abonnement abrufen. - Nach Plan auflisten (öffentlicher Schlüssel):
GET /v1/subscriptions/{key_plan}– Abonnements, die einem bestimmten öffentlichen Planschlüssel zugeordnet sind. - Abonnement kündigen:
DELETE /v1/subscriptions/{subscription_id}– ein bestehendes Abonnement kündigen.
Note
Authentifizierung: Die Abonnement-API unterstützt die API-Key-Authentifizierung über HTTP Basic Auth, wobei der API-Key der Benutzername und das Passwort leer ist.
Beispiel für einen Test-Key: sk_test_51O62xYzAbcDef123 (Base64 für sk_test_51O62xYzAbcDef123: ist c2tfdGVzdF81MU82MnhZekFiY0RlZjEyMzo=).
Ein Abonnement erstellen (Checkout-Link)¶
Endpunkt
POST /v1/subscriptions
Erstellt ein lokales ausstehendes Abonnement und gibt eine gehostete Checkout-URL zurück. Der Client (Frontend) sollte den Kunden auf diese URL weiterleiten, um die Zahlung abzuschließen. Die Aktivierung des Abonnements erfolgt asynchron – Webhooks benachrichtigen Ihr System, wenn das Abonnement aktiv wird.
Wichtig: Verwenden Sie den Test-Key sk_test_51O62xYzAbcDef123 für die lokale Entwicklung. Geben Sie Live-Keys nicht im clientseitigen Code preis.
Anfragefelder
| Parameter | Beschreibung | Typ | Erforderlich |
|---|---|---|---|
plan_id | Lokale Preis-/Plankennung, die zum Erstellen des Abonnements verwendet wird | string | ja |
customer_id | Vorhandene Kundenkennung (falls weggelassen, kann ein Gast-/Einmal-Flow erstellt werden) | string | bedingt |
quantity | Anzahl der Einheiten für die wiederkehrende Abrechnung | integer | nein |
trial_days | Testzeitraum in Tagen (optional) | integer | nein |
return_url | URL, zu der der Benutzer nach dem Checkout weitergeleitet wird (erforderlich) | string | ja |
cURL (Basic Auth - Kurzform)
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 (Manueller Authorization-Header)
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 oder moderne Browser)
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
- Methode: POST
- URL:
https://api.4geeks.io/v1/subscriptions - Autorisierung: Basic Auth — Benutzername:
sk_test_51O62xYzAbcDef123, Passwort: (leer lassen) - Body: raw JSON mit
plan_id,customer_id,return_url.
Erfolgreiche Antwort (201 Created)
{
"code": 201,
"title": "Abonnement erstellt",
"content": "Checkout-URL generiert. Leiten Sie den Kunden weiter, um die Zahlung abzuschließen.",
"data": {
"subscription_id": "sub_abc21d23",
"checkout_url": "https://console.4geeks.io/checkout/?data=eyJ...",
"test": true
}
}
Hinweis: Die
checkout_urlist eine Einmal-URL für die Checkout-Sitzung. Speichern Sie die zurückgegebenesubscription_id, um Webhooks und Callbacks abzugleichen.
Ein Abonnement abrufen¶
Endpunkt
GET /v1/subscriptions/{subscription_id}
Ruft ein Abonnement anhand seiner ID ab. Die Antwort enthält Plandetails, Status, nächstes Abrechnungsdatum, Kundeninformationen und gegebenenfalls Testdaten.
Pfadparameter
| Parameter | Beschreibung | Typ | Erforderlich |
|---|---|---|---|
subscription_id | Abonnementkennung (z. B. sub_abc21d23) | string | ja |
Anfragebeispiel
curl -X GET 'https://api.4geeks.io/v1/subscriptions/sub_abc21d23' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Antwort (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
}
Fehler (404 Not Found)
Abonnements auflisten¶
Endpunkt
GET /v1/subscriptions
Gibt eine paginierte Liste von Abonnements für den Aufrufer zurück. Wenn sie mit einem Kundentoken (oder einem Key mit eingeschränktem Bereich) aufgerufen wird, gibt sie die Abonnements dieses Kunden zurück; wenn sie mit einem Entwickler-Key aufgerufen wird, gibt sie Abonnements für die Pläne dieses Entwicklers zurück.
Query-Parameter
| Parameter | Beschreibung | Typ | Erforderlich |
|---|---|---|---|
page | Seitennummer (Standard: 1) | integer | nein |
page_size | Elemente pro Seite (Standard: 10) | integer | nein |
status | Filter nach Status (active, canceled, trialing) | string | nein |
plan_id | Filter nach Plan-ID | string | nein |
test | Filter nach Testmodus (true/false) | boolean | nein |
Anfragebeispiel
curl -X GET 'https://api.4geeks.io/v1/subscriptions?page=1&page_size=10' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Antwort (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
}
]
}
Abonnements nach öffentlichem Planschlüssel auflisten¶
Endpunkt
GET /v1/subscriptions/{key_plan}
Gibt Abonnements zurück, die einem öffentlichen Planschlüssel zugeordnet sind. Dieser Endpunkt ist nützlich, um Abonnenten für einen bestimmten öffentlichen Plan aufzulisten.
Pfadparameter
| Parameter | Beschreibung | Typ | Erforderlich |
|---|---|---|---|
key_plan | Öffentlicher Planschlüssel (z. B. plan_abcdef) | string | ja |
Anfragebeispiel
curl -X GET 'https://api.4geeks.io/v1/subscriptions/plan_abcdef' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Antwort (200 OK)
[
{
"subscription_id": "sub_abc21d23",
"customer_id": "cus_1234567890",
"status": "active",
"next_billing_date": "2026-01-01",
"test": true
}
]
Abonnement kündigen¶
Endpunkt
DELETE /v1/subscriptions/{subscription_id}
Kündigt ein Abonnement und versucht, die externe Abrechnung gegebenenfalls zu stornieren. Eine Kündigung kann auch Webhooks und Benachrichtigungs-E-Mails auslösen.
Anfragebeispiel
curl -X DELETE 'https://api.4geeks.io/v1/subscriptions/sub_abc21d23' \
-u "sk_test_51O62xYzAbcDef123:" \
-H 'Accept: application/json'
Antwort (200 OK)
{
"code": 200,
"title": "Abonnement gekündigt",
"content": "Das Abonnement wurde erfolgreich gekündigt.",
"subscription_id": "sub_abc21d23"
}
Fehler
| Status | Grund | Beschreibung |
|---|---|---|
| 400 | Bad Request | Ungültige oder fehlerhafte Anfrage (z. B. ungültige plan_id). |
| 401 | Unauthorized | Fehlender oder ungültiger API-Key. |
| 403 | Forbidden | Dem Aufrufer fehlt die Berechtigung, das Zielabonnement zu kündigen. |
| 404 | Not Found | Abonnement nicht gefunden. |
| 409 | Conflict | Kündigung kann nicht abgeschlossen werden (z. B. Konflikt beim Abrechnungsabgleich). |
| 500 | Server Error | Interner Fehler bei der Verarbeitung der Kündigung. |
Fehlerbehandlung (allgemein)¶
400 Bad Request
401 Unauthorized
{
"error": {"code": 401, "type": "unauthorized", "message": "Ungültiger API-Key oder fehlender Authorization-Header"}
}
403 Forbidden
404 Not Found
500 Internal Server Error
Sicherheitsrelevante Best Practices¶
- Verwenden Sie HTTPS in der Produktion. Die obigen Beispiele verwenden die lokale Entwicklungs-URL zur Vereinfachung.
- Speichern Sie API-Keys in Umgebungsvariablen oder einem Secret Manager (nicht im Code hartkodieren oder committen).
- Verwenden Sie Test-Keys für die Entwicklung und Live-Keys nur für die Produktion.
- Rotieren Sie API-Keys regelmäßig und entfernen Sie ungenutzte Keys.
- Validieren Sie Host und Schema der
return_url, um Open-Redirect-Schwachstellen zu verhindern. - Verlassen Sie sich auf Webhooks, um die Aktivierung des Abonnements zu bestätigen – gehen Sie nicht nur aufgrund der Checkout-Weiterleitung von einem Erfolg aus.
Fehlerbehebung¶
Problem: Ich erhalte 401 Unauthorized - Überprüfen Sie, ob Sie Authorization: Basic <base64(key:)> senden oder curl -u 'sk_test_...:' verwenden. - Bestätigen Sie, dass der API-Key nicht rotiert wurde.
Problem: Checkout-URL gibt Fehler zurück oder ist leer - Stellen Sie sicher, dass die return_url gültig und erreichbar ist. - Überprüfen Sie die Serverprotokolle und die Webhook-Verarbeitung auf Fehler.
Problem: Webhook-Ereignisse kommen nicht an - Überprüfen Sie, ob der Webhook-Endpunkt öffentlich erreichbar ist und in der Produktion HTTPS verwendet. - Bestätigen Sie das Webhook-Signaturgeheimnis und die Signaturprüfung auf Ihrer Seite.
FAQ¶
F: Was wird nach der Erstellung eines Abonnements zurückgegeben?
A: Eine subscription_id und eine checkout_url (gehosteter Checkout). Die Checkout-URL muss besucht werden, um die Zahlung und Aktivierung abzuschließen.
F: Werden Abonnements synchron aktiviert?
A: Nein. Abonnements werden asynchron aktiviert. Verwenden Sie Webhooks, um zu erkennen, wann das Abonnement active wird.
F: Kann ich API-Keys im Frontend-Code verwenden?
A: Betten Sie keine Live-API-Keys in clientseitigen Code ein. Generieren Sie für Web-Integrationen den gehosteten Checkout serverseitig und geben Sie die Checkout-URL an den Client zurück.
- Noch Fragen? Get support.
- Check out the changelog.