Checkout sayfası, gelirin gerçekleştiği ya da öldüğü yerdir. Başka her sayfada kötü bir karar sana bir tıklama kaybettirir; checkout’ta bir siparişi kaybettirir. Headless WooCommerce’de ise bunu sıfırdan oluşturuyorsun — varsayılan WooCommerce checkout şablonu yok, önceden hazır ödeme formu yok, otomatik kargo hesaplama yok. Açık konuşayım: bu, headless’a geçmenin hem en büyük zorluğu hem de en büyük fırsatı. Zorluk, çünkü güvenlik ağı sende değil; fırsat, çünkü dönüşümü ısıran her sürtünme noktasına artık sen karar veriyorsun.
Motoru sahneden ayırmak: aslında ne yapıyorsun
İzin ver de sektörün dinozoru bir dakika araya girsin, çünkü headless kelimesi kulağa yeni geliyor ama altındaki fikir hiç değil. Yıllarca Macromedia Director’da multimedya projeleri kurdum. Director’ın güzelliği tam olarak buydu: sahne (stage) bir şeydi, cast — yani varlıkların ve davranışların kütüphanesi — bambaşka bir şeydi, ve Lingo ile mantığı ikisinden de ayrı tutardın. Sunumu değiştirmek için motoru elleme; motoru değiştirmek için sahneyi yeniden çizme. O ayrımı bir kez tattığında geri dönemezdin.
Headless WooCommerce tam olarak aynı ayrım, sadece isimleri değişmiş. WooCommerce artık motor — sepet, vergi, kargo, sipariş, ödeme mutabakatı. Next.js ön yüzün ise sahne. İkisi arasındaki tek sözleşme API. Bu yüzden checkout’u “zor” yapan şey aslında dağınıklık değil, disiplin: sunum katmanında iş mantığı yazmaya başladığın an — vergiyi tarayıcıda hesaplamak, stok kararını istemcide vermek — Director’da Lingo’yu sahnenin üstüne saçmak gibi olur. Bir süre çalışır, sonra bakımı imkânsız hâle gelir. Kural basit: karar motorda kalır, sahne sadece gösterir.
Checkout Mimarisi
Headless checkout tipik olarak 3-4 adımdan oluşur ve tümü API aracılığıyla WooCommerce ile iletişim kurar:
Cart Review → Shipping Info → Payment → Confirmation
Store API WC REST API Stripe/ WC REST API
(cart) (shipping) PayPal JS (create order)
WooCommerce Store API ile Sepet Yönetimi
WooCommerce Store API (WooCommerce 6.0+ ile dahil) headless kullanım için tasarlanmış sepet endpoint’leri sağlar:
// Cart state management (Next.js)
const STORE_API = ${process.env.WP_URL}/wp-json/wc/store/v1;
export async function getCart(nonce) {
const res = await fetch(${STORE_API}/cart, {
credentials: 'include',
headers: { 'Nonce': nonce }
});
return res.json();
}
export async function addToCart(productId, quantity, nonce) {
const res = await fetch(${STORE_API}/cart/add-item, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Nonce': nonce
},
body: JSON.stringify({ id: productId, quantity })
});
return res.json();
}
export async function applyCoupon(code, nonce) {
const res = await fetch(${STORE_API}/cart/apply-coupon, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Nonce': nonce
},
body: JSON.stringify({ code })
});
return res.json();
}
Önemli: Store API sepet oturumu yönetimi için nonce kullanır. Bunu wc/store/v1/cart yanıt başlığı Nonce‘den al. Bir uyarı: nonce süre dolumu ve oturum çerezi, headless kurulumda en çok baş ağrıtan yerdir — sepet sessizce boşalıyorsa, ilk şüphelenmen gereken şey nonce’ın tazelenip tazelenmediği.
Kargo Hesaplama
WooCommerce, müşterinin adresine göre kargoyu sunucu tarafında hesaplar — ve bunu böyle yapması iyi bir şey, çünkü kargo bölgesi ve vergi kuralları tam olarak motorda kalması gereken kararlardır:
export async function updateShippingAddress(address, nonce) {
const res = await fetch(${STORE_API}/cart/update-customer, {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Nonce': nonce
},
body: JSON.stringify({
shipping_address: {
first_name: address.firstName,
last_name: address.lastName,
address_1: address.address1,
city: address.city,
state: address.state,
postcode: address.postcode,
country: address.country
}
})
});
const cart = await res.json();
// cart.shipping_rates contains available methods with costs
return cart;
}
Yanıt, seçenek olarak gösterdiğin hesaplanmış kargo tarifelerini içerir.
Ödeme Entegrasyonu: Stripe
Stripe, headless WooCommerce için en yaygın ödeme gateway’idir. PCI uyumlu kart toplama için Stripe Elements kullan — kart numarası hiçbir zaman senin sunucuna uğramaz, doğrudan Stripe’a gider ve sen sadece bir token görürsün:
import { loadStripe } from '@stripe/stripe-js';
import { Elements, CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PK);
function CheckoutForm({ cart }) {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (e) => {
e.preventDefault();
// 1. Create payment intent on your server
const { clientSecret } = await fetch('/api/create-payment-intent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ amount: cart.totals.total_price })
}).then(r => r.json());
// 2. Confirm payment with Stripe
const { error, paymentIntent } = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement),
billing_details: { name: cart.billing_address.first_name }
}
});
if (error) {
setError(error.message);
return;
}
// 3. Create WooCommerce order
if (paymentIntent.status === 'succeeded') {
await createWooCommerceOrder(cart, paymentIntent.id);
}
};
return (
);
}
WooCommerce Siparişi Oluşturma
Başarılı ödemeden sonra, WooCommerce REST API aracılığıyla sipariş oluşturun:
async function createWooCommerceOrder(cart, paymentIntentId) {
const orderData = {
payment_method: 'stripe',
payment_method_title: 'Credit Card (Stripe)',
set_paid: true,
transaction_id: paymentIntentId,
billing: cart.billing_address,
shipping: cart.shipping_address,
line_items: cart.items.map(item => ({
product_id: item.id,
variation_id: item.variation?.[0]?.attribute || undefined,
quantity: item.quantity
})),
shipping_lines: [{
method_id: cart.shipping_rates[0]?.rate_id,
method_title: cart.shipping_rates[0]?.name,
total: cart.shipping_rates[0]?.price
}],
coupon_lines: cart.coupons.map(c => ({ code: c.code })),
meta_data: [
{ key: '_stripe_payment_intent', value: paymentIntentId }
]
};
const response = await fetch(${WP_URL}/wp-json/wc/v3/orders, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': Basic ${btoa(${CK}:${CS})}
},
body: JSON.stringify(orderData)
});
return response.json();
}
Burada açık konuşmam gereken bir nokta var, çünkü çok kişinin ayağı buraya takılıyor. Bu createWooCommerceOrder çağrısı, WooCommerce consumer key ve secret (CK/CS) ile kimlik doğruluyor. O anahtarlar asla tarayıcıya inmemeli — btoa(CK:CS) istemci kodunda çalışırsa, mağazanın tüm REST API’sini herkese açmış olursun. Bu fonksiyonu bir sunucu tarafı route’ta (Next.js API route ya da edge function) çalıştır; ön yüz yalnızca kendi backend’ini çağırsın, WooCommerce’i doğrudan değil. Aynı Director dersi: karar ve sır motorda kalır, sahnede değil.
Checkout UX En İyi Uygulamaları
- Tek sayfalık checkout çoğu mağaza için çok aşamalıdan daha iyi performans gösterir. Ayrı sayfalar yerine akordeon bölümleri kullan.
- Adres otomatik tamamlama Google Places API aracılığıyla sürtünmeyi ve hataları azaltır.
- Gerçek zamanlı doğrulama — alanları gönderimde değil, blur’da doğrula.
- Varsayılan olarak misafir checkout — satın almadan önce hesap oluşturmayı zorlama.
- Sipariş özeti her zaman görünür — masaüstünde sepet özetini kenar çubuğunda göster.
- Hızlı checkout düğmeleri — Apple Pay, Google Pay ve PayPal’ı sayfa üstünde.
Hata Yönetimi
Checkout hataları müşteri kaybettirir. Her başarısızlığı zarif bir şekilde ele al — ve kullanıcının anlayacağı dilde, “processing_error” gibi bir kodu ekrana basmadan:
const ERROR_MESSAGES = {
'card_declined': 'Your card was declined. Please try another card.',
'insufficient_funds': 'Insufficient funds. Please try another payment method.',
'expired_card': 'Your card has expired. Please update your card details.',
'processing_error': 'A processing error occurred. Please try again.',
'stock_error': 'Some items in your cart are no longer available.',
'shipping_error': 'We cannot ship to this address. Please check your details.'
};
Sonuç
Headless checkout, headless WooCommerce yapısının en zor kısmıdır, ancak müşteri deneyimi üzerinde en fazla kontrole sahip olduğun yer de burası. Sepet yönetimi için WooCommerce Store API’sını, PCI uyumlu ödemeler için Stripe Elements’i kullan, sırları sunucu tarafında tut ve sürtünmeyi azaltmaya amansızca odaklan. Her ek alan, her gereksiz sayfa yüklemesi, her kafa karıştıran hata mesajı dönüşümlere mal olur. Yalın yap, gerçek kullanıcılarla test et ve yinele. Motoru sahneden temiz ayırdığın sürece, ön yüzü istediğin kadar cesur tasarlayabilirsin — arkadaki WooCommerce sağlam durduğu müddetçe.
Last modified: Ağustos 2, 2026
United States / English
Slovensko / Slovenčina
Canada / Français
Türkiye / Türkçe