Yeni·E-Ticaret Pro Paketi Yayında — Entegre Ödeme, Stok ve Sipariş YönetimiBlog·2025'te Küçük İşletmeler İçin Web Tasarım TrendleriKampanya·Mayıs Ayına Özel %20 İndirim — Kartvizit & Başlangıç Paketleriİçgörü·Müşteri Projelerinde Dönüşüm Oranı Ortalama %40 Artış SağlandıBlog·SEO'ya Yeni Başlayanlar İçin Temel Rehber — Ücretsiz İndirHaber·Ankara'da Yeni Çözüm Ortaklıkları ile Hizmet Ağı GenişliyorGüncelleme·Tüm Projeler İçin Ücretsiz SSL, CDN ve Hız Optimizasyonu DahilYeni·Çözümler Sayfası Açıldı — Sektöre Özel Web ÇözümleriKampanya·Ücretsiz Web Sitesi Değerlendirmesi — Bugün Başvurİçgörü·Ortalama Proje Teslim Süresi: 14 Gün — GarantiliYeni·E-Ticaret Pro Paketi Yayında — Entegre Ödeme, Stok ve Sipariş YönetimiBlog·2025'te Küçük İşletmeler İçin Web Tasarım TrendleriKampanya·Mayıs Ayına Özel %20 İndirim — Kartvizit & Başlangıç Paketleriİçgörü·Müşteri Projelerinde Dönüşüm Oranı Ortalama %40 Artış SağlandıBlog·SEO'ya Yeni Başlayanlar İçin Temel Rehber — Ücretsiz İndirHaber·Ankara'da Yeni Çözüm Ortaklıkları ile Hizmet Ağı GenişliyorGüncelleme·Tüm Projeler İçin Ücretsiz SSL, CDN ve Hız Optimizasyonu DahilYeni·Çözümler Sayfası Açıldı — Sektöre Özel Web ÇözümleriKampanya·Ücretsiz Web Sitesi Değerlendirmesi — Bugün Başvurİçgörü·Ortalama Proje Teslim Süresi: 14 Gün — Garantili
ilkkod
Türkiye Ödeme Sistemleri

Next.js ile İkas Headless E-Ticaret: GraphQL API ile Özel Mağaza Kurulumu

İkas GraphQL API ile Next.js headless mağaza kurun: OAuth 2.0 token akışı, ürün/sipariş query'leri, SSG ile ürün sayfaları, ISR ve webhook entegrasyonu. Türk geliştiriciler için pratik rehber.

İlker
25 Mart 2026
22 dk
Next.js ile İkas Headless E-Ticaret: GraphQL API ile Özel Mağaza Kurulumu

Önemli Not: Bu yazıdaki teknik bilgiler yazım tarihi itibarıyla geçerlidir. Kullanılan kütüphaneler, API'ler ve servisler zaman içinde değişebilir. Ücretlendirme, yasal düzenleme ve vergi konularında ilgili resmi kaynakları ve uzmanları referans alınız. Bu içerik bilgilendirme amaçlı olup herhangi bir finansal veya hukuki tavsiye niteliği taşımamaktadır.

Türkiye'de e-ticaret geliştiriyorsanız muhtemelen İkas'ı duymuşsunuzdur: 2026 itibarıyla 15.000'den fazla aktif mağazayla Türkiye'nin en hızlı büyüyen e-ticaret platformu. Peki İkas sadece "tıkla-aç" bir çözüm mü, yoksa geliştiriciler için de güçlü bir backend mi?

Bu rehberde İkas'ın GraphQL API'sini kullanarak Next.js 16 App Router üzerinde tam headless bir mağaza kurulumunu ele alacağız. OAuth 2.0 token akışından SSG ile statik ürün sayfalarına, ISR ile canlı katalog güncellemelerine ve webhook entegrasyonuna kadar her adımı TypeScript ile örnekleyeceğiz.


İkas Nedir? 2026 Türkiye E-Ticaret Ekosistemindeki Yeri

İkas, Türk girişimciler ve KOBİ'ler için tasarlanmış yerli bir e-ticaret SaaS platformudur. Shopify'a en yakın Türkçe alternatif olarak konumlanmaktadır. İkas'ı rakiplerinden ayıran birkaç kritik özellik var:

  • Yerleşik Trendyol ve Hepsiburada senkronizasyonu: Ayrı entegrasyon ücreti yok
  • Yerli ödeme gateway'leri: Türk bankalarıyla doğrudan anlaşmalar
  • GraphQL API: Geliştiriciler için tam headless mimari desteği
  • EUR bazlı fiyatlandırma: Güncel planlar için ikas.com adresini ziyaret edin

2026 sonuna kadar 30.000 mağaza hedefi olan İkas, geliştiriciye yönelik pivot yapıyor: resmi API dokümantasyonu (ikas.dev), Zapier MCP entegrasyonu ve GPT bağlantısı bunun somut göstergeleri.


Headless E-Ticaret Ne Demek? Ne Zaman Tercih Edilir?

Headless mimaride backend (ürün veritabanı, sipariş yönetimi, stok) ile frontend (kullanıcı arayüzü) birbirinden tamamen ayrılır. İkas backend görevi görürken, siz Next.js ile istediğiniz frontend'i inşa edersiniz.

Headless tercih etmeli misiniz?

SenaryoKarar
Standart mağaza, hızlı açılış❌ İkas tema editörü yeterli
Marka kimliğine özel tasarım✅ Headless
Yüksek performans hedefi (Core Web Vitals)✅ Headless
Harici sistem entegrasyonu (CRM, ERP)✅ Headless
Çoklu kanal (web + mobil + kiosk)✅ Headless
Küçük bütçe, geliştirici yok❌ Tema editörü

Proje Kurulumu

bun create next-app@latest ikas-headless --typescript --tailwind --app cd ikas-headless bun add graphql graphql-request bun add -d @graphql-codegen/cli @graphql-codegen/typescript

Ortam değişkenlerini ayarlayalım:

# .env.local IKAS_STORE_NAME="magazaadi" # myikas.com subdomain'i IKAS_CLIENT_ID="your_client_id" IKAS_CLIENT_SECRET="your_client_secret"

OAuth 2.0 ile Token Alma

İkas, client_credentials grant type kullanan OAuth 2.0 akışını uygular. Bir kullanıcı oturumu gerekmez; sunucudan sunucuya kimlik doğrulaması yapılır.

App Oluşturma

  1. İkas Dashboard → AppsMy AppsCreate Private App
  2. İzinleri seçin: read_products, write_products, read_orders, write_orders, read_customers, read_inventories, write_inventories
  3. Oluşturulan client_id ve client_secret'i kopyalayın

Token Servisi

Token geçerlilik süresi 14.400 saniye (4 saat)'tir. Her istekte yeni token almak yerine, süre dolmadan önce yenilemek performans açısından doğru yaklaşımdır:

// lib/ikas/auth.ts interface TokenCache { token: string expiresAt: number } let tokenCache: TokenCache | null = null export async function getIkasToken(): Promise<string> { const now = Date.now() // Cache'de geçerli token varsa kullan (30 saniye erken yenile) if (tokenCache && tokenCache.expiresAt - 30_000 > now) { return tokenCache.token } const storeName = process.env.IKAS_STORE_NAME! const response = await fetch( `https://${storeName}.myikas.com/api/admin/oauth/token`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ grant_type: "client_credentials", client_id: process.env.IKAS_CLIENT_ID!, client_secret: process.env.IKAS_CLIENT_SECRET!, }), }, ) if (!response.ok) { const error = await response.text() throw new Error(`İkas token alınamadı: ${response.status}${error}`) } const data = (await response.json()) as { access_token: string expires_in: number token_type: string } // 14.400 saniyelik geçerlilik süresi tokenCache = { token: data.access_token, expiresAt: now + data.expires_in * 1000, } return tokenCache.token }

GraphQL Client

İkas iki API versiyonu sunar:

  • v1: https://api.myikas.com/api/v1/admin/graphql (eski)
  • v2: https://api.myikas.com/api/v2/admin/graphql (önerilen)

v2'yi kullanacağız:

// lib/ikas/client.ts import { GraphQLClient } from "graphql-request" import { getIkasToken } from "./auth" const IKAS_GRAPHQL_URL = "https://api.myikas.com/api/v2/admin/graphql" export async function getIkasClient(): Promise<GraphQLClient> { const token = await getIkasToken() return new GraphQLClient(IKAS_GRAPHQL_URL, { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }) }

Temel GraphQL Query'leri

Ürün Listesi — listProduct

// lib/ikas/queries/products.ts import { gql } from "graphql-request" export const LIST_PRODUCTS_QUERY = gql` query ListProducts($page: Int, $limit: Int, $categoryId: String) { listProduct( pagination: { page: $page, limit: $limit } filter: { categoryId: { eq: $categoryId } } ) { data { id name slug description status images { id fileName originalFileName order } variants { id sku price { sellPrice buyPrice currency } stock { stockCount } weight } categories { id name } } pagination { totalCount currentPage pageSize } } } ` export interface IkasProduct { id: string name: string slug: string description: string | null status: "ACTIVE" | "PASSIVE" | "DRAFT" images: Array<{ id: string fileName: string originalFileName: string order: number }> variants: Array<{ id: string sku: string price: { sellPrice: number buyPrice: number currency: string } stock: { stockCount: number } weight: number | null }> categories: Array<{ id: string; name: string }> } export interface ListProductsResponse { listProduct: { data: IkasProduct[] pagination: { totalCount: number currentPage: number pageSize: number } } }

Sipariş Listesi — listOrder

// lib/ikas/queries/orders.ts import { gql } from "graphql-request" export const LIST_ORDERS_QUERY = gql` query ListOrders($page: Int, $status: String) { listOrder( pagination: { page: $page, limit: 20 } filter: { status: { eq: $status } } sort: { createdAt: DESC } ) { data { id orderNumber status totalPrice currency createdAt customer { id email firstName lastName } orderLineItems { id quantity price product { id name } variant { id sku } } shippingAddress { addressLine1 city country } } pagination { totalCount currentPage pageSize } } } `

Ürün Güncelleme — saveProduct

saveProduct mutation'ı hem oluşturma hem güncelleme işlemi yapar (upsert):

// lib/ikas/mutations/products.ts import { gql } from "graphql-request" export const SAVE_PRODUCT_MUTATION = gql` mutation SaveProduct($input: SaveProductInput!) { saveProduct(input: $input) { id name slug status } } ` export interface SaveProductInput { id?: string // varsa güncelleme, yoksa oluşturma name: string description?: string status: "ACTIVE" | "PASSIVE" | "DRAFT" variants: Array<{ id?: string sku: string price: { sellPrice: number buyPrice: number currency: string } stock: { stockCount: number } }> categoryIds?: string[] }

Kullanım Örneği

// lib/ikas/services/product-service.ts import { getIkasClient } from "../client" import { LIST_PRODUCTS_QUERY, type ListProductsResponse, } from "../queries/products" export async function fetchProducts(page = 1, limit = 20) { const client = await getIkasClient() const data = await client.request<ListProductsResponse>(LIST_PRODUCTS_QUERY, { page, limit, }) return data.listProduct } export async function fetchAllProductSlugs(): Promise<string[]> { const client = await getIkasClient() const allSlugs: string[] = [] let page = 1 let hasMore = true while (hasMore) { const data = await client.request<ListProductsResponse>( LIST_PRODUCTS_QUERY, { page, limit: 100 }, ) const { data: products, pagination } = data.listProduct allSlugs.push(...products.map((p) => p.slug)) hasMore = page * pagination.pageSize < pagination.totalCount page++ } return allSlugs }

SSG ile Ürün Sayfaları

Next.js 16 App Router ile tüm ürün sayfalarını build time'da statik olarak üretelim. Binlerce ürün için generateStaticParams mükemmel çalışır:

// app/urunler/[slug]/page.tsx import { notFound } from "next/navigation" import { fetchAllProductSlugs, fetchProductBySlug } from "@/lib/ikas/services/product-service" import type { Metadata } from "next" // Build time'da tüm ürün slug'larını üret export async function generateStaticParams() { const slugs = await fetchAllProductSlugs() return slugs.map((slug) => ({ slug })) } // Dinamik metadata export async function generateMetadata({ params, }: { params: Promise<{ slug: string }> }): Promise<Metadata> { const { slug } = await params const product = await fetchProductBySlug(slug) if (!product) return {} return { title: `${product.name} | Mağazamız`, description: product.description ?? `${product.name} ürününü inceleyin.`, openGraph: { images: product.images[0] ? [{ url: `https://cdn.myikas.com/images/${product.images[0].fileName}` }] : [], }, } } export default async function ProductPage({ params, }: { params: Promise<{ slug: string }> }) { const { slug } = await params const product = await fetchProductBySlug(slug) if (!product) notFound() const mainVariant = product.variants[0] const mainImage = product.images[0] return ( <main> <div> {mainImage && ( <img src={`https://cdn.myikas.com/images/${mainImage.fileName}`} alt={product.name} width={800} height={800} /> )} <div> <h1>{product.name}</h1> {product.description && <p>{product.description}</p>} {mainVariant && ( <p> {mainVariant.price.sellPrice.toLocaleString("tr-TR", { style: "currency", currency: mainVariant.price.currency, })} </p> )} </div> </div> </main> ) }

Next.js 16 Notu: params artık Promise<{}> tipindedir ve await ile çözülmelidir. Sync erişim Next.js 16'da tamamen kaldırılmıştır.


ISR ile Katalog Güncellemeleri

Yüzlerce veya binlerce ürününüz varsa hepsini her build'de yeniden üretmek verimsizdir. ISR (Incremental Static Regeneration) ile sayfaları arkaplanda yeniliyoruz:

// app/urunler/[slug]/page.tsx — ISR eklemesi // Next.js 16'da segment config export const revalidate = 3600 // 1 saatte bir yenile // VEYA dinamik revalidation için: // import { revalidatePath } from "next/cache" // Webhook geldiğinde çağrılır

Ürün sayfası listesi için:

// app/urunler/page.tsx export const revalidate = 1800 // 30 dakikada bir export default async function ProductsPage() { const { data: products, pagination } = await fetchProducts(1, 24) return ( <main> <h1>Ürünler</h1> <div> {products.map((product) => ( <a key={product.id} href={`/urunler/${product.slug}`}> {product.name} </a> ))} </div> </main> ) }

Webhook ile Anlık Güncelleme

ISR belirli aralıklarla yeniler; ancak ürün güncellemesi anında yansımasını istiyorsanız webhook kullanın.

Webhook Kaydetme

// scripts/register-webhook.ts import { getIkasClient } from "@/lib/ikas/client" import { gql } from "graphql-request" const SAVE_WEBHOOK_MUTATION = gql` mutation SaveWebhook($input: SaveWebhookInput!) { saveWebhook(input: $input) { id endpoint events } } ` async function registerWebhook() { const client = await getIkasClient() const result = await client.request(SAVE_WEBHOOK_MUTATION, { input: { endpoint: "https://siteniz.com/api/webhooks/ikas", events: ["PRODUCT_UPDATED", "PRODUCT_CREATED", "ORDER_CREATED"], }, }) console.log("Webhook kaydedildi:", result) } registerWebhook()

Webhook Handler

// app/api/webhooks/ikas/route.ts import { revalidatePath, revalidateTag } from "next/cache" import { NextRequest, NextResponse } from "next/server" interface IkasWebhookPayload { event: string data: { id: string slug?: string } } export async function POST(request: NextRequest) { let payload: IkasWebhookPayload try { payload = await request.json() } catch { return NextResponse.json({ error: "Geçersiz payload" }, { status: 400 }) } const { event, data } = payload switch (event) { case "PRODUCT_UPDATED": case "PRODUCT_CREATED": // Belirli ürün sayfasını yenile if (data.slug) { revalidatePath(`/urunler/${data.slug}`) } // Ürün listesini yenile revalidatePath("/urunler") revalidateTag("products") break case "ORDER_CREATED": // Sipariş bildirimi işle console.log("Yeni sipariş:", data.id) break default: console.log("Bilinmeyen event:", event) } return NextResponse.json({ received: true }) }

Trendyol ve Hepsiburada Entegrasyonu

İkas'ın Trendyol ve Hepsiburada entegrasyonu hakkında önemli bir not: bu entegrasyonlar developer API'si değil, İkas Admin Panel üzerinden çalışır.

Trendyol: İkas'tan Trendyol'a ürün push edilebilir. Stok ve fiyat senkronizasyonu otomatik yönetilir.

Hepsiburada: Hepsiburada'dan İkas'a ürün çekilebilir, ancak İkas'tan Hepsiburada'ya push yapılamaz. Bu önemli bir kısıtlamadır.

Sonuç: Trendyol/Hepsiburada senkronizasyonu için GraphQL API yazmanıza gerek yok — İkas dashboard'undaki entegrasyon ayarlarını yapılandırmanız yeterli. Sipariş akışı, stok güncellemeleri ve fiyat senkronizasyonu otomatik çalışır.


SEO: Ürün JSON-LD Şeması

Ürün sayfalarına yapılandırılmış veri ekleyerek arama motorlarında zengin sonuçlar (rich results) elde edebilirsiniz:

// components/ProductJsonLd.tsx import type { IkasProduct } from "@/lib/ikas/queries/products" interface ProductJsonLdProps { product: IkasProduct } export function ProductJsonLd({ product }: ProductJsonLdProps) { const mainVariant = product.variants[0] const mainImage = product.images[0] const jsonLd = { "@context": "https://schema.org", "@type": "Product", name: product.name, description: product.description, image: mainImage ? `https://cdn.myikas.com/images/${mainImage.fileName}` : undefined, sku: mainVariant?.sku, offers: mainVariant ? { "@type": "Offer", price: mainVariant.price.sellPrice, priceCurrency: mainVariant.price.currency, availability: mainVariant.stock.stockCount > 0 ? "https://schema.org/InStock" : "https://schema.org/OutOfStock", } : undefined, } return ( <script type="application/ld+json" // biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD şeması dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} /> ) }

İkas vs Shopify: Türkiye Pazarı için Teknik Karşılaştırma

Research verilerine dayanan güncel karşılaştırma:

KriterİkasShopify
API tipiGraphQL (Admin)GraphQL + REST
Kimlik doğrulamaOAuth 2.0 client_credentialsOAuth 2.0 (user flow)
TR marketplace entegrasyonuYerleşik (Trendyol, Hepsiburada, n11)3. parti uygulama gerekli
TR ödeme gatewayYerleşik banka entegrasyonlarıSınırlı
Fiyat para birimiEURUSD
Dokümantasyon kalitesiİyi (v2 önerilen)Mükemmel
Türk geliştirici topluluğuAz (büyüyor)Geniş (İngilizce)
Headless desteği✅ GraphQL API✅ Storefront API

Türkiye'de İkas'ı tercih etmeniz gereken durumlar:

  • Trendyol/Hepsiburada entegrasyonu öncelikliyse
  • Türk ödeme yöntemleri (yerli banka sanal POS) gerekiyorsa
  • Türk iş süreçleri (KDV, e-fatura) için yerli destek lazımsa

Shopify'ı tercih etmeniz gereken durumlar:

  • Uluslararası satış hedefleniyorsa
  • Daha zengin uygulama ekosistemi gerekiyorsa
  • İngilizce kaynaklar ve büyük topluluk önemliyse

Ne Zaman İkas, Ne Zaman Custom Backend?

İkas API kullanın:
├── Türk marketplace senkronizasyonu gerekiyor
├── Ödeme altyapısı hızla kurulacak
├── Ürün/sipariş yönetimi İkas üzerinde kalacak
└── Müşteri İkas admin panelini kullanacak

Custom backend yazın:
├── Çok özel iş mantığı var (karmaşık fiyatlandırma, üyelik sistemi)
├── Mevcut ERP/CRM ile derin entegrasyon gerekiyor
├── İkas'ın veri modeliyle uyumsuzluk var
└── Tam veri sahipliği ve taşınabilirlik kritik

Production Kontrol Listesi

  • Token cache mekanizması aktif (gereksiz token istekleri önlenir)
  • API v2 endpoint kullanılıyor (api.myikas.com/api/v2/admin/graphql)
  • IKAS_CLIENT_SECRET sadece server-side kod ve ortam değişkenlerinde
  • Rate limit handling: API hata yanıtları için retry mantığı
  • ISR revalidation süreleri belirlendi
  • Webhook endpoint'i güvenliğe alındı (opsiyonel imza doğrulama)
  • generateStaticParams ile kritik ürün sayfaları build time'da üretiliyor
  • Ürün resimleri için next/image ve uygun sizes prop kullanılıyor
  • Hata durumları ele alındı: notFound(), try-catch blokları
  • Türkçe karakter testleri yapıldı (ürün adları, kategoriler)
  • Trendyol/Hepsiburada entegrasyonu İkas dashboard'undan yapılandırıldı

Sıkça Sorulan Sorular

İkas API için ücret ödeniyor mu?

API erişimi İkas plan aboneliğinize dahildir; ayrı API ücreti alınmaz. Hangi planın API erişimini içerdiğini öğrenmek için ikas.com adresindeki güncel plan bilgilerini inceleyin.

OAuth token ne kadar süre geçerli?

expires_in değeri 14.400 saniye (4 saattir). Token cache mekanizması kullanarak her GraphQL isteğinde yeni token almaktan kaçının. Kod örneğimizde 30 saniye erken yenileme stratejisi uyguladık.

İkas GraphQL v1 mi v2 mi kullanmalıyım?

v2'yi kullanın. https://api.myikas.com/api/v2/admin/graphql adresindeki v2, daha güncel ve önerilen endpoint'tir. v1 eski projeler için destekleniyor olsa da yeni geliştirmelerde v2 başlayın.

Trendyol siparişlerini API ile çekebilir miyim?

Hayır. Trendyol/Hepsiburada entegrasyonu İkas Admin Panel üzerinden çalışır ve developer API'si sunmaz. Siparişler İkas'a otomatik aktarılır; siz listOrder query'si ile İkas üzerindeki tüm siparişlere (Trendyol kaynaklı dahil) erişebilirsiniz.

saveProduct ile mevcut ürünü güncelleyebilir miyim?

Evet. saveProduct bir upsert mutation'dır: id alanı geçerseniz güncelleme yapar, geçmezseniz yeni ürün oluşturur. Toplu güncelleme için bulkUpdateProducts mutation'ını kullanabilirsiniz.

Webhook güvenliğini nasıl sağlarım?

İkas webhook gönderdiğinde endpoint'inizi kamuya açık bırakmak zorundasınız. Güvenlik için webhook handler'ınıza bir secret key doğrulaması ekleyebilirsiniz: İkas'tan gelen isteklerin belirli bir header içermesini bekleme stratejisi uygulanabilir. Detaylar için ikas.dev dokümantasyonunu inceleyin.

ISR ve webhook'u birlikte mi kullanmalıyım?

Kullanım senaryonuza bağlı: Ürünleriniz sık değişmiyorsa ISR (1 saat revalidation) yeterlidir. Fiyat/stok anlık yansıması kritikse webhook + revalidatePath kombinasyonunu kullanın. İkisini birden kullanmak en güvenli yaklaşımdır.


Sonuç

İkas, Next.js geliştiricileri için güçlü bir headless backend alternatifi sunuyor. OAuth 2.0 ile güvenli kimlik doğrulama, kapsamlı GraphQL API'si ve yerleşik Türk marketplace entegrasyonlarıyla Türkiye pazarına yönelik e-ticaret projelerinde ciddi bir tercih nedenine sahip.

Bu rehberde ele aldığımız:

  • OAuth 2.0 client_credentials akışı ve token cache
  • GraphQL v2 ile listProduct, listOrder, saveProduct örnekleri
  • Next.js 16 App Router ile SSG ürün sayfaları
  • ISR ile otomatik katalog yenileme
  • Webhook ile anlık güncelleme
  • Trendyol/Hepsiburada entegrasyonunun dashboard üzerinden çalıştığı bilgisi
  • İkas vs Shopify teknik karşılaştırması

Headless İkas projelerinizde karmaşık bir mimari planlamanız gerekiyorsa veya mevcut bir Next.js projesine İkas entegrasyonu eklemek istiyorsanız iletişime geçin — e-ticaret altyapısı konusunda deneyimli bir geliştirici olarak yardımcı olmaktan memnuniyet duyarım.

Paylaş: