Un magazin online care vinde atât persoanelor fizice, cât și firmelor are o problemă pe care formularul standard WooCommerce nu o rezolvă: cele două tipuri de client trebuie să dea date diferite, iar greșelile se văd abia după ce comanda e plasată, când factura e deja emisă. Un CUI scris greșit, o denumire de firmă diferită de cea din registru sau un IBAN cu o cifră în plus înseamnă emailuri de corecție, facturi stornate și timp pierdut de ambele părți.
Ghidul de mai jos explică ce câmpuri merită să ceri la checkout de la persoane fizice și de la firme, cum validezi CNP, CUI și IBAN înainte ca datele să ajungă în comandă și cum eviți greșeala opusă: să ceri prea multe date, să pierzi clienți la checkout și să încalci principiul minimizării datelor din GDPR.
Pe scurt: de la o persoană fizică ceri doar ce îți trebuie pentru livrare și factură: nume, adresă, telefon, email. CNP-ul îl ceri doar dacă o obligație concretă îl impune. De la o firmă ceri denumirea, CUI/CIF, numărul de înregistrare la registrul comerțului și adresa sediului, iar banca și IBAN-ul sunt opționale. Validezi formatul pe server și, opțional, confirmi CUI-ul în ANAF.
De ce nu ajunge un singur formular pentru ambele tipuri de client
Formularul de facturare din WooCommerce pornește de la ideea unui cumpărător individual: prenume, nume, adresă, telefon, email, plus un câmp opțional pentru numele companiei. Pentru un magazin B2C ajunge. Pentru un magazin care vinde și către firme, câmpul „Companie” nu e suficient, pentru că factura către o firmă din România are nevoie de CUI, de numărul de la registrul comerțului și de adresa sediului social, iar aceste date trebuie să fie corecte, nu doar prezente.
Soluția nu e să pui toate câmpurile pentru toată lumea. Un client persoană fizică care vede câmpuri pentru CUI și număr de înregistrare se întreabă dacă a nimerit în locul potrivit, iar un client firmă care nu găsește unde să scrie CUI-ul abandonează sau scrie CUI-ul în câmpul de companie. Cea mai curată variantă este un selector „Cumpăr ca persoană fizică / Cumpăr ca firmă”, care arată sau ascunde grupurile de câmpuri potrivite.
Ce câmpuri ceri de la o persoană fizică
Pentru o persoană fizică, setul minim este cel pe care îl ai deja: nume și prenume, adresa de livrare și de facturare, telefon (curierii îl cer aproape întotdeauna) și email pentru confirmarea comenzii. Orice câmp în plus scade rata de finalizare a comenzii și crește cantitatea de date personale pe care trebuie să o protejezi.
Întrebarea delicată este CNP-ul. Pentru o factură emisă unei persoane fizice, CNP-ul nu este, de regulă, necesar, iar GDPR cere ca datele colectate să fie adecvate, relevante și limitate la ce este necesar scopului (principiul minimizării). Cere CNP doar dacă un document sau o obligație concretă o impune, de exemplu anumite tipuri de garanții sau contracte, și confirmă cu contabilul tău înainte să adaugi câmpul. Dacă îl ceri, spune clar de ce, nu îl face obligatoriu pentru toate comenzile și stochează-l cât mai puțin timp.
Ce câmpuri ceri de la o firmă
O firmă are nevoie de un set diferit de date, iar fiecare are rolul lui pe factură:
| Câmp | Obligatoriu? | Observații |
|---|---|---|
| Denumire firmă | Da | Exact ca în registrul comerțului, inclusiv forma juridică (SRL, SA, PFA) |
| CUI / CIF | Da | Cu sau fără prefixul RO, care arată că firma este înregistrată în scopuri de TVA |
| Număr de înregistrare la registrul comerțului | De obicei | Are formatul J40/1234/2020: litera J, codul județului, numărul și anul |
| Adresa sediului social | Da | Adresa de pe factură poate fi diferită de adresa de livrare |
| Bancă și IBAN | Opțional | Util dacă faci retururi sau plăți prin transfer, altfel nu îl cere |
| Persoană de contact și telefon | Da | Pentru livrare și pentru întrebări despre factură |
În practică, adresa de facturare a unei firme și adresa la care vrea marfa sunt adesea diferite (sediul social față de un depozit sau un punct de lucru). Păstrează cele două adrese separate, cum face WooCommerce implicit, și nu le forța să coincidă.
Cum validezi CNP-ul
CNP-ul are 13 cifre cu o structură fixă: prima cifră codifică sexul și secolul nașterii, urmează anul, luna și ziua nașterii (șase cifre), codul județului (două cifre), un număr de ordine (trei cifre) și o cifră de control. Validarea locală verifică două lucruri: că data este una reală și că cifra de control se potrivește. Cifra de control se calculează înmulțind primele 12 cifre cu constanta 279146358279, adunând produsele și luând restul împărțirii la 11, cu excepția cazului în care restul este 10, când cifra de control este 1.
function valid_cnp( string $cnp ): bool {
if ( ! preg_match( '/^[1-9]\d{12}$/', $cnp ) ) {
return false;
}
$key = '279146358279';
$sum = 0;
for ( $i = 0; $i < 12; $i++ ) {
$sum += (int) $cnp[ $i ] * (int) $key[ $i ];
}
$control = $sum % 11;
if ( $control === 10 ) {
$control = 1;
}
return $control === (int) $cnp[12];
}
Un CNP care trece de această verificare are un format valid, dar asta nu înseamnă că aparține persoanei care îl introduce. Validarea te ferește de greșeli de tastare, nu de date false.
Cum validezi CUI-ul sau CIF-ul
Un CUI are între 2 și 10 cifre, iar ultima cifră este cifra de control. Verificarea folosește cheia 753217532: scoți prefixul RO dacă există, separi ultima cifră, completezi restul cu zerouri la stânga până la 9 cifre, înmulțești cifră cu cifră cu cheia, aduni produsele, înmulțești suma cu 10 și iei restul împărțirii la 11. Dacă restul este 10, cifra de control corectă este 0.
function valid_cui( string $cui ): bool {
$cui = preg_replace( '/^RO/i', '', trim( $cui ) );
if ( ! ctype_digit( $cui ) || strlen( $cui ) < 2 || strlen( $cui ) > 10 ) {
return false;
}
$control = (int) substr( $cui, -1 );
$body = str_pad( substr( $cui, 0, -1 ), 9, '0', STR_PAD_LEFT );
$key = '753217532';
$sum = 0;
for ( $i = 0; $i < 9; $i++ ) {
$sum += (int) $body[ $i ] * (int) $key[ $i ];
}
$rest = ( $sum * 10 ) % 11;
if ( $rest === 10 ) {
$rest = 0;
}
return $rest === $control;
}
Ca și la CNP, un CUI valid ca format poate fi al unei firme radiate sau inexistente. Dacă vrei să știi că firma există și cum se numește, verificarea în ANAF face diferența, iar completarea automată după CUI o rezolvă chiar în checkout.
Cum validezi IBAN-ul
Un IBAN românesc are 24 de caractere: „RO”, două cifre de control, patru litere care identifică banca și 16 caractere alfanumerice. Validarea completă mută primele patru caractere la final, înlocuiește literele cu numere (A devine 10, B devine 11 și tot așa până la Z, care devine 35) și verifică dacă numărul rezultat dă restul 1 la împărțirea cu 97.
function valid_iban_ro( string $iban ): bool {
$iban = strtoupper( preg_replace( '/\s+/', '', $iban ) );
if ( ! preg_match( '/^RO\d{2}[A-Z]{4}[A-Z0-9]{16}$/', $iban ) ) {
return false;
}
$moved = substr( $iban, 4 ) . substr( $iban, 0, 4 );
$number = '';
foreach ( str_split( $moved ) as $ch ) {
$number .= ctype_alpha( $ch ) ? (string) ( ord( $ch ) - 55 ) : $ch;
}
$rest = 0;
foreach ( str_split( $number, 7 ) as $chunk ) {
$rest = (int) ( $rest . $chunk ) % 97;
}
return 1 === $rest;
}
Acceptă IBAN-ul cu spații, pentru că așa îl copiază oamenii din aplicația băncii, și normalizează-l înainte de salvare.
Validare în browser și pe server
Validarea din browser (JavaScript) îi arată clientului greșeala imediat, fără să trimită formularul, și îmbunătățește experiența. Dar ea nu are nicio valoare de securitate: oricine o poate ocoli. Validarea care contează rulează pe server, în momentul plasării comenzii. În checkout-ul clasic, punctul potrivit este hook-ul woocommerce_after_checkout_validation, unde adaugi o eroare pe câmpul greșit, iar comanda nu se mai creează. Checkout-ul bazat pe blocuri funcționează diferit, iar diferențele sunt explicate în ghidul despre checkout cu blocuri sau checkout clasic.
Cum arăți formularul ca să nu pierzi comenzi
Câteva reguli simple țin rata de abandon sub control. Pornește cu „persoană fizică” selectat, pentru că majoritatea clienților sunt acolo. Arată câmpurile firmei doar când clientul alege „firmă”. Pune mesajul de eroare lângă câmpul greșit și spune ce e greșit („CUI-ul are cifra de control greșită”), nu doar „date invalide”. Folosește inputmode="numeric" pe câmpurile cu cifre, ca telefoanele să deschidă tastatura numerică, și atributele autocomplete potrivite, ca browserul să poată completa singur adresa. Dacă vrei un punct de plecare pentru restul checkout-ului, checklist-ul de UX pentru ecommerce acoperă și această zonă.
Greșeli frecvente
- Ceri CNP tuturor clienților. Colectezi date sensibile fără motiv, iar unii clienți abandonează.
- Faci validarea doar în JavaScript. Se ocolește ușor, iar datele greșite ajung oricum în comandă.
- Respingi CUI-ul cu prefix RO. Mulți clienți îl scriu cu prefix, deci scoate-l înainte de calcul.
- Forțezi adresa de facturare să fie și adresa de livrare. La firme sunt adesea diferite.
- Mesaje de eroare generice. Clientul nu știe ce să corecteze și renunță.
- Nu salvezi tipul de client în comandă. Programul de facturare nu mai știe cum să trateze comanda.
Întrebări frecvente
Trebuie să cer CNP-ul de la persoanele fizice?
De regulă nu. Cere-l doar dacă o obligație concretă îl impune și confirmă cu contabilul tău. Altfel, încalci principiul minimizării datelor din GDPR și riști să pierzi clienți.
Cum validez un CUI care începe cu RO?
Scoate prefixul RO înainte de calcul. Prefixul arată că firma este înregistrată în scopuri de TVA, dar cifra de control se calculează doar pe cifre.
E suficientă validarea locală a CUI-ului?
Validarea locală prinde greșelile de tastare, dar nu arată dacă firma există. Pentru asta ai nevoie de o verificare în ANAF, care poate completa și denumirea și adresa.
Pot cere IBAN-ul la checkout?
Poți, ca prim câmp opțional pentru firme. Ai nevoie de el doar dacă faci retururi sau plăți prin transfer bancar.
Unde se salvează datele de facturare în WooCommerce?
În metadatele comenzii. Un plugin bine făcut le salvează prin API-ul WooCommerce, ca să rămână compatibile cu stocarea comenzilor în tabele dedicate (HPOS).
Dacă vrei să construim împreună un checkout adaptat pentru clienții tăi, vezi cum lucrăm la dezvoltarea WooCommerce sau scrie-ne pentru o integrare cu programul tău de facturare.
