Entwickler/Integration
Handy-Aufladung
Mit der Handy-Aufladung laden Sie eine Prepaid-Telefonnummer direkt auf. Ihr Kunde erhält Gesprächsguthaben oder Datenvolumen auf seinem Anschluss. Es gibt keinen Code, den Sie weitergeben müssen. Bezahlt wird aus Ihrer CardV-Wallet, genau wie bei anderen Bestellungen.
Siehe auch: Authentifizierung · Grundregeln · Webhooks
#So funktioniert es
GET /recharge/countries Länder, die Sie aufladen können
GET /recharge/operators?country=US Anbieter, Aufladungsarten und Beträge
POST /recharge/quote Ihr Preis und ein quote_token, 300 s gültig
POST /recharge/orders Bestellung aufgeben, bezahlt aus Ihrer Wallet
GET /recharge/orders/{order_id} Status abfragen oder auf einen Webhook warten- Alle Pfade beginnen mit
/api/v1. Senden Sie dieselben Header wie bei jeder Anfrage. - Die beiden
POST-Anfragen müssen signiert sein. Signieren Sie sie wiePOST/orders, aber mit ihrem eigenen Pfad, zum Beispiel/api/v1/recharge/quote. - Aufladungsbestellungen sind von Geschenkkarten-Bestellungen getrennt. Rufen Sie sie über die
/recharge-Endpunkte ab. - Angeboten werden nur Direktaufladungen. PIN-Produkte (ein Code, den der Kunde eintippt) gibt es nicht.
#Länder
GET/api/v1/recharge/countries listet die Länder, die Sie derzeit aufladen können.
{
"count": 2,
"results": [
{"code": "MX", "name": "Mexico", "currency_codes": ["MXN"], "operator_count": 4, "offer_count": 37},
{"code": "US", "name": "United States", "currency_codes": ["USD"], "operator_count": 6, "offer_count": 52}
]
}codeist der Ländercode nach ISO 3166-1 alpha-2. Senden Sie ihn in späteren Anfragen alscountry.currency_codessind die Landeswährungen, in denen die Anbieter dieses Landes verkaufen.- Die Liste ändert sich, wenn Anbieter hinzukommen oder nicht mehr verfügbar sind. Laden Sie sie alle paar Stunden neu.
#Anbieter
GET/api/v1/recharge/operators?country=US listet die Mobilfunkanbieter eines Landes.
Mit search=att filtern Sie nach dem Namen des Anbieters.
{
"count": 1,
"results": [
{
"operator_key": "us-att",
"name": "AT&T",
"country": "US",
"country_name": "United States",
"logo_url": "https://b2b.cardv.net/api/v1/catalog-assets/3f5c...a1.png",
"subtypes": ["airtime", "data"],
"amount_model": "range",
"currency_codes": ["USD"],
"amounts": [
{"min": "5.0000", "max": "100.0000", "currency": "USD", "subtype": "airtime", "label": "5.0000-100.0000 USD"},
{"min": "15.0000", "max": "15.0000", "currency": "USD", "subtype": "data", "label": "15.0000 USD"}
],
"offer_count": 3
}
]
}| Feld | Bedeutung |
|---|---|
operator_key | Die ID für Preisabfrage und Bestellung, zum Beispiel us-att. Speichern Sie sie als Text. |
subtypes | Was Sie kaufen können: airtime (Gesprächsguthaben), data oder bundle (Telefonie und Daten). |
amount_model | fixed, wenn alle Beträge feste Werte sind, range, wenn mindestens ein Betrag ein Bereich ist. |
amounts[] | Jede Option. Ist min gleich max, ist es ein fester Betrag. Sonst ist jeder Betrag dazwischen möglich. |
amounts[].currency | Die Landeswährung dieser Option. Senden Sie sie als local_currency. |
logo_url | Bild, das CardV bereitstellt, oder "". |
- Beträge sind lokale Beträge: das, was der Anschluss erhält, in der Landeswährung.
- Ein unbekannter oder ungültiger
country-Wert führt zu HTTP 400.
#Preisabfrage
POST/api/v1/recharge/quote liefert Ihren Preis für eine Aufladung. Diese Anfrage muss signiert sein.
{
"country": "US",
"operator_key": "us-att",
"amount": "10.00",
"local_currency": "USD",
"subtype": "airtime"
}| Feld | Pflicht | Bedeutung |
|---|---|---|
country | Ja | Ländercode aus der Länderliste. |
operator_key | Ja | Aus der Anbieterliste. |
amount | Ja | Lokaler Betrag als String. Fest: einer der gelisteten Werte. Bereich: zwischen min und max. |
local_currency | Empfohlen | ISO-4217-Code von amount, aus amounts[].currency. Senden Sie ihn, wenn ein Anbieter mehrere Währungen listet. |
subtype | Nein | airtime (Standard), data oder bundle. |
Die Antwort:
{
"country": "US",
"country_name": "United States",
"operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
"subtype": "airtime",
"local_amount": "10.0000",
"local_currency": "USD",
"merchant_price": "9.6200",
"merchant_currency": "USD",
"expires_at": "2026-09-30T08:20:30.123456+00:00",
"quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}merchant_priceist der Betrag, der Ihrer Wallet belastet wird, inmerchant_currency.quote_tokenhält diesen Preis 300 Sekunden lang fest, bisexpires_at. Senden Sie ihn unverändert mit der Bestellung.- Das Token gilt nur für Ihr Konto und für dieses Land, diesen Anbieter, diese Art und diesen Betrag.
- Prüfen Sie vor der Bestellung, ob
local_currencydie erwartete Währung ist. - Eine Preisabfrage reserviert kein Geld. Sie können jederzeit einen neuen Preis abfragen.
#Aufladung bestellen
POST/api/v1/recharge/orders lädt das Telefon auf und bezahlt aus Ihrer Wallet. Diese Anfrage muss signiert sein.
{
"external_order_id": "SHOP-RC-20260930-0001",
"country": "US",
"operator_key": "us-att",
"amount": "10.00",
"local_currency": "USD",
"subtype": "airtime",
"account": "12125550100",
"quote_token": "eyJ2ZXJzaW9uIjox...:1uXyZa:8c1f..."
}| Feld | Pflicht | Bedeutung |
|---|---|---|
external_order_id | Ja | Ihre Bestellnummer. Eindeutig über alle Ihre Bestellungen, auch Geschenkkarten-Bestellungen. |
country, operator_key, amount, local_currency, subtype | Ja | Dieselben Werte wie bei der Preisabfrage. |
account | Ja | Die aufzuladende Telefonnummer: nur Ziffern, mit Ländervorwahl, ohne + und ohne Leerzeichen. |
quote_token | Ja | Aus der Preisabfrage, bevor es abläuft. |
Beispiele für Telefonnummern: 12125550100 (USA), 525512345678 (Mexiko).
Prüfen Sie, ob die Nummer zum gewählten Anbieter gehört. Eine Aufladung auf eine falsche Nummer lässt sich nicht rückgängig machen.
CardV prüft den Preis, belastet Ihre Wallet sofort mit merchant_price und startet die Aufladung im Hintergrund.
Eine neue Bestellung liefert HTTP 201:
{
"idempotent_replay": false,
"order": {
"order_id": "O-00005678",
"external_order_id": "SHOP-RC-20260930-0001",
"status": "accepted",
"status_title": "Recharge accepted",
"poll_after_seconds": 12,
"account": "12***00",
"local_amount": "10.0000",
"local_currency": "USD",
"merchant_price": "9.6200",
"merchant_currency": "USD",
"...": "more fields"
}
}- Speichern Sie
order.order_id. - Die Telefonnummer wird maskiert zurückgegeben, nie vollständig.
#Sicher erneut senden
external_order_id schützt Sie davor, zweimal aufzuladen.
| Sie senden | Sie erhalten |
|---|---|
| Eine neue Bestellnummer | HTTP 201. Eine neue Bestellung. Ihre Wallet wird belastet. |
| Dieselbe Bestellnummer und dieselbe Aufladung | HTTP 200 und "idempotent_replay": true. Die bestehende Bestellung. Keine Abbuchung. |
| Dieselbe Bestellnummer, aber eine andere Aufladung | HTTP 400 bei external_order_id. Es passiert nichts. |
„Dieselbe Aufladung“ bedeutet: gleiches Land, gleicher Anbieter, gleiche Art, gleicher Betrag und gleiche Telefonnummer.
Eine Wiederholung wird erkannt, bevor der Preis geprüft wird. Ein abgelaufenes quote_token liefert daher trotzdem die erste Bestellung.
- Nach einem Timeout, einem 5xx-Fehler oder einer abgebrochenen Verbindung senden Sie denselben Body mit derselben Bestellnummer erneut. Signieren Sie ihn neu, mit neuem Zeitstempel und neuer Nonce.
- Vergeben Sie nie eine neue Bestellnummer, nur weil eine Antwort verloren ging. Sonst wird das Telefon womöglich zweimal aufgeladen.
#Aufladungen abrufen
GET/api/v1/recharge/orders/{order_id} liefert eine Bestellung.
Sie können die CardV-Bestell-ID (O-00005678) verwenden.
{
"order_id": "O-00005678",
"external_order_id": "SHOP-RC-20260930-0001",
"status": "processing",
"order_status": "processing",
"status_title": "Recharge processing",
"status_message": "The recharge request is being processed. Delivery is not confirmed yet.",
"next_step": "Keep this order open and wait for confirmation before placing another recharge.",
"poll_after_seconds": 12,
"country": "US",
"operator": {"operator_key": "us-att", "name": "AT&T", "logo_url": ""},
"subtype": "airtime",
"account": "12***00",
"local_amount": "10.0000",
"local_currency": "USD",
"merchant_price": "9.6200",
"merchant_currency": "USD",
"attempts": [{"attempt_no": 1, "status": "processing", "error_message": "", "submitted_at": "2026-09-30T08:16:02.511201Z", "completed_at": null}],
"created_at": "2026-09-30T08:16:01.004211Z",
"updated_at": "2026-09-30T08:16:02.611978Z",
"...": "more fields"
}- Eine unbekannte Bestell-ID oder die Bestellung eines anderen Kontos führt zu HTTP 404.
status_title,status_messageundnext_stepsind englische Texte, die Sie Ihren Mitarbeitern zeigen können.poll_after_secondsgibt an, wie lange Sie bis zur nächsten Abfrage warten sollen.0bedeutet, dass die Bestellung abgeschlossen ist.
#Aufladungen auflisten
GET/api/v1/recharge/orders listet Ihre Aufladungsbestellungen, die neuesten zuerst.
GET /api/v1/recharge/orders?status=processing&limit=50&offset=0{"count": 3, "limit": 50, "results": ["..."]}- Filter:
statusundsearch(CardV-Bestell-ID, Ihre Bestellnummer oder Name des Anbieters). limitist standardmäßig 20, höchstens 100. Größere Werte werden auf 100 gesenkt.- Ein negativer oder nicht numerischer Wert für
limitoderoffsetführt zu HTTP 400.
#Status
accepted ──► processing ──► succeeded
│
├──► manual_review ──► succeeded oder refunded
│
└──► failed ──► refunded (Geld zurück in Ihrer Wallet)| Status | Abgeschlossen? | Was tun |
|---|---|---|
accepted | Nein | Warten. Die Wallet ist belastet, die Aufladung hat noch nicht begonnen. |
processing | Nein | Warten. Das kann einige Minuten dauern. Bestellen Sie nicht noch einmal. |
manual_review | Nein | CardV prüft das Ergebnis mit dem Anbieter. Warten. |
succeeded | Ja | Das Telefon wurde aufgeladen. Informieren Sie Ihren Kunden. |
failed | Noch nicht | Die Aufladung ist nicht durchgegangen. Auf refunded warten. |
refunded | Ja | Das Geld ist wieder in Ihrer Wallet. Sie dürfen neu bestellen. |
- Fragen Sie nach
poll_after_secondsab und verlängern Sie dann die Abstände: 30 s, 60 s, danach alle 5 Minuten. Bleiben Sie innerhalb des Anfragelimits. - Behandeln Sie einen unbekannten Status als „noch nicht abgeschlossen“.
- Solange eine Bestellung nicht abgeschlossen ist, senden Sie keine weitere Aufladung an dieselbe Nummer mit einer neuen Bestellnummer. Gelingt die erste ebenfalls, wird das Telefon zweimal aufgeladen.
#Webhooks und Erstattungen
Aufladungsbestellungen senden dieselben Webhooks wie andere Bestellungen:
order.succeeded, order.failed und order.refunded.
Der Webhook enthält die CardV-Bestell-ID und Ihre Bestellnummer sowie eine leere items-Liste.
Rufen Sie die Bestellung nach einem Webhook mit GET/api/v1/recharge/orders/{order_id} ab.
Erstattungen erfolgen automatisch. Bestätigt der Anbieter einen Fehlschlag, erstattet CardV den vollen
merchant_price in Ihre Wallet, und die Bestellung wechselt zu refunded.
Die Erstattung sehen Sie im Portal auf der Seite mit den Wallet-Buchungen.
Eine erfolgreiche Aufladung kann weder erstattet noch storniert werden.
#Fehler
Fehler folgen den Grundregeln. Eine abgelehnte Preisabfrage oder Bestellung liefert HTTP 400, und nichts wird belastet.
| Schlüssel | Wo | Was tun |
|---|---|---|
detail | Preisabfrage, Bestellung | Land, Anbieter, Art oder Betrag nicht verfügbar. Prüfen Sie die Anbieterliste. |
amount | Preisabfrage, Bestellung | Keine Zahl, null oder außerhalb des Bereichs. |
local_currency | Preisabfrage, Bestellung | Kein dreistelliger ISO-4217-Code. |
account | Bestellung | Telefonnummer fehlt. |
quote_token | Bestellung | Fehlt, abgelaufen, verändert oder passt nicht. Siehe code, dann Preis neu abfragen. |
balance | Bestellung | Guthaben im Portal aufladen. |
risk | Bestellung | Sie haben ein Bestelllimit erreicht. An CardV wenden. |
external_order_id | Bestellung | Schon für eine andere Bestellung verwendet. Siehe Sicher erneut senden. |
wallet | Bestellung | Keine aktive Wallet. An CardV wenden. |
Fehler bei quote_token enthalten einen code:
{"code": "quote_expired", "quote_token": "This quote expired. Refresh the price and confirm again."}code | Bedeutung |
|---|---|
quote_required | Es wurde kein quote_token gesendet. |
quote_expired | Älter als 300 Sekunden. Preis neu abfragen. |
quote_invalid | Verändert oder für eine andere Aufladung. Preis neu abfragen. |
price_changed | Ihr Preis hat sich seit der Abfrage geändert. Preis neu abfragen und den neuen Preis bestätigen. |
HTTP 403 bedeutet ein Problem mit Zugangsdaten, Signatur, IP-Adresse oder Freischaltung. Siehe Authentifizierung.
Fragen zur Integration? Schreiben Sie an [email protected] und nennen Sie Ihre Merchant ID sowie die Bestell- oder Request-ID.