
🛒 Dupliserte ordrer i WooCommerce: 3 skript for blokkering på handlekurvnivå
Kunden klikket «Legg inn bestilling» to ganger, og nå ligger det to identiske ordrer i adminpanelet med bare et par sekunders mellomrom. Pengene er trukket to ganger, kunden er rasende, og du må håndtere en refusjon.
Doble ordrer er ikke en hypotetisk situasjon. Omtrent én av tre butikker på WooCommerce opplever det, særlig med ustabil hosting eller trege betalingsgatewayer. Men selv på en rask server kan en bruker legge til et produkt på nytt via URL eller kjøpe et gratis digitalt produkt dusinvis av ganger.
Vi har satt sammen tre fungerende skript som dekker ulike dupliseringsscenarioer: fra å tvinge frem salg av enkeltenheter til å blokkere gjentatte URL-tilføyelser. Nedenfor finner du en komplett gjennomgang med kode.
Hvorfor ordrer dupliseres i WooCommerce
💡 Rask oversikt:
- Du lærer hvorfor ordrer dupliseres på handlekurv, URL- og gjentatt kjøp-nivå
- Du installerer et skript for å tvinge frem salg av enkeltenheter via metafelter
- Du forhindrer gjentatte kjøp av gratis variasjoner (digitale varer, kuponger)
- Du eliminerer duplisering via URL med
add-to-cartved sideoppdatering - Du tester beskyttelsen og lærer hva annet som kan forårsake duplikater på servernivå
Ordreduplikater oppstår fra tre hovedscenarioer.
For det første klikker brukeren «Legg inn bestilling» flere ganger. Dette skjer når siden henger og personen ikke ser noen respons og klikker på knappen igjen. På treg hosting er det en vanlig historie.
Andre scenario, gratisprodukter. Hvis du har et gratis digitalt produkt, er det ingenting som hindrer én bruker i å «kjøpe» det ti ganger på rad. WooCommerce ut av boksen sporer ikke om denne kunden har tatt det samme gratisproduktet før.
Tredje scenario, en direkte lenke med parameteren ?add-to-cart=123. Oppdaterte handlekurvsiden, produktet ble lagt til igjen. Fulgt en lenke fra et nyhetsbrev to ganger, to eksemplarer i handlekurven.
Alle tre scenarioer løses på serversiden via WooCommerce-hooks. Ingen utvidelser, bare kode.
Metode 1: Tvinge frem salg av enkeltenheter via metafelter

Det første skriptet tvinger WooCommerce til å behandle et bestemt produkt som «selges enkeltvis», selv om den avkrysningsboksen ikke er haket av i produktinnstillingene. Kontroll skjer via et metafelt.
Når metafeltet maximum_allowed_quantity er lik 1, returnerer filteret woocommerce_is_sold_individually true, og WooCommerce blokkerer selv å legge til en andre enhet i handlekurven. Fungerer for både enkle produkter og variasjoner.
Legg til koden i barnetemaets functions.php eller via utvidelsen Code Snippets:
1 function 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 } 16 add_filter( 'woocommerce_is_sold_individually', 'sd_woocommerce_is_sold_individually', 10, 2 );
Hva som skjer her: hooken woocommerce_is_sold_individually fyres av hver gang WooCommerce sjekker om et produkt kan legges til i handlekurven mer enn én gang. Funksjonen ser i produktets metafelter og, hvis den finner maximum_allowed_quantity = 1, tvinger den frem «Selges enkeltvis»-modus. For variasjoner heter feltet variation_maximum_allowed_quantity.
Slik bruker du det. Gå inn i redigering av et produkt eller en variasjon, legg til et egendefinert felt med navnet maximum_allowed_quantity (eller variation_maximum_allowed_quantity for en variasjon) og verdien 1. Lagre. Det er alt, nå kan ikke dette produktet legges i handlekurven to ganger.
Metode 2: Forhindre gjentatte kjøp av gratis variasjoner
Gratis digitale produkter er det største hullet i duplikatbeskyttelse. Brukeren er logget inn, produktprisen er null, WooCommerce slipper ordren gjennom uten spørsmål. Ti slike ordrer fra én kunde, ti identiske oppføringer i adminpanelet.
Skriptet nedenfor sjekker via wc_customer_bought_product() om denne brukeren har kjøpt det samme produktet før. Hvis ja, blokkeres tilføyelse til handlekurv med en tydelig melding.
1 function 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 } 17 add_filter( 'woocommerce_add_to_cart_validation', 'sd_disable_repeat_purchase_for_free_products', 10, 4 );
Etter installasjon ser brukeren en feilmelding når de prøver å legge et allerede kjøpt gratisprodukt i handlekurven. Selve ordren opprettes ikke.
To viktige forutsetninger. For det første må kunden være logget inn. For gjester returnerer wp_get_current_user() et tomt objekt, og sjekken vil ikke fungere. For det andre må produktprisen være nøyaktig null (floatval eliminerer formateringsproblemer). Skriptet vil ikke røre produkter med en pris over null.
Metode 3: Beskyttelse mot duplisering via URL med add-to-cart
WooCommerce tillater å legge et produkt i handlekurven via en direkte lenke: /cart/?add-to-cart=123. Praktisk for markedsføring, men hvis brukeren oppdaterer siden eller følger lenken igjen, blir produktet lagt til på nytt.
Dette skriptet fanger opp lasting av handlekurv- eller kasse-siden og, hvis produktet fra URL-parameteren allerede er i handlekurven, fjerner det lydløst spørreparameterne og omdirigerer til en ren URL.
1 function 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 } 16 add_action( 'template_redirect', 'sd_prevent_duplicate_add_to_cart_redirect' );
Hooken template_redirect fyres av før WordPress begynner å rendre siden. Skriptet sjekker om parameteren add-to-cart er i URL-en, ser etter det produktet i handlekurvens innhold (WC()->cart->get_cart()), og hvis det finnes, utfører det en wp_redirect til samme side uten spørreparametere.
Gjentatt tilføyelse via URL er eliminert. Samtidig fungerer den første tilføyelsen (når produktet ennå ikke er i handlekurven) som normalt.
Sette alt sammen
Alle tre skriptene er uten konflikter og fungerer uavhengig:
- Det første begrenser antallet av et enkelt produkt til 1, beskyttelse mot flere tilføyelser.
- Det andre blokkerer gjentatte kjøp av gratisprodukter, beskyttelse mot «klikkspamming» av gratissaker.
- Det tredje fjerner duplisering via URL, beskyttelse mot utilsiktede gjentatte tilføyelser.
Legg til koden via utvidelsen Code Snippets på WP.org, ikke direkte i temaets functions.php. Utvidelsen lar deg aktivere og deaktivere snutter én etter én uten å knekke nettstedet ved feil, og mister ikke kode når du bytter tema. Opprett tre separate snutter, det er lettere å feilsøke på den måten.
Hva annet du bør sjekke hvis duplikater vedvarer
Skriptene ovenfor dekker duplikater på handlekurv- og kassenivå. Men det er to kilder til problemet som kode ikke kan fikse.
Bufring av handlekurv- og kassesider. Bufringsutvidelser som WP Rocket eller LiteSpeed Cache ekskluderer disse sidene som standard, men etter en innstillingsoppdatering kan ekskluderingen tilbakestilles. Sjekk: handlekurv, kasse og min konto må ikke bufres på utvidelsesnivå, servernivå eller i CDN-et.
Nye forsøk fra betalingsgatewayen. Hvis gatewayen (Stripe, PayPal) ikke mottar bekreftelse fra serveren i tide, sender den varselet på nytt, og WooCommerce oppretter en ny ordre. Årsaken er vanligvis treg hosting eller en brannmur som blokkerer callback-forespørsler. Løsning: sjekk gateway-loggene for gjentatte webhook-utsendelser og sørg for at callback-URL-en er tilgjengelig utenfra.
Hvordan teste beskyttelsen
Etter at du har installert skriptene, må du teste hvert scenario på et testnettsted.
Metode 1, opprett et produkt med metafeltet maximum_allowed_quantity = 1 og prøv å legge til to enheter i handlekurven. Bare én skal bli lagt til.
Metode 2, logg inn, kjøp et gratisprodukt, og prøv deretter å kjøpe det igjen. Du skal se en feilmelding.
Metode 3, legg til et produkt i handlekurven via en direkte lenke med ?add-to-cart=ID, og oppdater deretter siden. Antall varer i handlekurven skal ikke endres.
Test i en separat installasjon eller på et staging-nettsted. På en live-butikk, bare etter en fullstendig sjekk.
⁉️🤔 Vanlige spørsmål
Hvorfor dupliseres ordrer hvis «Legg inn bestilling»-knappen ble klikket én gang?
Årsaken er nesten alltid en treg serverrespons. Brukeren klikker på knappen, forespørselen går ut, men siden oppdateres ikke på flere sekunder. Personen tror de ikke klikket og klikker igjen. Begge forespørslene når WooCommerce, og to ordrer opprettes. Skriptene i denne artikkelen fanger ikke opp denne situasjonen; her hjelper bufring på klientsiden (deaktiver knapp etter klikk) eller unikhetssjekk av ordre på serversiden via en nonce-token.
Kan en betalingsgateway opprette duplikater på egen hånd?
Ja. Hvis gatewayen ikke mottar en HTTP 200 fra serveren din som svar på en IPN/webhook, gjentar den utsendelsen. Ved hvert nye forsøk kan WooCommerce opprette en ny ordre. Problemet løses ved å øke hastigheten på hostingen og sjekke at gatewayens callback-URL ikke er blokkert av en brannmur og ikke krever HTTP-autentisering.
Blokkerer denne beskyttelsen genuine gjentatte ordrer fra en kunde?
Nei. Skriptene fungerer på legg-i-handlekurv-stadiet, ikke på ordreopprettelsesstadiet. Hvis en kunde bevisst la inn én ordre, og en uke senere en ny ordre, vil ikke skriptene forstyrre. Unntak: metode 2, som forbyr et gjentatt kjøp av et gratisprodukt av samme bruker.
Er det obligatorisk å bruke Code Snippets, eller kan det legges i functions.php?
Du kan bruke
functions.php, men vi anbefaler Code Snippets. Med en skrivefeil ifunctions.php-kode får du en hvit skjerm og tilgang kun via FTP. Code Snippets-utvidelsen fanger opp fatale feil og deaktiverer automatisk den problematiske snutten, nettstedet holder seg på beina.
Hjelper utvidelser for å forhindre duplikater?
Spesialiserte utvidelser som WooCommerce Duplicate Order Blocker fungerer på et annet nivå; de sporer duplikater etter IP, e-post eller nettleserfingeravtrykk på kassestadiet. Dette dekker dobbeltklikkscenarioet som våre skript ikke dekker. Utvidelser løser imidlertid ikke problemet med duplikater via add-to-cart URL og gjentatte kjøp av et gratisprodukt. Det ideelle alternativet: skriptene fra denne artikkelen pluss en blocker-utvidelse på kassen.
Oppsummering: tre nivåer av duplikatbeskyttelse
Tre skript dekker tre spesifikke ordredupliseringsscenarioer. Installer alle på én gang; hver er ansvarlig for sitt eget område, og sammen gir de tett beskyttelse på handlekurvnivå.
Hvis duplikater fortsatt dukker opp etter installasjon, se mot hosting og betalingsgatewayen. Et dobbeltklikk på «Legg inn bestilling»-knappen kan ikke kureres med kode på handlekurvnivå; her trenger du enten en blocker-utvidelse eller tilpasset knappebeskyttelse via JavaScript.
Test beskyttelsen på et testnettsted, og flytt den deretter til produksjon. Femten minutter for å installere tre snutter sparer timer med opprydding i refusjoner.


