Zum Inhalt springen
🛒 Doppelte Bestellungen in WooCommerce: 3 Skripte zur Blockierung auf Warenkorbebene

🛒 Doppelte Bestellungen in WooCommerce: 3 Skripte zur Blockierung auf Warenkorbebene

Der Kunde hat zweimal auf „Bestellung aufgeben" geklickt, und nun erscheinen im Admin-Panel zwei identische Bestellungen im Abstand von nur wenigen Sekunden. Der Betrag wurde doppelt abgebucht, der Kunde ist verärgert, und Sie müssen eine Rückerstattung veranlassen.

Doppelte Bestellungen sind kein hypothetisches Szenario. Etwa jeder dritte Shop auf WooCommerce ist damit konfrontiert, insbesondere bei instabilem Hosting oder langsamen Zahlungsgateways. Aber selbst auf einem schnellen Server kann ein Nutzer ein Produkt per URL erneut hinzufügen oder ein kostenloses digitales Produkt dutzende Male kaufen.

Wir haben drei funktionierende Skripte zusammengestellt, die verschiedene Duplikationsszenarien abdecken: von der Erzwingung des Einzelverkaufs bis zur Blockierung wiederholter URL-Zugriffe. Nachfolgend finden Sie eine vollständige Aufschlüsselung mit Code.

Warum Bestellungen in WooCommerce dupliziert werden

💡 Kurzüberblick:

  • Sie erfahren, warum Bestellungen auf Warenkorb-, URL- und Wiederholungskauf-Ebene dupliziert werden
  • Sie installieren ein Skript, um Einzelverkäufe über Metafelder zu erzwingen
  • Sie unterbinden Wiederholungskäufe kostenloser Varianten (digitale Güter, Gutscheine)
  • Sie beseitigen Duplikate per URL mit add-to-cart beim Seiten-Reload
  • Sie testen den Schutz und erfahren, was sonst noch auf Serverebene zu Duplikaten führen kann

Bestellungsduplikate entstehen aus drei Hauptszenarien.

Erstens: Der Nutzer klickt mehrfach auf „Bestellung aufgeben". Das passiert, wenn die Seite hakt, die Person keine Reaktion sieht und die Schaltfläche erneut klickt. Bei langsamem Hosting ein alltäglicher Vorgang.

Zweites Szenario: kostenlose Produkte. Wenn Sie ein kostenloses digitales Produkt anbieten, hält nichts einen Nutzer davon ab, es zehnmal hintereinander zu „kaufen". WooCommerce erfasst von Haus aus nicht, ob dieser Kunde dasselbe Gratisprodukt bereits zuvor erhalten hat.

Drittens: ein direkter Link mit dem Parameter ?add-to-cart=123. Die Warenkorbseite wurde neu geladen, das Produkt wurde erneut hinzugefügt. Ein Link aus einem Newsletter wurde zweimal angeklickt, zwei Exemplare im Warenkorb.

Alle drei Szenarien werden serverseitig über WooCommerce-Hooks gelöst. Keine Plugins, nur Code.

Methode 1: Einzelverkauf über Metafelder erzwingen

Das erste Skript zwingt WooCommerce dazu, ein bestimmtes Produkt als „Einzeln verkauft" zu behandeln, auch wenn dieses Kontrollkästchen in den Produkteinstellungen nicht aktiviert ist. Die Steuerung erfolgt über ein Metafeld.

Wenn das Metafeld maximum_allowed_quantity den Wert 1 hat, gibt der Filter woocommerce_is_sold_individually true zurück, und WooCommerce selbst blockiert das Hinzufügen einer zweiten Einheit zum Warenkorb. Funktioniert sowohl für einfache Produkte als auch für Varianten.

Fügen Sie den Code in die functions.php Ihres Child-Themes ein oder über das Plugin Code Snippets:

1function sd_woocommerce_is_sold_individually( $return, $product ) {
2 switch ( $product->get_type() ) {
3 case 'variation':
4 if ( $product->get_meta( 'variation_maximum_allowed_quantity' ) == 1 ) {
5 return true;
6 }
7 break;
8 case 'simple':
9 if ( $product->get_meta( 'maximum_allowed_quantity' ) == 1 ) {
10 return true;
11 }
12 break;
13 }
14 return $return;
15}
16add_filter( 'woocommerce_is_sold_individually', 'sd_woocommerce_is_sold_individually', 10, 2 );

Was hier passiert: Der Hook woocommerce_is_sold_individually wird jedes Mal ausgelöst, wenn WooCommerce prüft, ob ein Produkt mehr als einmal in den Warenkorb gelegt werden darf. Die Funktion schaut in die Metafelder des Produkts und aktiviert, wenn sie maximum_allowed_quantity = 1 vorfindet, zwangsweise den Modus „Einzeln verkauft". Für Varianten heißt das Feld variation_maximum_allowed_quantity.

So wenden Sie es an. Gehen Sie in die Bearbeitung eines beliebigen Produkts oder einer Variante, fügen Sie ein benutzerdefiniertes Feld mit dem Namen maximum_allowed_quantity (oder variation_maximum_allowed_quantity für eine Variante) und dem Wert 1 hinzu. Speichern. Das war's, dieses Produkt kann nun nicht mehr zweimal in den Warenkorb gelegt werden.

Methode 2: Wiederholungskäufe kostenloser Varianten unterbinden

Kostenlose digitale Produkte sind die größte Lücke im Duplikatschutz. Der Nutzer ist eingeloggt, der Produktpreis ist null, WooCommerce lässt die Bestellung ohne Rückfrage durch. Zehn solcher Bestellungen von einem Kunden, zehn identische Einträge im Admin-Panel.

Das folgende Skript prüft über wc_customer_bought_product(), ob dieser Nutzer dasselbe Produkt bereits gekauft hat. Falls ja, wird das Hinzufügen zum Warenkorb mit einem klaren Hinweis blockiert.

1function sd_disable_repeat_purchase_for_free_products( $passed, $product_id, $quantity, $variation_id = 0 ) {
2 $current_user = wp_get_current_user();
3 $product = $variation_id > 0 ? wc_get_product( $variation_id ) : wc_get_product( $product_id );
4 $target_id = $variation_id > 0 ? $variation_id : $product_id;
5
6 if ( floatval( $product->get_price() ) == 0 ) {
7 if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $target_id ) ) {
8 wc_add_notice(
9 sprintf( __( 'You have already purchased "%s" and cannot purchase it again.', 'sd' ), $product->get_name() ),
10 'error'
11 );
12 return false;
13 }
14 }
15 return $passed;
16}
17add_filter( 'woocommerce_add_to_cart_validation', 'sd_disable_repeat_purchase_for_free_products', 10, 4 );

Nach der Installation sieht der Nutzer eine Fehlermeldung, wenn er versucht, ein bereits gekauftes Gratisprodukt erneut in den Warenkorb zu legen. Die Bestellung selbst wird nicht angelegt.

Zwei wichtige Bedingungen. Erstens: Der Kunde muss eingeloggt sein. Bei Gästen liefert wp_get_current_user() ein leeres Objekt, und die Prüfung funktioniert nicht. Zweitens: Der Produktpreis muss exakt null sein (floatval eliminiert Formatierungsprobleme). Das Skript rührt Produkte mit einem Preis über null nicht an.

Methode 3: Schutz vor Duplikaten per URL mit add-to-cart

WooCommerce erlaubt das Hinzufügen eines Produkts zum Warenkorb über einen direkten Link: /cart/?add-to-cart=123. Praktisch für das Marketing, aber wenn der Nutzer die Seite neu lädt oder dem Link erneut folgt, wird das Produkt wieder hinzugefügt.

Dieses Skript fängt das Laden der Warenkorb- oder Checkout-Seite ab und entfernt, falls das Produkt aus dem URL-Parameter bereits im Warenkorb liegt, stillschweigend die Query-Parameter und leitet auf eine saubere URL um.

1function sd_prevent_duplicate_add_to_cart_redirect() {
2 if ( ( is_cart() || is_checkout() ) && isset( $_GET['add-to-cart'] ) ) {
3 $current_url = home_url( add_query_arg( null, null ) );
4 $product_id = intval( $_GET['add-to-cart'] );
5 $variation_id = isset( $_GET['variation_id'] ) ? intval( $_GET['variation_id'] ) : 0;
6
7 foreach ( WC()->cart->get_cart() as $cart_item ) {
8 if ( $cart_item['product_id'] == $product_id
9 && ( $variation_id == 0 || $cart_item['variation_id'] == $variation_id ) ) {
10 wp_redirect( remove_query_arg( array( 'add-to-cart', 'variation_id' ), $current_url ) );
11 exit;
12 }
13 }
14 }
15}
16add_action( 'template_redirect', 'sd_prevent_duplicate_add_to_cart_redirect' );

Der Hook template_redirect wird ausgelöst, bevor WordPress mit dem Rendern der Seite beginnt. Das Skript prüft, ob der Parameter add-to-cart in der URL vorhanden ist, sucht im Warenkorbinhalt (WC()->cart->get_cart()) nach diesem Produkt und führt, falls gefunden, einen wp_redirect auf dieselbe Seite ohne Query-Parameter durch.

Die wiederholte Zugabe per URL ist damit eliminiert. Gleichzeitig funktioniert die erste Zugabe (wenn das Produkt noch nicht im Warenkorb ist) wie gewohnt.

Alles zusammenführen

Alle drei Skripte arbeiten konfliktfrei und unabhängig voneinander:

  • Das erste begrenzt die Menge eines einzelnen Produkts auf 1, Schutz vor Mehrfachzugaben.
  • Das zweite blockiert Wiederholungskäufe von Gratisprodukten, Schutz vor „Klick-Spamming" bei Freebies.
  • Das dritte beseitigt Duplikate per URL, Schutz vor versehentlichen Wiederholungszugaben.

Fügen Sie den Code über das Plugin Code Snippets auf WP.org hinzu, nicht direkt in die functions.php des Themes. Das Plugin erlaubt es, Snippets einzeln zu aktivieren und zu deaktivieren, ohne die Seite bei einem Fehler lahmzulegen, und verliert den Code nicht bei einem Theme-Wechsel. Legen Sie drei separate Snippets an, das erleichtert die Fehlersuche.

Was Sie sonst noch prüfen sollten, wenn Duplikate bestehen bleiben

Die obigen Skripte decken Duplikate auf Warenkorb- und Checkout-Ebene ab. Es gibt jedoch zwei weitere Problemquellen, die Code nicht beheben kann.

Caching von Warenkorb- und Checkout-Seiten. Caching-Plugins wie WP Rocket oder LiteSpeed Cache schließen diese Seiten standardmäßig aus, aber nach einer Einstellungsaktualisierung kann der Ausschluss zurückgesetzt werden. Prüfen Sie: Warenkorb, Checkout und Mein Konto dürfen weder auf Plugin-Ebene, noch auf Server-Ebene oder im CDN gecached werden.

Wiederholungsversuche des Zahlungsgateways. Wenn das Gateway (Stripe, PayPal) nicht rechtzeitig eine Bestätigung vom Server erhält, sendet es die Benachrichtigung erneut, und WooCommerce legt eine zweite Bestellung an. Ursache ist meist langsames Hosting oder eine Firewall, die Callback-Anfragen blockiert. Lösung: Prüfen Sie die Gateway-Logs auf wiederholte Webhook-Sendungen und stellen Sie sicher, dass die Callback-URL von außen erreichbar ist.

So testen Sie den Schutz

Testen Sie nach der Installation der Skripte unbedingt jedes Szenario auf einer Testseite.

Methode 1: Legen Sie ein Produkt mit dem Metafeld maximum_allowed_quantity = 1 an und versuchen Sie, zwei Einheiten in den Warenkorb zu legen. Es sollte nur eine hinzugefügt werden.

Methode 2: Melden Sie sich an, kaufen Sie ein Gratisprodukt und versuchen Sie dann, es erneut zu kaufen. Sie sollten eine Fehlermeldung sehen.

Methode 3: Fügen Sie ein Produkt über einen direkten Link mit ?add-to-cart=ID zum Warenkorb hinzu und laden Sie dann die Seite neu. Die Anzahl der Artikel im Warenkorb sollte sich nicht ändern.

Testen Sie in einer separaten Installation oder auf einer Staging-Site. Auf einem Live-Shop erst nach vollständiger Prüfung.

⁉️🤔 Häufige Fragen

Warum werden Bestellungen dupliziert, wenn der Button „Bestellung aufgeben" nur einmal geklickt wurde?

Der Grund ist fast immer eine langsame Server-Antwort. Der Nutzer klickt den Button, die Anfrage geht raus, aber die Seite aktualisiert sich mehrere Sekunden lang nicht. Die Person denkt, sie hätte nicht geklickt, und klickt erneut. Beide Anfragen erreichen WooCommerce, und es werden zwei Bestellungen angelegt. Die Skripte in diesem Artikel fangen diese Situation nicht ab; hier hilft clientseitiges Caching (Button nach Klick deaktivieren) oder eine serverseitige Eindeutigkeitsprüfung der Bestellung per Nonce-Token.

Kann ein Zahlungsgateway von sich aus Duplikate erzeugen?

Ja. Wenn das Gateway als Antwort auf eine IPN/Webhook keinen HTTP 200 von Ihrem Server erhält, wiederholt es den Sendevorgang. Bei jedem Wiederholungsversuch kann WooCommerce eine neue Bestellung anlegen. Das Problem wird durch schnelleres Hosting und die Prüfung gelöst, dass die Callback-URL des Gateways nicht durch eine Firewall blockiert wird und keine HTTP-Authentifizierung erfordert.

Blockiert dieser Schutz echte Wiederholungsbestellungen eines Kunden?

Nein. Die Skripte arbeiten auf der Stufe des Hinzufügens zum Warenkorb, nicht auf der Stufe der Bestellerstellung. Wenn ein Kunde bewusst eine Bestellung aufgegeben hat und eine Woche später eine zweite, greifen die Skripte nicht ein. Ausnahme: Methode 2, die einen Wiederholungskauf desselben Gratisprodukts durch denselben Nutzer verbietet.

Ist die Verwendung von Code Snippets zwingend, oder kann der Code in die functions.php?

Sie können functions.php verwenden, aber wir empfehlen Code Snippets. Bei einem Tippfehler im Code der functions.php erhalten Sie einen weißen Bildschirm und Zugriff nur noch per FTP. Das Plugin Code Snippets fängt fatale Fehler ab und deaktiviert das problematische Snippet automatisch, die Seite bleibt funktionsfähig.

Helfen Plugins zur Verhinderung von Duplikaten?

Spezialisierte Plugins wie WooCommerce Duplicate Order Blocker arbeiten auf einer anderen Ebene; sie verfolgen Duplikate anhand von IP, E-Mail oder Browser-Fingerprint auf der Checkout-Stufe. Das deckt das Doppelklick-Szenario ab, das unsere Skripte nicht abdecken. Allerdings lösen Plugins nicht das Problem der Duplikate per add-to-cart-URL und der Wiederholungskäufe eines Gratisprodukts. Die ideale Option: die Skripte aus diesem Artikel plus ein Blocker-Plugin im Checkout.

Zusammenfassung: drei Ebenen des Duplikatschutzes

Drei Skripte decken drei spezifische Szenarien der Bestellungsduplikation ab. Installieren Sie alle auf einmal; jedes ist für seinen eigenen Bereich zuständig, und zusammen bieten sie einen dichten Schutz auf Warenkorb-Ebene.

Sollten nach der Installation weiterhin Duplikate auftreten, richten Sie den Blick auf das Hosting und das Zahlungsgateway. Ein Doppelklick auf den Button „Bestellung aufgeben" lässt sich nicht mit Code auf Warenkorb-Ebene heilen; hier benötigen Sie entweder ein Blocker-Plugin oder einen individuellen Button-Schutz per JavaScript.

Testen Sie den Schutz auf einer Testseite und übertragen Sie ihn dann in den Live-Betrieb. Fünfzehn Minuten für die Installation von drei Snippets sparen Stunden der Abwicklung von Rückerstattungen.