Skip to content

Anleitung zur Einrichtung von QryptoPay

QryptoPay ist eine self-hosted Krypto-Acquiring-Lösung zur automatischen Annahme von Kryptowährungszahlungen auf Ihrer Website. Das Modul lässt sich schnell integrieren: Sie können Zahlungslinks automatisch erstellen, diese an Ihre Kunden senden und Zahlungen direkt auf Ihre eigenen Krypto-Wallets empfangen.

Die gesamte Lösung wird auf Ihrem eigenen Server betrieben. Dadurch behalten Sie die volle Kontrolle über Ihre Gelder und profitieren von einem erhöhten Sicherheitsniveau.

Voraussetzungen für den Start

QryptoPay ist ein Modul der Verwaltungsoberfläche BeAdmin. Für den korrekten Betrieb des Dienstes benötigen Sie:

  • einen Server mit installiertem BeAdmin-Panel (siehe Installationsanleitung);
  • einen Domainnamen, der auf diesen Server verweist (z. B. qpay.mysite.com).

⚠️ Wichtig

Der Domainname wird als Adresse der Zahlungsseite verwendet, auf die Ihre Kunden zur Durchführung der Zahlung weitergeleitet werden. Diese Seite läuft auf demselben Server, auf dem QryptoPay installiert ist. Falls Sie noch keinen Domainnamen haben, können Sie diesen jederzeit später hinzufügen.

Schritt 1. Installation des Moduls

Für den korrekten Betrieb von QryptoPay müssen die folgenden Module installiert werden:

  • DOCKER — zwingend erforderlich, da QryptoPay auf Docker-Containern basiert;
  • NGINX — kann später installiert werden, ist jedoch erforderlich, um die Zahlungsseite bereitzustellen.

Um ein Modul zu installieren, öffnen Sie den entsprechenden Bereich im Seitenmenü und klicken Sie auf Installieren. Die Module müssen nacheinander installiert werden.

Nach der erfolgreichen Installation aller Abhängigkeiten kehren Sie zum QryptoPay-Modul zurück und starten dort die Installation des Moduls selbst.

Schritt 2. Erstellen eines Merchants

Nach der erfolgreichen Installation von QryptoPay erstellen Sie einen Merchant. Klicken Sie dazu auf Erstellen und vergeben Sie einen beliebigen Namen (dieser kann bei Bedarf später geändert werden).

Wenn das Modul NGINX bereits installiert ist und Sie über eine Domain für die Zahlungsseite verfügen, können Sie diese in den erweiterten Einstellungen angeben. In diesem Fall wird die Zahlungsseite automatisch zusammen mit dem Merchant erstellt.

Nach dem Erstellen des Merchants können Sie mit der weiteren Konfiguration fortfahren.

Jeder Merchant umfasst die folgenden Komponenten:

  • zwei Terminals: ein Hauptterminal und ein Testterminal — sie werden zur Einrichtung und Überprüfung der Anbindung an Ihr Projekt verwendet;
  • Bereich Kunden — zur Nachverfolgung von Zahlern (die angezeigten Daten hängen vom ausgewählten Terminal ab);
  • Bereich Zahlungen — zur Anzeige und Analyse von Zahlungen (ebenfalls abhängig vom gewählten Terminal);
  • Bereich Wallets — zur Konfiguration von Zahlungsmethoden und zum Empfang von Zahlungen (nur für das Hauptterminal verfügbar).

ℹ️ Hinweis

Für das Testterminal sind keine Wallets erforderlich, daher ist die Erstellung von Wallets dort nicht vorgesehen.

Für den produktiven Betrieb des Merchants müssen Sie Ihr Projekt mit einem Terminal verbinden und mindestens ein Wallet hinzufügen.

Schritt 3. Einrichtung der Integration

Das zentrale Element der Integration ist das Terminal. Jedes Terminal verfügt über die folgenden Parameter:

  • ID — eine eindeutige Kennung;
  • Token-Paar — ein öffentlicher und ein privater Token (zur Identifizierung von Zahlungen);
  • Webhook — die URL Ihres Projekts, an die QryptoPay Benachrichtigungen über den Zahlungsstatus sendet;
  • Webhook-Schlüssel — wird zur Autorisierung der Webhook-Benachrichtigungen verwendet.

⚠️ Wichtig

Der private Token muss sicher aufbewahrt werden. Wird er kompromittiert, können Dritte in die Zahlungslogik Ihres Projekts eingreifen. Aus diesem Grund speichert QryptoPay den privaten Token nach der Generierung nicht auf seiner Seite.

Bei Verlust oder Kompromittierung können Sie jederzeit ein neues Token-Paar generieren. Vergessen Sie dabei nicht, die Werte in Ihrem Projekt zu aktualisieren.

Der Webhook-Schlüssel ist weniger kritisch, sollte jedoch ebenfalls nicht an Dritte weitergegeben werden, um manipulierte Webhook-Benachrichtigungen zu vermeiden.

Wir empfehlen, die Integration zunächst mit dem Testterminal zu beginnen. Im Gegensatz zum Hauptterminal können Sie damit die korrekte Funktion der Integration prüfen, ohne tatsächlich Kryptowährungen zu übertragen.

Generieren Sie zunächst ein Token-Paar für das Testterminal und speichern Sie den privaten Token sicher ab.

Speichern Sie anschließend die Terminal-Parameter in den Umgebungsvariablen Ihres Projekts. Eine .env-Datei kann beispielsweise wie folgt aussehen:

TERMINAL_ID: <Terminal-ID>
PRIVATE_TOKEN: <generierter privater Token>
WEBHOOK_KEY: <Webhook-Schlüssel aus den Einstellungen>
PAYMENT_URL: <Domain der Zahlungsseite>

Als Nächstes müssen Sie eine Methode implementieren, die einen Zahlungstoken erzeugt, der zum Erstellen eines Zahlungslinks auf der QryptoPay-Seite verwendet wird.

Nachfolgend sehen Sie ein Beispiel für die Implementierung einer solchen Methode in Pseudocode:

function generate_payment_token(private_key_b64, terminal_uuid) -> string
  # dekodiert den privaten Schlüssel von base64/base64url in einen Seed (Rohbytes)
  seed := decode_base64_any(private_key_b64)

  # generiert einen eindeutigen Nonce (in der Regel uuid4)
  nonce := uuid_v4()

  # erstellt den Payload (Pflichtfelder + Zahlungsdaten)
  payload := {
    timestamp: current_unix_time_seconds(),
    nonce: nonce,
    terminal_uuid: terminal_uuid,     // Terminal-ID in QryptoPay

    amount_fiat: transaction.amount,  // Zahlungsbetrag in USD, Format 00.00, decimal, > 0
    payment_mid: transaction.uuid,    // Transaktions-ID in Ihrem Projekt, string
    back_to_store_link: link,         // Link zurück zu Ihrer Website nach der Zahlung (Parameter können optional ergänzt werden), string

    customer: {
      id: customer.uuid,              // Kunden-ID aus Ihrem System (erforderlich), string
      email: customer.email or ""     // Kunden-E-Mail aus Ihrem System (optional), string
    },

    metadata: {                       // beliebige zusätzliche Parameter, die Sie übergeben möchten
      key: value                      // im Format metadata.key=value
    }
  }

  # serialisiert den Payload in eine deterministische (kanonische) Byte-Darstellung
  payload_bytes := canonical_encode(payload)

  # kodiert den Payload in ein für die Übertragung geeignetes Format
  payload_part := base64url_no_padding(payload_bytes)

  # berechnet den kryptografischen Teil des Tokens basierend auf dem privaten Schlüssel und payload_part
  proof_bytes := sign(seed, bytes(payload_part, ASCII))

  # kodiert den kryptografischen Teil des Tokens
  proof_part := base64url_no_padding(proof_bytes)

  # endgültiges Token-Format: "<payload_b64u>.<proof_b64u>"
  return payload_part + "." + proof_part
end

⚠️ Wichtig

Für die Generierung des Zahlungstokens müssen Sie zusätzlich zu den Transaktionsdaten drei Pflichtparameter übergeben: den aktuellen Zeitstempel, einen nonce (empfohlen: uuid4) und die Terminal-ID.

Der Zeitstempel wird verwendet, um die Gültigkeitsdauer des Links zu berechnen (etwas mehr als 1 Stunde). Der nonce dient der Sicherheit und verhindert, dass aus demselben Link mehrere Zahlungs-Intents erstellt werden (Spamschutz). Ohne die Terminal-ID kann QryptoPay die Zahlung nicht verarbeiten.

Verwenden Sie den erzeugten Token und senden Sie eine POST-Anfrage an QryptoPay, um einen Zahlungslink zu erhalten. Zum Beispiel:

POST /public/api/payments/intents/create/
Host: qpay.yoursite.com
Content-Type: application/json

{
  "key": "Zahlungstoken"
}

⚠️ Wichtig

Zum Zeitpunkt der Anfrage muss die Zahlungsseite bereits auf dem Server erstellt sein, auf dem QryptoPay installiert ist.

Wenn die Anfrage erfolgreich ist, erhalten Sie eine Antwort mit einem Zahlungslink. Diesen Link müssen Sie an den Kunden weitergeben, damit er zur Zahlung wechseln kann.

{
  "service_id": "be535ba0-7f84-4cd3-9454-b26c4a938479",
  "url": "https://qpay.yoursite.com/?payment=be535ba0-7f84-4cd3-9454-b26c4a979225",
  "expires_at": "2026-01-30T08:21:56.526112Z"
}

Im Fehlerfall kann der Server einen der folgenden Codes zurückgeben:

  • 400 — ungültige Anfrage (Formatfehler oder fehlende Pflichtparameter).
  • 403 — ungültige Anfragesignatur oder der Zahlungstoken ist abgelaufen.
  • 409 — erneute Verwendung eines Einmal-Tokens. Der übergebene nonce wurde für dieses Terminal bereits verwendet.
  • 444 — die Erstellung eines Zahlungs-Intents ist vorübergehend nicht erlaubt (z. B. aufgrund von Lizenzbeschränkungen oder überschrittener Limits).
  • 445 — die Erstellung von Zahlungs-Intents ist nicht erlaubt — die Lizenz ist ausgeschöpft oder der Zugriff dauerhaft eingeschränkt.
  • 500 — interner Serverfehler.

⚠️ Wichtig

Wenn der Kunde dem Zahlungslink folgt, eine Währung auswählt und den Zahlungsvorgang startet (auf Weiter klickt), kann die ausgewählte Währung nicht mehr geändert werden. In diesem Fall muss der Kunde zu Ihrer Website zurückkehren und einen neuen Zahlungslink erstellen. Dieses Verhalten ist aus Sicherheitsgründen implementiert.

⚠️ Wichtig

Wenn Sie die E-Mail-Adresse des Kunden im Payload an QryptoPay übermitteln und sich diese E-Mail später ändert, identifiziert QryptoPay den Kunden anhand der ID und überschreibt die gespeicherte E-Mail bei einer Abweichung. Die aktualisierte E-Mail wird auch auf ранее erstellte Zahlungen angewendet.

Der allgemeine Ablauf zur Generierung eines Zahlungslinks sieht wie folgt aus:

  • in Ihrem Projekt wird ein Zahlungs-Intent erstellt (z. B. eine Transaktion);
  • der zu zahlende Betrag wird in USD umgerechnet (QryptoPay akzeptiert eingehende Beträge ausschließlich in USD);
  • es wird ein Zahlungstoken mit den erforderlichen Parametern erzeugt und an Ihren Server mit QryptoPay gesendet;
  • QryptoPay gibt einen Zahlungslink zurück, den Sie an den Kunden weitergeben, damit er zur Zahlung wechseln kann.

Anschließend führt der Kunde die Zahlung auf der Zahlungsseite durch und kehrt bei Bedarf in den Shop zurück. Die Benachrichtigung über eine erfolgreiche oder fehlgeschlagene Zahlung wird mit einer Verzögerung an Ihr Projekt gesendet, da Blockchain-Transaktionen auf Netzwerkbestätigungen warten müssen. Dies dauert in der Regel 1–2 Minuten (Tron, USDT TRC-20) bis zu 10–30 Minuten (Bitcoin).

Nun können Sie einen Zahlungslink erstellen, ihn öffnen, eine Währung auswählen und den Zahlungsvorgang starten. Wenn alles korrekt konfiguriert ist, wird die Zahlung in Ihrem QryptoPay-Merchant im Test-Terminal angezeigt.

Schritt 4. Webhook einrichten

Nachdem der Kunde die Zahlung abgeschlossen hat, beginnt QryptoPay damit, die Blockchains nach der entsprechenden Transaktion zu durchsuchen. Wenn die Zahlung strikt gemäß den Anweisungen auf der Zahlungsseite durchgeführt wurde, wird eine Benachrichtigung über die erfolgreiche Zahlung an Ihren Webhook gesendet.

Die Benachrichtigung wird als HTTP-Anfrage mit folgenden Parametern gesendet:

POST /your/webhook/url
Content-Type: application/json

X-Term-UUID: 2671f44b-a025-44d3-b2f1-a0ea07b8acb7
X-Timestamp: 1738150000
X-Body-SHA256: 9c4d2b0a2f5b7d6c8a...   # 64 Hex-Zeichen
X-Signature: 7f1c3d5e9a...             # 64 Hex-Zeichen

{
  ... JSON-Webhook-Payload ...
}

Für die Verarbeitung der Benachrichtigungen benötigen Sie eine Methode, die die Webhook-Signatur validiert und sicherstellt, dass die Anfrage nicht abgefangen oder verändert wurde. Nachfolgend sehen Sie ein Beispiel für eine solche Prüfung in Pseudocode:

function validate_webhook_response() -> bool
  # baut die HMAC-Nachricht: "<terminal_uuid>:<ts>:<body_sha256_hex>"
  message_str := string(term_uuid_header) + ":" + string(ts) + ":" + computed_body_hash
  message_bytes := utf8_bytes(message_str)

  # berechnet die erwartete Signatur: HMAC-SHA256(secret, message), hex
  expected_sig := hmac_sha256_hex(key = utf8_bytes(secret), msg = message_bytes)

  # vergleicht die Signaturen in konstanter Zeit
  if not constant_time_equals(expected_sig, sig_header) then
    return false
  end

  return true
end

⚠️ Wichtig

Wir empfehlen, die Webhook-Anfrage als ungültig zu behandeln, wenn mindestens eine der folgenden Bedingungen erfüllt ist:

  • einer der erforderlichen Header fehlt;
  • X-Term-UUID stimmt nicht mit der Terminal-ID überein, die beim Generieren des Zahlungstokens für diese Transaktion verwendet wurde;
  • X-Timestamp ist keine Zahl (int) oder seit dem angegebenen Zeitstempel sind mehr als 300 Sekunden vergangen (empfohlener Wert).

Wenn die Prüfung erfolgreich ist, können Sie den Request-Body deserialisieren. Sie erhalten ein Objekt in etwa der folgenden Form:

{
  "payment_result": "payment_result",  // Zahlungsergebnis: success, mismatch, unexpected
  "amount_coins": "0.00",             // Betrag in Kryptowährung, Format 00.00
  "amount_fiat": "0.00",              // Betrag in USD, Format 00.00
  "fiat_code": "USD",                 // Fiat-Währung
  "coins_asset": "USDC",              // Kryptowährung: BTC, ETH, USDT, USDC usw.
  "coins_chain": "ETH",               // Netzwerk/Chain: BTC, ETH, TRX usw.
  "service_id": "qryptopay_pi_uuid",  // interner Zahlungs-Identifier in QryptoPay
  "payment_mid": "string",            // Transaktions-ID in Ihrem Projekt; null bei Status unexpected
  "customer": {
    "id": "your_id",                  // Kunden-ID in Ihrem System
    "email": "string"                 // Kunden-E-Mail; null, wenn nicht übergeben
  },
  "metadata": {                       // null, wenn ursprünglich nicht übergeben oder bei Status unexpected
    "key1": "value1"
  },
  "transaction_ids": [                // zugehörige Blockchain-Transaktionen (eine oder mehrere)
    "686...fbe",
    "8be...6ab"
  ]
}

⚠️ Wichtig

Wenn die Validierung erfolgreich ist, antworten Sie mit 200 OK. Andernfalls wird QryptoPay die Zahlungsbenachrichtigung erneut senden, bis eine 200-Antwort zurückgegeben wird.

Die empfangenen Daten können Sie für die Nachbearbeitung der Zahlung verwenden. Ein Teil der Parameter wird im Originalformat zurückgegeben — zum Beispiel alle metadata-Werte, die über den Zahlungslink übergeben wurden.

⚠️ Wichtig

Wenn die E-Mail-Adresse des Kunden bereits in QryptoPay gespeichert ist, aber bei der aktuellen Zahlung keine E-Mail übergeben wird, enthält die Webhook-Benachrichtigung die E-Mail aus der QryptoPay-Datenbank.

💡 Tipp

Wir empfehlen, die Webhook-Daten zusätzlich zu validieren, indem Sie sie mit den ursprünglichen Transaktionsparametern abgleichen (z. B. Betrag, Zahlungs-ID und Kunden-ID).

Als Nächstes müssen Sie auf der Seite Ihres Projekts eine Methode implementieren, die die eingehende Benachrichtigung korrekt verarbeitet. Es gibt drei mögliche Szenarien:

  • success — die Zahlung war erfolgreich. In diesem Fall empfehlen wir, den im Webhook gelieferten Wert amount_fiat vor der Finalisierung der Zahlung mit Ihrem internen Betrag abzugleichen;
  • mismatch — der Kunde hat weniger oder mehr als den erwarteten Betrag bezahlt;
  • unexpected — der Kunde hat Gelder an die Wallet gesendet, ohne zuvor einen Zahlungslink zu erstellen.

Die Verarbeitungslogik für jedes Szenario können Sie selbst festlegen. Beispielsweise können Sie bei mismatch den Betrag aus der Benachrichtigung mit dem erwarteten Betrag vergleichen und den Kunden bei einer unvollständigen Zahlung zur Nachzahlung auffordern. Bei unexpected ist es möglich, den Kontostand des Kunden automatisch aufzufüllen und ihn anschließend über die Zahlung zu informieren.

Nachdem Sie den Handler implementiert haben, tragen Sie die Webhook-URL in den Einstellungen des Test-Terminals ein und wiederholen Sie den Zahlungsablauf: Erstellen Sie einen neuen Zahlungslink und öffnen Sie ihn. Im Test-Terminal wird die Zahlung sofort verarbeitet, und die Benachrichtigung wird umgehend an den Webhook gesendet.

Wenn die Benachrichtigung auf der Seite Ihres Projekts erfolgreich empfangen wurde, kann die Test-Integration als abgeschlossen betrachtet werden.

Schritt 5. Wallets einrichten

Um Zahlungen zu akzeptieren, müssen Sie Wallets für jede Kryptowährung hinzufügen, die Sie unterstützen möchten. Die Wallets werden in externen Diensten erstellt und anschließend mit ihren параметрами im QryptoPay-Modul hinterlegt.

Eine подробная Anleitung zum Hinzufügen und Konfigurieren von Wallets finden Sie unter diesem Link.

Schritt 6. Einrichtung des Hauptterminals

Nach dem Hinzufügen der Wallets können Sie Ihre Website auf den Betrieb mit dem Hauptterminal umstellen. Gehen Sie dazu wie folgt vor:

  • generieren Sie ein neues Token-Paar für das Hauptterminal;
  • bearbeiten Sie die Terminal-Einstellungen und tragen Sie die Webhook-Adresse ein;
  • ersetzen Sie in der .env-Datei Ihres Projekts die Werte ID, PRIVATE_TOKEN und WEBHOOK_KEY durch die Daten des Hauptterminals.

Anschließend können Sie die Funktion des Terminals mit einer Testzahlung überprüfen. Bitte beachten Sie: In diesem Schritt ist eine echte Kryptowährungsüberweisung erforderlich — und zwar in der Währung, für die Sie ein Wallet hinzugefügt haben. Wir empfehlen, mit kleinen Beträgen zu beginnen.

Wenn alle Einstellungen korrekt vorgenommen wurden, wird die Zahlung erfolgreich in Ihrem Projekt verbucht.

BeAdmin © 2025. Alle Rechte vorbehalten.