Integrationen

Krypto-Zahlungen mit WooCommerce

Wie Sie Krypto als WooCommerce-Zahlungsart hinzufügen: eine eigene Gateway-Klasse, die Qvard-Zahlung erstellen, der Webhook, der die Bestellung abschließt, und die WooCommerce-spezifischen Stolperfallen.

WooCommerce hat einen sauberen Erweiterungspunkt für Zahlungsarten, und Qvard braucht davon nur zwei Dinge: einen Aufruf, der eine Zahlung erstellt, wenn der Kunde zahlt, und einen Endpunkt, der die Bestellung abschließt, wenn die Zahlung erledigt ist. Ein fertiges Qvard-Plugin gibt es noch nicht, daher zeigt dieser Leitfaden den eigenen Code Stück für Stück und die WooCommerce-Details, die meist schiefgehen.

Bevor Sie anfangen

Sie brauchen ein Qvard-Konto mit einem Projekt, einem API-Schlüssel und einer im Projekt gespeicherten Callback-URL. Auf der WooCommerce-Seite brauchen Sie einen Weg, Code hinzuzufügen, idealerweise ein kleines eigenes Plugin oder ein Code-Snippets-Plugin, keine Theme-Datei, die beim nächsten Theme-Update verschwindet.

Zwei Entscheidungen vorab:

  • Währung. Qvard bepreist Zahlungen in US-Dollar. Das Gateway in diesem Leitfaden akzeptiert Bestellungen in USD und lehnt andere Währungen ab, was die sichere Voreinstellung ist. Verkauft Ihr Shop in einer anderen Währung, rechnen Sie die Bestellsumme vor dem Erstellen der Zahlung in Dollar um und sagen Sie das an der Kasse.
  • Wo der Schlüssel liegt. Definieren Sie den API-Schlüssel als Konstante in wp-config.php (define( 'QVARD_API_KEY', '...' );), nicht in den Datenbankeinstellungen, wo Exporte und andere Plugins ihn lesen können.

Wenn Sie nur die Grundidee ohne die WooCommerce-Klasse brauchen, beginnen Sie mit Krypto-Zahlungen mit WordPress.

Die Teile und wie eine Bestellung vorankommt

Drei Teile bilden die Integration:

  1. Eine Payment-Gateway-Klasse, die an der WooCommerce-Kasse als „Mit Krypto bezahlen“ erscheint.
  2. Ein Aufruf an Qvard im Gateway, der eine Zahlung für die Bestellung erstellt und die Adresse der gehosteten Zahlungsseite zurückgibt.
  3. Ein Webhook-Endpunkt, den Qvard aufruft, wenn die Zahlung abgeschlossen ist.

Eine Bestellung läuft so: Der Kunde wählt die Zahlungsart und drückt auf Bezahlen; das Gateway erstellt die Qvard-Zahlung, setzt die Bestellung in Wartestellung und leitet den Kunden auf die Zahlungsseite; der Kunde zahlt aus einer Wallet; Qvard ruft Ihren Endpunkt auf; der Endpunkt schließt die Bestellung ab, und WooCommerce versendet seine üblichen E-Mails und bringt sie weiter. Die Zahlungs-id, die Sie an Qvard senden, ist die WooCommerce-Bestellnummer, und so findet der Webhook die Bestellung wieder.

Die Gateway-Klasse

Die Klasse erweitert WC_Payment_Gateway. Ihr Konstruktor setzt ID und Titel der Zahlungsart und lädt die Einstellungen, und process_payment erledigt die Arbeit. Sie lehnt Nicht-USD-Bestellungen ab und sendet dann einen POST an https://api.qvard.com/api/v1/payment mit Ihrem Schlüssel im Header Authorization: Bearer und einem JSON: id (die Bestellnummer als String) und price (die Summe in US-Dollar). Eine 201-Antwort trägt eine redirectUrl.

Bei Erfolg speichert das Gateway die Qvard-Zahlungs-ID an der Bestellung, setzt den Status auf on-hold („wartet auf Zahlung“), leert den Warenkorb und gibt die redirectUrl als Weiterleitung zurück. Bei einem Fehler fügt es einen Fehlerhinweis hinzu und gibt failure zurück, sodass der Kunde auf der Kassenseite bleibt und eine andere Zahlungsart wählen kann.

Wird dieselbe id für dieselbe Zahlungsmethode erneut gesendet, kommt die bestehende Zahlung zurück; ein Kunde, der den Button zweimal drückt, erzeugt also keine zwei Zahlungen.

PHPqvard-gateway.php
<?php
// A minimal WooCommerce payment method that sends the customer to the Qvard payment page.
add_filter( 'woocommerce_payment_gateways', function ( $gateways ) {
    $gateways[] = 'WC_Gateway_Qvard';
    return $gateways;
} );

add_action( 'plugins_loaded', function () {
    if ( ! class_exists( 'WC_Payment_Gateway' ) ) {
        return;
    }

    class WC_Gateway_Qvard extends WC_Payment_Gateway {
        public function __construct() {
            $this->id                 = 'qvard';
            $this->method_title       = 'Qvard (crypto)';
            $this->method_description = 'Accept USDT and other crypto through Qvard.';
            $this->has_fields         = false;

            $this->init_form_fields();
            $this->init_settings();
            $this->title = $this->get_option( 'title', 'Pay with crypto' );

            add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
        }

        public function init_form_fields() {
            $this->form_fields = array(
                'enabled' => array( 'title' => 'Enable', 'type' => 'checkbox', 'default' => 'no' ),
                'title'   => array( 'title' => 'Title', 'type' => 'text', 'default' => 'Pay with crypto' ),
            );
        }

        public function process_payment( $order_id ) {
            $order = wc_get_order( $order_id );

            // Qvard prices payments in US dollars: refuse other shop currencies instead of charging a wrong amount.
            if ( 'USD' !== $order->get_currency() ) {
                wc_add_notice( 'Crypto payment is available for orders in USD only.', 'error' );
                return array( 'result' => 'failure' );
            }

            $response = wp_remote_post( 'https://api.qvard.com/api/v1/payment', array(
                'timeout' => 15,
                'headers' => array( 'Authorization' => 'Bearer ' . QVARD_API_KEY, 'Content-Type' => 'application/json' ),
                'body'    => wp_json_encode( array( 'id' => (string) $order->get_id(), 'price' => (float) $order->get_total() ) ),
            ) );

            if ( is_wp_error( $response ) || 201 !== wp_remote_retrieve_response_code( $response ) ) {
                wc_add_notice( 'Could not start the payment. Please try again.', 'error' );
                return array( 'result' => 'failure' );
            }

            $data = json_decode( wp_remote_retrieve_body( $response ), true );
            if ( empty( $data['redirectUrl'] ) ) {
                wc_add_notice( 'Could not start the payment. Please try again.', 'error' );
                return array( 'result' => 'failure' );
            }

            $order->update_meta_data( '_qvard_payment_id', sanitize_text_field( $data['id'] ?? '' ) );
            $order->update_status( 'on-hold', 'Waiting for the crypto payment.' );
            WC()->cart->empty_cart();

            return array( 'result' => 'success', 'redirect' => $data['redirectUrl'] );
        }
    }
} );

Der Webhook, der die Bestellung abschließt

Registrieren Sie eine REST-Route und speichern Sie deren Adresse in Ihrem Qvard-Projekt als Callback-URL. Ist eine Zahlung abgeschlossen, sendet Qvard einen POST mit der id und dem status im Header X-Qvard-Signature signiert. Der Handler im Beispiel:

  • prüft die Signatur (HMAC-SHA256 mit Ihrem geheimen Schlüssel) mit dem Qvard-SDK und antwortet sonst mit 401;
  • findet die Bestellung über die id und ignoriert Bestellungen, die es nicht gibt oder die nicht mit diesem Gateway bezahlt wurden, antwortet aber trotzdem mit 200, damit Qvard aufhört zu wiederholen;
  • ruft payment_complete() nur beim Status completed und nur auf, wenn die Bestellung noch nicht bezahlt ist, was ihn bei doppelter Ausführung sicher macht;
  • antwortet genau mit HTTP 200. Jeder andere Status, ein Timeout oder eine Weiterleitung zählt als fehlgeschlagene Zustellung und wird wiederholt, fünf Versuche in rund sechs Minuten.

Erlauben Sie die Route in jedem Sicherheits-Plugin oder jeder Firewall und stellen Sie sicher, dass Caching /wp-json/ nicht anfasst. Die allgemeinen Regeln stehen in Krypto-Zahlungs-Webhooks absichern.

PHPqvard-webhook.php
<?php
// Callback URL to save in the Qvard project: https://your-shop.com/wp-json/qvard/v1/webhook
add_action( 'rest_api_init', function () {
    register_rest_route( 'qvard/v1', '/webhook', array(
        'methods'             => 'POST',
        'permission_callback' => '__return_true', // authenticated below by the X-Qvard-Signature header
        'callback'            => function ( WP_REST_Request $request ) {
            try {
                $payload = ( new Qvard\Qvard( QVARD_API_KEY ) )->webhooks->constructEvent( $request->get_body(), $request->get_header( 'x-qvard-signature' ), QVARD_API_KEY );
            } catch ( \Exception $e ) {
                return new WP_REST_Response( null, 401 );
            }
            $order   = wc_get_order( (int) ( $payload['id'] ?? 0 ) );

            // Unknown order or not ours: nothing to retry, answer 200.
            if ( ! $order || 'qvard' !== $order->get_payment_method() ) {
                return new WP_REST_Response( null, 200 );
            }

            if ( 'completed' === ( $payload['status'] ?? '' ) && ! $order->is_paid() ) {
                $order->payment_complete( (string) $order->get_meta( '_qvard_payment_id' ) );
                $order->add_order_note( 'Qvard: payment completed.' );
            }

            return new WP_REST_Response( null, 200 ); // must be exactly 200
        },
    ) );
} );

WooCommerce-Details, die beißen

  • Bestand. WooCommerce reduziert den Bestand, wenn eine Bestellung in Bearbeitung oder Wartestellung geht, daher können unbezahlte Krypto-Bestellungen Bestand blockieren. Stornieren Sie veraltete Bestellungen in Wartestellung nach einer von Ihnen gewählten Frist mit einem eigenen geplanten Job (die Bestandsreservierungs-Einstellung von WooCommerce gilt für Bestellungen mit ausstehender Zahlung, nicht für die in Wartestellung); sonst bleibt der Bestand reserviert.
  • Teilzahlungen. Kommt weniger als der volle Betrag an, ist der Zahlungsstatus partial und es wird kein Abschluss-Webhook gesendet. Die Bestellung bleibt in Wartestellung; fügen Sie eine Notiz hinzu, fordern Sie den Rest an oder stornieren und erstatten Sie.
  • Erstattungen. Eine Krypto-Zahlung lässt sich nicht zurückholen. Legen Sie den Erstattungsdatensatz in WooCommerce für Ihre Bücher an, senden Sie das Geld aber selbst an eine Adresse, die der Kunde Ihnen nennt.
  • Bestell-E-Mails. Die „In Wartestellung“-E-Mail geht beim Aufgeben der Bestellung raus; stellen Sie sicher, dass ihr Text dem Kunden sagt, dass die Zahlung aussteht und wo er zahlt.
  • Die Rückkehr auf die Seite. Rücksprung-URLs nach der Zahlung sind noch nicht verfügbar, der Kunde kehrt also von selbst in Ihren Shop zurück. Die Standard-Bestellseite zeigt den echten Status, was richtig ist.
  • Block-Kasse. Die blockbasierte WooCommerce-Kasse braucht ein auch für Blöcke registriertes Gateway; testen Sie die Zahlungsart in der Kasse, die Sie tatsächlich nutzen.

Vor dem Livegang testen

  1. Öffnen Sie eine Demo-Rechnung, um die Zahlungsseite zu sehen, die Ihr Kunde erhält.
  2. Geben Sie eine Testbestellung mit der Krypto-Zahlungsart auf und prüfen Sie, dass Sie auf die Zahlungsseite weitergeleitet werden und die Bestellung in Wartestellung ist.
  3. Zahlen Sie einen kleinen echten Betrag und bestätigen Sie, dass der Webhook eintrifft und die Bestellung in Bearbeitung geht.
  4. Lassen Sie den Endpunkt einmal fehlschlagen, bestätigen Sie, dass Qvard wiederholt und die Bestellung nicht zweimal abgeschlossen wird.
  5. Heben Sie einen kleinen Betrag von Ihrem Guthaben auf Ihre Wallet ab, um zu wissen, dass der ganze Weg funktioniert.

Eine separate Sandbox gibt es noch nicht, verwenden Sie also kleine echte Beträge.

Was es kostet und was bereit ist

Für das Gateway gibt es keine Abo-Gebühr. Die Provision ist für Ihr Projekt individuell und beginnt laut Preisseite bei 1 % und kann bis auf 0,1 % sinken. Die Mittel liegen auf Ihrem Qvard-Guthaben und Sie heben sie gegen die Netzwerkgebühr auf Ihre eigene Wallet ab; eine Auszahlung auf ein Bankkonto in Fiat ist nicht verfügbar.

Qvard arbeitet über seine API, die Integration erfordert also einen Entwickler und Tests; ein fertiges WooCommerce-Plugin gibt es nicht, Zahlungslinks und eine separate Sandbox sind in Entwicklung. Die API selbst ist in Krypto-Zahlungs-API für Entwickler beschrieben, die Shop-Seite in Krypto-Zahlungen für E-Commerce.

FAQ

Gibt es ein Qvard-Plugin für WooCommerce?

Noch nicht. Die Integration läuft über die API: eine Gateway-Klasse, die die Zahlung erstellt, und ein Webhook, der die Bestellung abschließt. Der Code in diesem Leitfaden ist ein Ausgangspunkt für einen Entwickler.

Mein Shop nutzt Euro. Können Kunden trotzdem mit Krypto zahlen?

Qvard bepreist Zahlungen in US-Dollar. Rechnen Sie die Bestellsumme vor dem Erstellen der Zahlung in Dollar um und nennen Sie dem Kunden an der Kasse den Dollarbetrag; das Beispiel-Gateway lehnt Nicht-USD-Bestellungen als sichere Voreinstellung ab.

Wann wird die Bestellung bezahlt?

Wenn der Webhook mit dem Status completed eintrifft. Ein in den Shop zurückgekehrter Kunde ist kein Zahlungsnachweis, und der Status partial bedeutet, dass weniger als erforderlich angekommen ist.

Was, wenn meine Seite beim Abschluss der Zahlung ausgefallen war?

Die Benachrichtigung wird fünfmal in rund sechs Minuten wiederholt. Danach senden Sie sie für die Zahlung aus dem Qvard-Konto erneut; der Handler ist bei doppelter Ausführung sicher.

Ähnliche Artikel

Ähnliche Artikel