import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { apiVersion: '2023-10-16' });
// Backend endpoint pentru Stripe Elements cu salvare date CUI
export async function createPaymentIntent(amountRon: number, cui: string, companyName: string) {
return await stripe.paymentIntents.create({
amount: amountRon * 100,
currency: 'ron',
automatic_payment_methods: { enabled: true },
metadata: {
cui_client: cui,
nume_firme: companyName,
mediu: 'saas_app_v2'
}
});
}Anul trecut am fost pus în situația de a alege între Stripe Checkout și Stripe Elements pentru un SaaS B2B local. Trecerea am făcut-o pe un proiect cu 4.500 de abonați activi și am tras câteva concluzii foarte clare legate de conversii, efort de dezvoltare și integrarea cu facturarea din România.
Stripe Checkout: Lansare în 2 ore, dar pierzi controlul pe UX
Checkout e opțiunea hosted de Stripe. Trimiți userul pe URL-ul lor securizat, omul introducă datele de card, plătește, iar Stripe îl redirecționează înapoi pe un success_url definit de tine.
Merge de minune la MVP-uri, aplicații B2C internaționale sau când n-ai chef să-ți bati capul cu frontend-ul. Se ocupă ei automat de 3D Secure 2, Apple Pay, Google Pay și adaptarea pe mobil. N-ai de scris decat un apel de backend care generază sesiunea.
De ce ne-am lovit noi în România? În B2B, firmele de la noi vor să introducă CUI-ul și adresa completă înainte de introducerea cardului, ca să fie sigure că prețul afișat conține sau nu TVA (sau că primesc factura pe firmă). Deși Stripe Checkout suportă colectarea de Tax ID, fluxul e destul de rigid. În plus, redirecționarea aia pe un domeniu extern (checkout.stripe.com) ne scădea conversia cu aproximativ 8% — unii useri credeau că s-a blocat aplicația sau că au ieșit din site din greșeală.
Stripe Elements: UX nativ, dar costă timp de dev
Elements îți oferă componente de UI ne-stilizate (sau pre-stilizate prin suita lor de teme) pe care le montezi direct în formularul tău de React, Vue sau JS chior. Userul rămâne pe domeniul tău de la cap la coadă.
Trade-off-ul e simplu: ai control total pe UX, dar preiei întreaga responsabilitate pentru stările formularului. Dintr-o dată trebuie să tratezi tu stările de loading, erorile de rețea, validarile locale și re-autentificarea 3D Secure direct din codul de frontend.
Pe proiectul nostru, migrarea de la Checkout la Elements ne-a luat 3 săptămâni pline de dev și QA. A trebuit să refacem complet fluxul de tratare a webhook-urilor pentru payment_intent.succeeded și invoice.payment_failed. Totuși, conversia pe pasul final a crescut cu 12% în prima lună. De ce? Am putut pune un pas intermediar în interfață unde validăm automat CUI-ul prin API-ul ANAF înainte ca userul să vadă câmpul de card.
Facturarea fiscală și integrarea cu SmartBill sau Oblio
Din punct de vedere al comisioanelor tranzacției, ambele soluții costă la fel la Stripe (1.5% + 1 RON pentru carduri europene standard).
Problematică e integrarea cu sistemele românești de facturare:
- La Checkout: Stripe colectează datele de facturare în forma lor standardizată. Dacă userul scrie greșit CUI-ul în câmpul nativ Stripe, trebuie să faci storno manual în SmartBill/Oblio și să-i ceri datele pe email.
- La Elements: Colectezi tu CUI-ul în formularul tău custom, îl validezi pe loc, îl salvezi în
metadatape PaymentIntent sau Customer, și abia apoi procesezi plata. Când vine webhook-ul de confirmare, trimiți datele deja curățate direct în softul de facturare.
Ce alegi în final?
Dacă ești la început de drum, ești B2C sau doar testezi un modul nou: folosește Stripe Checkout. Nu irosi două săptămâni să construiești un checkout nativ când încă n-ai dovedit că oamenii vor să plătească.
Dacă ești un SaaS B2B în România, ai deja venituri recurente și vrei să automatizezi complet emiterea de facturi pe firmă fără fricțiuni: treci pe Stripe Elements.
Voi ce soluție folosiți pe proiectele curente? Ați avut bătăi de cap cu validările de CUI la checkout-ul nativ?