Stripe Checkout rahatdır, lakin bəzən ödəniş formasının saytınızın bir hissəsi olması lazım olur: eyni şriftlər və rənglər, yad ünvana keçid olmadan. Bunun üçün Payment Element var — Stripe-ın hazır qorunan sahələri, onları öz səhifənizə yerləşdirirsiniz. Onu mağazaya qoşacağıq: serverdə PaymentIntent yaradacağıq, brauzerə onun client_secret-ini verəcəyik, ödənişi stripe.confirmPayment ilə təsdiqləyəcəyik, statuslara, 3-D Secure-a və kart xətalarına baxacağıq və nəticəni yenə webhook-a etibar edəcəyik.

Checkout, yoxsa öz formanız

Checkout (dərs 039) — Stripe-ın hazır səhifəsi: ən sadə və ən sürətli yol. Payment Element — sizin səhifənizdəki forma: sahənin ətrafındakı dizaynı və mətni özünüz qurursunuz, kartın nömrəsi isə Stripe-ın qorunan iframe-ində daxil edilir və serverinizə düşmür (SAQ A, dərs 038). Azadlığın qiyməti koddur: düyməni, xətaları və 3-D Secure-dan sonrakı qayıdışı özünüz yazırsınız.

ÜsulKart harada daxil edilirKod
Checkout (hosted_page)Stripe səhifəsindəən az
Embedded Checkout (embedded_page)səhifənizdəki Stripe iframe-indəaz
Payment Element + Checkout Sessions (ui_mode: 'elements')dizaynınızdakı Stripe sahələriorta
Payment Element + PaymentIntentdizaynınızdakı Stripe sahələriən çox

💡 Stripe-ın tövsiyəsi barədə dürüst qeyd. İndi (2026-cı ilin oktyabrı) Stripe sənədləri yeni inteqrasiyaların əksəriyyəti üçün Payment Element ilə Checkout Sessions-ı məsləhət görür: ui_mode: 'elements', React-də @stripe/react-stripe-js/checkout-dan CheckoutElementsProvider və checkout.confirm. Kod azdır, vergi və endirimlər hazırdır. Biz PaymentIntent-i öyrənirik: o, Checkout-un da altında durur, ona görə statuslar, client_secret və webhook-lar hər iki yolda eynidir.

PaymentIntent: bir ödənişin «qovluğu»

PaymentIntent — bir ödənişi niyyətdən nəticəyə qədər aparan Stripe obyektidir: məbləğ, valyuta, ödəniş üsulu, status, xətalar. Bənzətmə: iş qovluğu. Məbləğ məlum olanda qovluğu açırsınız, müştəri ora kartını qoyur, Stripe nə baş verdiyini yazır. Alınmasa, qovluq qalır və müştəri yenidən cəhd edir.

Qovluqla birlikdə Stripe client_secret verir — məhz onun açarı. Onunla brauzer bu ödənişi təsdiqləyə bilər, lakin məbləği dəyişə və başqalarının ödənişlərini görə bilməz. Bu, serveri tərk etməyən sk_… gizli açarı deyil; lakin client_secret-i də yalnız bu sifarişin alıcısı görür: onu log-a yazmırlar və URL-ə qoymurlar.

Payment Element ardıcıllığı: brauzer PaymentIntent istəyir, server onu yaradıb client_secret qaytarır, kart iframe-dən birbaşa Stripe-a gedir, sonra 3-D Secure, brauzerdə status və serverə webhook
Payment Element ardıcıllığı: brauzer PaymentIntent istəyir, server onu yaradıb client_secret qaytarır, kart iframe-dən birbaşa Stripe-a gedir, sonra 3-D Secure, brauzerdə status və serverə webhook

1–3-cü addımlar: server PaymentIntent yaradır və brauzerə yalnız client_secret qaytarır. 4–5-ci addımlar: stripe.confirmPayment kart məlumatlarını iframe-dən birbaşa Stripe-a göndərir, lazım olsa Stripe.js 3-D Secure pəncərəsini açır. 6–7-ci addımlar: brauzer nəticəni öyrənir, əsl təsdiq isə webhook ilə gəlir.

Addım 1. Server PaymentIntent yaradır

Order-ə əlaqə üçün sahə əlavə edək (npx prisma migrate dev --name add_payment_intent_id):

prisma
model Order {
  // id, sku, quantity, total, status, stripeSessionId: as before
  stripePaymentIntentId String? @unique
}