Die InstantPay API

Ein API-Key, eine Rechnung, ein Webhook. Zahlungsanforderung in EUR oder USD anlegen, Kunde zum Hosted Checkout schicken, signierten Webhook bekommen, sobald bezahlt ist. Diese Seite wird aus dem OpenAPI-3-Schema erzeugt unter /openapi.json.

pay.instantnode.eu/v1 API-Key-Auth JSON rein, JSON raus OpenAPI 3.0.3
20
Endpunkte
8
Ressourcengruppen
97
Coins akzeptiert
REST / JSON
Über HTTPS

Loslegen

1

API-Key anlegen

Im Dashboard unter API-Keys. Keys sehen aus wie ik_… und werden einmal gezeigt; zum Bauen einen Test-Key nehmen.

2

Bei jeder Anfrage mitschicken

Als X-API-Key oder Authorization: Bearer. Beides funktioniert gleich.

3

Rechnung anlegen, Kunden weiterleiten

Die Antwort enthält eine checkoutUrl. Zahlt der Kunde, bekommt dein Webhook invoice.confirmed.

Gut zu wissen

Fehler sind { error, message }. Ein Idempotency-Key-Header bei POST /invoices sorgt dafür, dass ein wiederholter Request nie zwei Rechnungen erzeugt.

bash
$ curl -X POST https://pay.instantnode.eu/v1/invoices \
     -H "X-API-Key: ik_…" -H "Content-Type: application/json" \
     -d '{"amount":"19.99","currency":"EUR","orderId":"order-1042"}'

# 201 Created
{
  "id": "3f9c1b2e-…",
  "status": "created",
  "paid": false,
  "amount": "19.99",
  "currency": "EUR",
  "checkoutUrl": "https://pay.instantnode.eu/pay/57rW…"
}

Leitfaden

Überblick

Mit InstantPay nimmt deine Website Krypto-Zahlungen an, ohne dass du selbst eine Wallet betreiben musst. Dein Kunde zahlt in SOL, USDC, USDT, ETH, BNB oder BTC auf einer von uns gehosteten Checkout-Seite; du bekommst einen signierten Webhook und eine Gutschrift in EUR oder USD auf deinem InstantPay-Guthaben. Jede bestätigte Zahlung kostet pauschal 1,66 % des Rechnungsbetrags. Ausgezahlt wird an deine eigene Wallet, wann immer du willst, in SOL, einem Stablecoin, ETH, BNB, POL, TRX, BTC oder LTC.

So läuft eine Zahlung ab:

  1. Dein Server legt eine Rechnung an mit einem Preis in EUR oder USD und bekommt eine Checkout-URL zurück.
  2. Der Kunde zahlt auf der Checkout-Seite (oder in einem Overlay auf deiner Seite): Coin wählen, Adresse und exakten Betrag sehen, senden. Der Kurs wird in diesem Moment eingefroren.
  3. InstantPay beobachtet die Chain. Sobald die Zahlung endgültig ist, bekommt deine Webhook-URL invoice.confirmed.
  4. Du lieferst. Der Rechnungsbetrag minus Gebühr liegt auf deinem Guthaben; eine Auszahlung in dem Coin deiner Wahl forderst du an, wann du willst.

Was du brauchst: ein InstantNode-Konto, einen Server, der HTTPS-Aufrufe machen kann (Node, PHP oder etwas anderes), und eine öffentliche https://-URL, die Webhooks entgegennimmt. Mit Coins, Adressen oder Wechselkursen hast du nie selbst zu tun.

Probier den kompletten Ablauf zuerst aus: unser Demo-Shop unter http://5.230.154.241 ist ein ganz normaler Shop, der InstantPay im Testmodus nutzt. Kauf etwas, zahl mit dem Knopf „Simulate payment“ und sieh zu, wie die Bestellung auf bezahlt springt.

Erste Schritte

Sechs Schritte von null bis zur Live-Integration. Für die Schritte 1 bis 5 brauchst du keine Freischaltung; du kannst bauen und testen, während wir dein Konto prüfen.

  1. Anmelden. Öffne pay.instantnode.eu/dashboard und melde dich mit deinem InstantNode-Konto an. Dabei entsteht ein Merchant-Konto im Status pending.
  2. Konto vervollständigen. Trag unter Account Firma, Website und eine kurze Beschreibung dessen ein, was du verkaufst, akzeptiere die Bedingungen und schick es ab. InstantNode prüft das und schaltet dich frei, in der Regel innerhalb eines Tages.
  3. Test-Key kopieren. Unter API-Keys hast du schon ein Live- und ein Test-Paar: einen Secret Key (sk_test_…, für deinen Server) und einen Public Key (pk_test_…, für den Browser). Zeig den Test-Secret-Key an und leg ihn in die Konfiguration deines Servers, nie in Browser-Code.
  4. Webhook-Endpunkt anlegen. Trag unter Webhooks die https://-Adresse auf deinem Server ein, die Ereignisse empfangen soll, und drück auf der Endpunkt-Seite Send test event, um zu prüfen, dass deine Signaturprüfung funktioniert.
  5. Testkauf machen. Leg mit dem Test-Key eine Rechnung an (siehe unten), öffne die Checkout-URL, drück Simulate payment. Ein paar Sekunden später bekommt dein Webhook invoice.confirmed mit livemode: false.
  6. Live gehen. Sobald dein Konto active ist, schaltest du das Dashboard in den Live-Modus, zeigst den Live-Secret-Key an (wird einmal angezeigt) und tauschst ihn gegen den Test-Key; leg einen Live-Webhook-Endpunkt an. Rechnungen aus einem Live-Key werden mit echten Coins bezahlt und deinem Guthaben gutgeschrieben.

Wege der Integration

Alle Wege nutzen dieselbe API; der einzige Unterschied ist, wo der Kunde bezahlt. Eine Regel gilt für alle: Die Rechnung wird immer auf deinem Server erzeugt, nie im Browser, sonst ist dein API-Key öffentlich.

Hosted Checkout

Der einfachste Weg. Dein Server legt die Rechnung an und leitet den Kunden auf checkoutUrl weiter. Nach der Zahlung kommt der Kunde auf deine redirectUrl zurück. Funktioniert in jedem Shop, braucht kein JavaScript.

js
// Node (Express) - das SDK ist eine einzige Datei: /sdk/node/instapay.mjs
import { InstantPay } from './instapay.mjs';
const pay = new InstantPay({ baseUrl: 'https://pay.instantnode.eu', apiKey: process.env.INSTAPAY_KEY });

app.post('/checkout', async (req, res) => {
  const invoice = await pay.createInvoice({
    amount: '19.99',
    currency: 'EUR',
    orderId: order.id,
    description: 'T-Shirt, blau, M',
    redirectUrl: 'https://shop.example/danke?order=' + order.id,
    cancelUrl: 'https://shop.example/warenkorb',
  }, order.id);                 // Idempotency-Key: ein Retry liefert dieselbe Rechnung
  res.redirect(invoice.checkoutUrl);
});
php
// PHP - /sdk/php/InstaPay.php
require 'InstaPay.php';
$pay = new InstantPay('https://pay.instantnode.eu', getenv('INSTAPAY_KEY'));
$invoice = $pay->createInvoice([
  'amount' => '19.99', 'currency' => 'EUR', 'orderId' => (string) $orderId,
  'redirectUrl' => 'https://shop.example/danke?order=' . $orderId,
], (string) $orderId);
header('Location: ' . $invoice['checkoutUrl']);

Ganz ohne Code. Lege unter Zahlungslinks einen Link mit festem Betrag oder offenem Betrag an (der Kunde gibt ihn ein, innerhalb deiner Grenzen), wiederverwendbar oder einmalig, mit optionalem Ablaufdatum und Erfolgs-URL. Der Link ist eine Seite unter https://pay.instantnode.eu/l/<slug>, die für jeden, der sie öffnet, eine Rechnung erstellt; du bekommst die URL, einen QR-Code und ein Einbett-Snippet. Jede Rechnung aus einem Link trägt paymentLinkId und die Bestellnummer link:<slug>:<n>, Webhook und Gutschrift funktionieren also genauso. Die Link-Seite zählt Aufrufe und Umsatz und listet ihre Zahlungen.

Overlay-Widget

Der Kunde bleibt auf deiner Seite; der Checkout öffnet sich in einem Overlay. Lade instapay.js und öffne es mit dem Token - das ist der letzte Teil der checkoutUrl und kommt von deinem Server. Wenn du den Token nicht durch deine Seite reichen willst, holt ihn der Browser mit deinem Public Key: POST /v1/public/checkout-sessions mit { "invoiceId" } antwortet { token, checkoutUrl } für eine Rechnung, die dein Server angelegt hat; mehr kann ein Public Key nicht.

html
<script src="https://pay.instantnode.eu/instapay.js"></script>
<script>
  InstantPay.open({
    token: token,                         // letzter Teil der checkoutUrl
    lang: 'de',                           // oder 'en'
    onStatus:  (s) => console.log(s.status),
    onPaid:    (s) => location.href = '/danke',
    onExpired: (s) => alert('Das Zahlungsfenster ist abgelaufen'),
    onClose:   ()  => console.log('geschlossen'),
    closeOnPaid: true,
  });
</script>

Das Widget fragt den Status alle vier Sekunden ab und ruft onPaid auf, sobald die Zahlung bestätigt ist. Betrachte das trotzdem nur als Service für den Kunden: ob eine Bestellung bezahlt ist, entscheidet allein der Webhook.

Eigene Zahlungsseite

Rechnung anlegen, POST /v1/invoices/:id/select mit dem vom Kunden gewählten Coin aufrufen und depositAddress sowie amountExpected selbst anzeigen. Den Status über GET /v1/invoices/:id abfragen oder auf den Webhook warten.

Rechnung anlegen

POST /v1/invoices mit deinem Key im Header X-API-Key. Beträge werden als Strings übertragen; rechne mit Geld nie in Fließkommazahlen.

bash
curl -X POST https://pay.instantnode.eu/v1/invoices \
  -H "X-API-Key: sk_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1001" \
  -d '{
    "amount": "19.99",
    "currency": "EUR",
    "orderId": "ORD-1001",
    "description": "T-Shirt, blau, M",
    "redirectUrl": "https://shop.example/danke?order=1001",
    "cancelUrl": "https://shop.example/warenkorb",
    "metadata": {"sku": "shirt-blue-m"},
    "ttlSeconds": 1200
  }'
FeldPflichtBedeutung
amountjaPreis als String mit höchstens zwei Nachkommastellen, z. B. "19.99"
currencyjaEUR oder USD
orderIdneinDeine Bestellnummer. Eindeutig pro Konto; dieselbe orderId liefert dieselbe Rechnung
descriptionneinWird dem Kunden im Checkout angezeigt
redirectUrl / cancelUrlneinWohin der Kunde nach der Zahlung bzw. nach dem Abbruch geht
webhookUrlneinÜberschreibt für diese Rechnung die Standard-Webhook-URL aus deinen Einstellungen
metadataneinBeliebiges JSON-Objekt bis 4 KB; kommt in jedem Webhook zurück
assetneinCoin vorwählen (z. B. USDC_SOL), dann entfällt die Auswahl im Checkout
ttlSecondsneinWie lange die Rechnung bezahlbar bleibt: Standard 1200 (20 Minuten), 60 bis 86400
customerEmailneinDer Kunde bekommt eine Beleg-Mail, sobald die Zahlung bestätigt ist; dir wird sie bei der Zahlung angezeigt

Die Antwort ist die Rechnung (201):

json
{
  "id": "f987fead-cbc0-47e1-b9c1-02423c18ec97",
  "orderId": "ORD-1001",
  "status": "created",
  "paid": false,
  "amount": "19.99",
  "currency": "EUR",
  "checkoutUrl": "https://pay.instantnode.eu/pay/Tx7CVPbpJk7IcTkdKMCKCCKt",
  "expiresAt": "2026-09-19T21:20:13.527Z",
  "asset": null, "amountExpected": null, "amountReceived": null, "depositAddress": null
}

Limits: 60 Aufrufe pro Minute und Key (429), höchstens 1000 offene Rechnungen gleichzeitig (429 too_many_open_invoices). Derselbe Idempotency-Key mit anderem Inhalt antwortet 409. Felder, die du weglässt, kommen aus deinen _Checkout_-Einstellungen: Zeit zum Bezahlen (ttlSeconds), Toleranz, Erfolgs- und Abbruch-URL und die im Checkout angebotenen Coins.

Webhooks

Der Webhook ist der Teil, auf den es ankommt. Die Weiterleitung nach der Zahlung ist nur kosmetisch: Der Kunde kann den Browser schließen und die Coins trotzdem senden, also liefere Ware erst, wenn das Ereignis mit paid: true angekommen ist.

Unter Webhooks legst du bis zu zehn Endpunkte pro Modus an (Live und Test sind getrennte Listen). Jeder Endpunkt hat sein eigenes Signatur-Secret (whsec_…), eine Liste der Event-Typen, die er abonniert (* für alle), und eine Statuszeile. InstantPay sendet an jeden abonnierten Endpunkt einen POST mit JSON-Body. Die URL muss https:// mit öffentlichem Hostnamen sein; Weiterleitungen werden nicht verfolgt, und dein Server hat 10 Sekunden zum Antworten.

X-InstantPay-Signature: t=1758315600,v1=<hex hmac-sha256>
X-InstantPay-Event: invoice.confirmed
X-InstantPay-Livemode: true
X-InstantPay-Delivery: 42
Idempotency-Key: evt_01K5N3Y7Z2Q8XW6M3R9V4T1B5C

Dieselben Header kommen zusätzlich in der bisherigen Schreibweise X-InstaPay-, damit ein bestehender Empfänger weiterläuft.

Signatur prüfen

Die Signatur ist ein HMAC-SHA256 über "<t>.<roher Body>" mit dem Secret des Endpunkts (auf der Endpunkt-Seite nach einer frischen Anmeldung einsehbar). Prüfe die rohen Bytes, die du empfangen hast, nicht ein neu serialisiertes Objekt, und weise Zeitstempel ab, die älter als fünf Minuten sind.

js
// Node (Express) - verifyWebhook kommt aus dem SDK
import { verifyWebhook } from './instapay.mjs';

app.post('/webhooks/instantpay', express.raw({ type: '*/*' }), (req, res) => {
  const raw = req.body.toString('utf8');
  if (!verifyWebhook(process.env.INSTANTPAY_WEBHOOK_SECRET, req.get('x-instantpay-signature'), raw)) {
    return res.status(400).send('bad signature');
  }
  const event = JSON.parse(raw);
  if (event.livemode === false) return res.json({ ok: true });      // ein Test-Event: nie liefern
  const invoice = event.data.object;
  if (event.type === 'invoice.confirmed' && invoice.paid) markOrderPaid(invoice.orderId);
  res.json({ ok: true });                                            // schnell antworten, danach arbeiten
});
php
// PHP
$raw = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_INSTANTPAY_SIGNATURE'] ?? '';
$event = InstantPay::parseWebhook(getenv('INSTANTPAY_WEBHOOK_SECRET'), $signature, $raw);
if ($event === null) { http_response_code(400); exit('bad signature'); }
if (($event['livemode'] ?? true) === false) { echo 'ok'; exit; }
$invoice = $event['data']['object'];
if ($event['type'] === 'invoice.confirmed' && $invoice['paid']) markOrderPaid($invoice['orderId']);
echo 'ok';

Der Ereignis-Body

data.object ist das Objekt genau so, wie GET /v1/invoices/:id (oder /v1/payouts/:id) es zurückgibt; Webhook und Abruf widersprechen sich nie.

json
{
  "id": "evt_01K5N3Y7Z2Q8XW6M3R9V4T1B5C",
  "object": "event",
  "type": "invoice.confirmed",
  "livemode": true,
  "created": "2026-09-19T21:05:00.000Z",
  "data": {
    "object": {
      "object": "invoice",
      "id": "f987fead-cbc0-47e1-b9c1-02423c18ec97",
      "orderId": "ORD-1001",
      "status": "confirmed",
      "paid": true,
      "livemode": true,
      "amount": "19.99",
      "currency": "EUR",
      "asset": "SOL",
      "amountExpected": "0.206789123",
      "amountReceived": "0.206789123",
      "metadata": {"sku": "shirt-blue-m"},
      "createdAt": "2026-09-19T21:00:13.527Z",
      "expiresAt": "2026-09-19T21:20:13.527Z",
      "confirmedAt": "2026-09-19T21:05:00.000Z"
    }
  }
}
EreignisWann
invoice.createdDie Rechnung existiert
invoice.detectedEine Transaktion wurde gesehen, ist aber noch nicht final
invoice.confirmedBezahlt. paid ist true
invoice.overpaidBezahlt, mehr als nötig; alles Eingegangene wird gutgeschrieben. paid ist true
invoice.underpaidZu wenig angekommen; du kannst die Teilzahlung im Dashboard akzeptieren
invoice.expiredVor Ablauf ist nichts angekommen
invoice.paid_lateNach Ablauf der Frist bezahlt; siehe Gebühren, Guthaben und Auszahlungen
invoice.cancelled / invoice.failedStorniert, oder etwas ist schiefgegangen
deposit.confirmedGeld ist auf der statischen Adresse eines Kunden gelandet (Funktion Kunden)
payout.paid / payout.failedEine Auszahlung an deine Wallet ist abgeschlossen; data.object ist die Auszahlung
refund.paid / refund.failedEine Erstattung an einen Kunden ist abgeschlossen; data.object ist die Erstattung
account.approved / account.suspendedDein Konto hat den Status gewechselt

Ein Endpunkt kann auch auf den Legacy-Body gestellt werden (event, livemode und invoice / deposit / payout auf oberster Ebene, priceAmount statt amount); das bekommen Integrationen aus der Zeit vor den Endpunkten. invoice.overpaid kommt dort als invoice.confirmed mit overpaid: true an. Neue Integrationen sollten den Standard nutzen.

Regeln für einen robusten Empfänger

  • Antworte innerhalb von 10 Sekunden mit 2xx und erledige die eigentliche Arbeit danach. Alles andere wird mit wachsenden Abständen wiederholt (5 s, 20 s, 1 min, 3 min, 10 min, 30 min, 1 h, 2 h, 4 h, 8 h), insgesamt zehn Versuche, dann gilt die Zustellung als dead. Ein Endpunkt, der 20 Zustellungen in Folge über mindestens drei Tage nicht annimmt, wird abgeschaltet, und du bekommst eine E-Mail; aktiviere ihn auf seiner Seite wieder, sobald er repariert ist.
  • Sei idempotent. Es gibt genau ein Event pro Ereignis, aber eine Zustellung kann sich wiederholen (Wiederholungen, der Button Erneut senden). Nutze den Header Idempotency-Key oder event.id, um Bereits-Verarbeitetes zu überspringen.
  • Prüfe livemode. Ereignisse aus Testrechnungen und vom Button Send test event tragen livemode: false. Sie sind zum Prüfen deines Codes da, nie zum Versenden von Ware.
  • Im Zweifel nachfragen. GET /v1/events listet jedes Ereignis deines Kontos, neueste zuerst, und GET /v1/invoices/:id antwortet mit paid. Der Tab Events im Dashboard zeigt dieselbe Liste mit jeder Zustellung und einem Button Erneut an Endpunkt senden.

Testmodus

Ein Test-Key verhält sich genau wie ein echter, nur dass seine Rechnungen nie mit Coins bezahlt werden. Im Checkout sieht der Kunde (also du) ein Banner „Test mode“ mit dem Knopf Simulate payment; dein Server kann dasselbe über die API tun. Testrechnungen werden einem getrennten Testguthaben gutgeschrieben, das du nur siehst, wenn der Live/Test-Schalter im Dashboard auf Test steht; es ist nie auszahlbar und nie echtes Geld. Ihre Webhooks tragen livemode: false.

bash
# eine Testrechnung vom eigenen Server aus bezahlen - "case" kann exact, under oder over sein
curl -X POST https://pay.instantnode.eu/v1/invoices/<id>/simulate \
  -H "X-API-Key: sk_test_..." -H "Content-Type: application/json" \
  -d '{"case": "exact"}'

Checkliste, bevor du live gehst:

  • Dein Webhook lehnt eine falsche Signatur ab (400) und akzeptiert das Testereignis aus dem Dashboard.
  • Eine Bestellung wird erst nach invoice.confirmed mit paid: true und livemode: true als bezahlt markiert.
  • Eine wiederholte Zustellung erzeugt keinen zweiten Versand.
  • Bei invoice.underpaid und invoice.expired sieht der Kunde etwas Sinnvolles.
  • Der Test-Key ist in deiner Konfiguration durch einen Live-Key ersetzt und der Test-Key ist widerrufen.

Status einer Rechnung

paid ist das Feld, auf das du schauen solltest: Es ist true bei confirmed und overpaid und false bei allem anderen.

StatusBedeutungpaid
createdAngelegt, Coin noch nicht gewähltnein
awaiting_paymentAdresse angezeigt, wartet auf die Überweisungnein
detectedTransaktion gesehen, noch nicht endgültignein
confirmedBezahlt und endgültigja
overpaidBezahlt, mehr als nötigja
underpaidZu wenig angekommen; du kannst den Eingang akzeptieren (Dashboard, bis 7 Tage nach Ablauf)nein
expiredFrist abgelaufen, nichts angekommennein
paid_lateNach Ablauf der Frist bezahltnein
cancelled / failedAbgebrochen bzw. ein Fehler ist aufgetretennein

Ein Kunde, der minimal zu wenig schickt (bis 0,5 %), gilt trotzdem als bezahlt. Darunter wird die Rechnung underpaid.

Gebühren, Guthaben und Auszahlungen

  • Gebühr. Jede bestätigte Zahlung wird deinem Guthaben in der Rechnungswährung gutgeschrieben, abzüglich der Plattformgebühr, standardmäßig 1,66 %. Rechnung 100.00 € → Gutschrift 98.34 €. Die Gebühr wird beim Anlegen der Rechnung eingefroren, eine spätere Änderung betrifft nur neue Rechnungen.
  • Überzahlt. Gutgeschrieben wird alles, was angekommen ist, zum für die Rechnung fixierten Kurs, abzüglich Gebühr. Das Geld des Kunden gehört dir.
  • Zu spät bezahlt. Bis 60 Minuten nach Ablauf wird die Zahlung automatisch zum fixierten Kurs gutgeschrieben. Spätere warten auf dich: Späte Zahlung akzeptieren auf der Rechnung schreibt den Eingang zum aktuellen Kurs gut; die Kursbewegung seit der Rechnung trägst du.
  • Zu wenig bezahlt. Von selbst wird nichts gutgeschrieben. Teilzahlung akzeptieren auf der Rechnung schreibt den Eingang zum fixierten Kurs abzüglich Gebühr gut; möglich bis 7 Tage nach Ablauf der Rechnung, danach über den Support.
  • Guthaben. Balance im Dashboard zeigt drei Zahlen je Währung: verfügbar (was du auszahlen kannst), ausstehend (auf der Chain erkannte, noch nicht bestätigte Zahlungen) und reserviert (offene Auszahlungen und Erstattungen, bereits abgezogen). Darunter jede Buchung: sale, fee, payout, payout_reversal, refund, refund_reversal und adjustment, mit laufendem Saldo und CSV-Export für deine Buchhaltung.
  • Erstattungen. Aus einer bezahlten Rechnung heraus schickt Erstattung einen Teil des gutgeschriebenen Betrags an eine vom Kunden genannte Adresse zurück, im Coin, mit dem er bezahlt hat, oder in deinem Auszahlungs-Coin. Der Fiat-Betrag verlässt dein Guthaben sofort; die Netzwerkgebühr geht davon ab, die genauen Zahlen siehst du vor der Bestätigung. Erstattungen bis 200 € von Konten, die seit 30 Tagen oder länger freigegeben sind, gehen von selbst raus, größere prüft InstantNode. refund.paid / refund.failed kommen als Webhooks; GET /v1/refunds listet sie. Testrechnungen können nicht erstattet werden.
  • Auszahlungen. Wähle unter Payouts den Coin, in dem du ausgezahlt werden willst (SOL als Standard; außerdem USDC und USDT auf Solana, ETH, USDT und USDC auf Ethereum, BNB, USDT auf BSC, POL, TRX, USDT auf TRON, BTC und LTC), hinterlege deine Wallet-Adresse für diesen Coin und fordere eine Auszahlung an. Dein Guthaben bleibt in EUR/USD; der Coin ist nur das, worin die Auszahlung gesendet wird. Mindestens 10 € (oder $), höchstens 2.000 pro Tag, eine offene Auszahlung gleichzeitig. Jeder Coin hat seine eigene Adresse, und eine neue Adresse muss 24 Stunden alt sein, bevor sie eine Auszahlung empfangen kann. Anfragen bis 500 € werden innerhalb einer Minute automatisch freigegeben; größere prüft InstantNode. Vor der Bestätigung zeigt das Dashboard ein Angebot (Kurs, Coin-Menge, geschätzte Netzwerkgebühr, was ankommt), 60 Sekunden gültig; die Netzwerkgebühr geht von der Auszahlung ab. Der Krypto-Betrag wird bei der Freigabe erneut fixiert und an deine Wallet gesendet. Du bekommst payout.paid oder payout.failed als Webhook; das Feld payout.asset sagt dir, welcher Coin gesendet wurde, networkFeeCrypto, was der Transfer gekostet hat.
  • Automatische Auszahlungen. Lege unter Payouts einen Schwellenwert, einen Zeitplan (sobald er erreicht ist, höchstens einmal am Tag, höchstens einmal pro Woche) und einen Betrag fest, der im Guthaben bleibt; die Regel fordert Auszahlungen von selbst an, markiert als Automatisch. Aus deinem eigenen System heraus macht POST /v1/payouts mit { "currency": "EUR", "amount": "250.00" } (oder "amount": "all") genau das, was das Dashboard-Formular tut, mit denselben Prüfungen; es antwortet 201 mit dem Auszahlungsobjekt, 409 payout_open, solange eine offen ist, und 400 test_mode für einen Test-Key.

Dein Konto

  • Antrag. Unter Konto füllst du das Geschäftsprofil aus: Name für Kunden, rechtlicher Name, Website, Geschäftsbereich, Land, USt-IdNr. (optional), erwartetes Monatsvolumen und was du verkaufst, dann akzeptierst du die Händlerbedingungen. InstantNode prüft das, meist innerhalb eines Tages; du bekommst in jedem Fall eine Mail. Test-Keys funktionieren, während du wartest.
  • Bedingungen. Ändern sich die Händlerbedingungen, bekommst du eine Mail, und der nächste Dashboard-Besuch zeigt die neue Version mit einem Haken, bevor irgendetwas anderes aufgeht; API-Keys und Webhooks laufen derweil weiter. Die aktuelle Version steht immer unter /terms.
  • Benachrichtigungen. Unter Benachrichtigungen wählst du, welche Mails du willst (Zahlung eingegangen, Auszahlung oder Erstattung gesendet oder gescheitert, Webhook-Endpunkt abgeschaltet, Kontostatus, neue Anmeldung von einem neuen Gerät), trägst bis zu 5 weitere Empfänger ein und optional einen Discord- oder Slack-Webhook, der dieselben Ereignisse als kurze Nachricht bekommt.
  • Sitzungen. Konto listet jeden angemeldeten Browser mit Gerät, IP und letzter Aktivität; melde einen ab oder alle anderen. Eine Anmeldung von einem Gerät, das wir auf deinem Konto noch nicht gesehen haben, bekommst du per Mail.
  • Datenexport. Export erstellen baut ein Zip mit Profil, Zahlungen, Kontobuch, Auszahlungen, Erstattungen, Endpunkten, Ereignissen und Zahlungslinks als JSON. Der Link gilt 60 Minuten und wird einmal gezeigt; eine frische Anmeldung wird verlangt.
  • Konto schließen. Möglich, sobald das Live-Guthaben null ist und keine Auszahlung oder Erstattung offen ist. Keys und Endpunkte werden sofort widerrufen, alle Sitzungen enden, die Daten bleiben für die Aufbewahrungsfrist.

API-Referenz

Basis-URL https://pay.instantnode.eu. Jeder Aufruf unter /v1 braucht X-API-Key: sk_live_… (oder Authorization: Bearer …); ein Key aus der Zeit vor den Paaren (ik_<id>.<secret>) funktioniert weiter. Keys liegen unter API-Keys: ein Secret Key je Modus für deinen Server (voller Zugriff, einmal angezeigt, Erneuern mit 24 h Überlappung, optionale IP-Allowlist) und ein Public Key je Modus für den Browser, der nur auf GET /v1/public/config, POST /v1/public/checkout-sessions und dem Checkout-Status angenommen wird. Alles andere antwortet einem Public Key mit 403 public_key_not_allowed.

ScopeErlaubt
invoices:readRechnungen, Währungen, dein Konto, Guthaben, Ledger und Auszahlungen lesen
invoices:writeRechnungen anlegen, Coin vorwählen, Testzahlungen simulieren

Schreibende Aufrufe brauchen ein aktives Konto (403 merchant_not_approved solange pending, 403 merchant_suspended bei Sperre). Ein Test-Key darf schon schreiben, während das Konto noch pending ist. Lesen geht immer.

Jeder Endpunkt mit Parametern, Bodies und Antworten steht in der interaktiven Referenz weiter unten. Dort kannst du Requests mit deinem eigenen Key ausprobieren.

Fehler kommen als JSON mit einem festen error-Code:

json
{"error": "invalid_request", "message": "amount: Required", "requestId": "…"}
CodeHTTPBedeutung
unauthorized401Key fehlt oder stimmt nicht
forbidden403Dem Key fehlt der Scope
public_key_not_allowed403Ein Public Key wurde außerhalb von /v1/public/* benutzt
ip_not_allowed403Der Key hat eine IP-Allowlist, und diese Adresse steht nicht darauf
key_expired401Der Key wurde erneuert, und seine 24-h-Übergangsfrist ist vorbei
merchant_not_approved403Konto noch nicht aktiv; Bewerbung im Dashboard abschicken
merchant_suspended403Konto gesperrt; offene Rechnungen werden noch abgewickelt
not_found404Keine solche Rechnung für diesen Key
invalid_request400Ein Feld fehlt oder ist fehlerhaft
invalid_amount400Betrag nicht positiv oder mehr als zwei Nachkommastellen
price_currency_not_allowed400Nur EUR und USD
unsafe_webhook_url400Kein https, kein öffentlicher Hostname oder ein privates Ziel
selection_failed400Coin nicht verfügbar, Betrag zu klein oder Rechnung abgelaufen
not_test_invoice403simulate wurde auf einer Live-Rechnung aufgerufen
idempotency_conflict409Gleicher Idempotency-Key, anderer Inhalt
too_many_open_invoices429Mehr als 1000 offene Rechnungen
amount_too_large400Über dem für dein Konto gesetzten Höchstbetrag je Rechnung
maintenance503InstantPay ist in Wartung: neue Live-Rechnungen und Auszahlungsanfragen pausieren kurz; versuche es nach den Retry-After-Sekunden erneut
Too Many Requests429Rate-Limit; siehe Header retry-after
internal_error500Nenn uns die requestId

SDKs und Beispiele

Alles ist eine einzelne Datei, die du in dein Projekt kopierst; installiert werden muss nichts.

  • Node: /sdk/node/instapay.mjs - createInvoice, getInvoice, listInvoices, selectAsset, getMerchant, listLedger, listPayouts, getPayout, createPayout, listRefunds, getRefund, simulatePayment, listEvents, getEvent, verifyWebhook, parseWebhook. Der Konstruktor nimmt den Secret Key; parseWebhook versteht den Standard- und den Legacy-Body.
  • PHP: /sdk/php/InstaPay.php - dieselben Methoden für PHP 8 (Klasse InstantPay).
  • Kompletter Shop: /examples/demo-shop/server.mjs ist der Quellcode des Demo-Shops: Produkte, Hosted Checkout, Overlay, Webhook-Empfänger und Bestellliste in einer Datei.
  • Overlay in reinem HTML: /examples/plain-html.html.
  • WooCommerce: /examples/woocommerce-instapay.php zusammen mit dem PHP-SDK in wp-content/plugins/instapay/; Basis-URL, Key und Webhook-Secret unter WooCommerce → Einstellungen → Zahlungen eintragen.

Fragen oder eine Integration, die hakt: [email protected].

Vollständige Referenz · Requests live mit deinem Key testen