# trkit dokümantasyonu (tamamı) > Tek komutla Türkçe Next.js projesi: KVKK, çerez onayı, il/ilçe, TCKN/IBAN doğrulama, iyzico/PayTR, Netgsm ve AI asistanları için hazır kurallar. Kaynak: https://zersjs.github.io/trkit/docs — Bu dosya AI asistanlarına bağlam olarak verilmek üzere hazırlanmıştır. --- # trkit nedir? URL: https://zersjs.github.io/trkit/docs/index.md > Türk geliştiriciler için hazır Next.js altyapısı. Her projede yeniden yazdığınız yerel ihtiyaçları tek komutla kurar. trkit, Next.js'in Türkiye için ayarlanmış hâlidir. Yeni bir proje açtığınızda Türkçe varsayılanlar, KVKK sayfaları, çerez onayı, il/ilçe seçici, TCKN/IBAN doğrulama ve TL/tarih biçimlendirme hazır gelir. E-ticaret şablonunda iyzico/PayTR ödeme ve Netgsm SMS altyapısı da eklenir. ```bash npx create-trkit-app@latest benim-sitem ``` ### Neden? Türkiye'de web projesi geliştiren herkes aynı işleri tekrar tekrar yapıyor: - KVKK aydınlatma metni, açık rıza, çerez politikası, mesafeli satış sözleşmesi sayfalarını başka bir siteden kopyalayıp düzenlemek - İl/ilçe listesi için JSON aramak, seçici bileşeni baştan yazmak - TCKN, VKN ve IBAN doğrulama algoritmalarını internetten bulmak - iyzico ve PayTR'nin imza ve bildirim (callback) akışını her seferinde yeniden çözmek - `toUpperCase()` ile "istanbul"un "ISTANBUL" olması, sunucunun UTC saatiyle yanlış gün göstermesi gibi Türkçeye özgü hatalar trkit bunları test edilmiş, versiyonlanmış paketler ve projenize kopyalanan, düzenleyebileceğiniz bileşenler olarak sunar. ### Neler var? | | | |---|---| | **create-trkit-app** | Tek komutla Türkçe Next.js projesi | | **trkit CLI** | `npx trkit add kvkk` gibi komutlarla mevcut projeye bileşen ve sayfa ekleme | | **@trkit-app-pack/validate** | TCKN, VKN, IBAN, telefon, plaka; Türkçe zod mesajları | | **@trkit-app-pack/format** | TL, İstanbul saatiyle tarih, göreli zaman, tutarı yazıya çevirme, hâl ekleri | | **@trkit-app-pack/address** | 81 il, 973 ilçe, Türkçe duyarsız arama | | **@trkit-app-pack/legal** | 8 yasal metin şablonu, çerez onayı ve onay kayıtları | | **@trkit-app-pack/pay** | iyzico, PayTR, test için mock | | **@trkit-app-pack/sms** | Netgsm, İYS filtresi, OTP | | **@trkit-app-pack/mcp** | AI asistanları için MCP sunucusu | ### AI ile geliştiriyorsanız Oluşturulan her projede `AGENTS.md`, `CLAUDE.md`, Cursor kuralları ve MCP ayarları bulunur. Claude Code, Cursor, Codex veya ChatGPT'ye "bu siteye iyzico ile ödeme ekle" dediğinizde asistan trkit'in kurallarına uygun kod yazar. Ayrıntılar: [AI ile geliştirme](/docs/ai). Bu dokümantasyonun tamamı AI asistanlarına verilmek üzere [llms-full.txt](/llms-full.txt) olarak da hazırdır. ### Yol haritası trkit şu an 0.1 sürümünde. Planlanan e-Fatura/e-Arşiv, kargo, ödemede 3D Secure ve abonelik, mahalle verisi, NVİ ile kimlik doğrulama, İYS entegrasyonu ve hazır uygulama şablonları için [yol haritasına](https://github.com/zersjs/trkit/blob/main/ROADMAP.md) bakın. ### Hukuki uyarı trkit'in yasal metinleri ilgili mevzuata (6698, 6502, 6563 sayılı Kanunlar ve ilgili yönetmelikler) dayanan **şablonlardır** ve hukuki danışmanlık yerine geçmez. Yayına almadan önce işletmenize özgü veri işleme faaliyetlerine göre bir avukata kontrol ettirin. --- # Kurulum URL: https://zersjs.github.io/trkit/docs/kurulum.md > create-trkit-app ile tek komutla Türkçe Next.js projesi oluşturun. ### Gereksinimler - Node.js 20.9 veya üzeri - npm, pnpm, yarn veya bun ### Yeni proje ```bash npx create-trkit-app@latest benim-sitem ``` Komut size proje adını ve şablonu sorar, dosyaları oluşturur, bağımlılıkları kurar ve bir git deposu başlatır. Ardından: ```bash cd benim-sitem npm run dev ``` Tarayıcıda [http://localhost:3000](http://localhost:3000) adresini açın. Diğer paket yöneticileriyle: ```bash pnpm create trkit-app benim-sitem yarn create trkit-app benim-sitem bun create trkit-app benim-sitem ``` ### Şablonlar | Şablon | İçerik | |---|---| | `minimal` | Türkçe temel, KVKK aydınlatma metni, çerez politikası ve onay banner'ı, il/ilçe seçici, örnek iletişim formu | | `kurumsal` (varsayılan) | Minimal + açık rıza metni, KVKK başvuru formu, ticari ileti onayı, il/ilçe arama | | `eticaret` | Kurumsal + mesafeli satış sözleşmesi, ön bilgilendirme formu, teslimat-iade koşulları, iyzico/PayTR ödeme, ödeme onay kutuları, SMS ve OTP | ```bash npx create-trkit-app@latest magaza --sablon eticaret ``` ### Seçenekler | Seçenek | Açıklama | |---|---| | `--sablon ` | `minimal`, `kurumsal` veya `eticaret` | | `--use-npm`, `--use-pnpm`, `--use-yarn`, `--use-bun` | Paket yöneticisini seçer (varsayılan: komutu çalıştırdığınız yönetici) | | `--no-install` | Bağımlılıkları kurmaz | | `--no-git` | Git deposu oluşturmaz | | `-y`, `--yes` | Soru sormadan varsayılanlarla ilerler (CI ve AI ajanları için) | > AI ajanına proje oluşturtuyorsanız `--yes` ile çalıştırın; etkileşimli sorular ajanı bekletir. ### İlk yapılacaklar 1. `src/trkit.config.ts` dosyasında şirket bilgilerinizi (unvan, MERSİS, adres, telefon, e-posta) doldurun. 2. Eksikleri kontrol edin: ```bash npx trkit check ``` 3. `.env.example` dosyasını `.env.local` olarak kopyalayın ve değerleri girin. 4. Yayına almadan önce [kontrol listesini](/docs/rehber/yayina-alma) gözden geçirin. ### Mevcut bir projeniz mi var? create-trkit-app yerine trkit CLI ile parça parça ekleyebilirsiniz: [Mevcut projeye ekleme](/docs/mevcut-projeye-ekleme). --- # Proje yapısı URL: https://zersjs.github.io/trkit/docs/proje-yapisi.md > create-trkit-app ile oluşturulan projedeki dosyalar ve ne işe yaradıkları. ```text benim-sitem/ ├── AGENTS.md # AI asistanları için proje kuralları ├── CLAUDE.md # Claude Code (AGENTS.md'yi içe aktarır) ├── .mcp.json # Claude Code için trkit MCP sunucusu ├── .cursor/ │ ├── mcp.json # Cursor için trkit MCP sunucusu │ └── rules/trkit.mdc # Cursor kuralları ├── .vscode/mcp.json # VS Code (Copilot) için trkit MCP sunucusu ├── .env.example ├── src/ │ ├── trkit.config.ts # Şirket bilgileri; yasal metinler buradan üretilir │ ├── app/ │ │ ├── layout.tsx # lang="tr", font, çerez onayı, header/footer │ │ ├── page.tsx │ │ ├── not-found.tsx # Türkçe 404 │ │ ├── error.tsx # Türkçe hata sayfası │ │ ├── iletisim/ # Örnek form: server action + zod + il/ilçe │ │ ├── kvkk/ # Yasal sayfalar (şablona göre değişir) │ │ ├── cerez-politikasi/ │ │ ├── api/consent/ # Çerez onay kayıtları │ │ ├── robots.ts │ │ └── sitemap.ts │ ├── components/ │ │ ├── site-header.tsx │ │ ├── site-footer.tsx # Yasal bağlantılar + "Çerez Tercihleri" │ │ └── trkit/ # trkit bileşenleri (sizin kodunuz, düzenleyebilirsiniz) │ └── lib/ │ ├── site.ts # Site adı, menü ve footer bağlantıları │ └── zod.ts # Türkçe hata mesajlı zod └── package.json ``` trkit CLI dizin yollarını (`src/app`, `src/components`, import takma adı) projeden otomatik algılar. Farklı bir düzen kullanıyorsanız `npx trkit init` ile oluşan `trkit.json` dosyasında değiştirebilirsiniz. ### İki tür kod **npm paketleri** (`@trkit-app-pack/validate`, `@trkit-app-pack/format`, `@trkit-app-pack/legal`…): Mantık ve veri. Güncellemeleri `npm update` ile alırsınız. Örneğin mevzuat değiştiğinde yasal metin şablonları yeni sürümle güncellenir. **Kopyalanan bileşenler** (`src/components/trkit/`, yasal sayfalar, `src/lib/pay.ts`…): shadcn/ui'daki gibi projenize kopyalanır, size aittir. Tasarımı ve davranışı istediğiniz gibi değiştirebilirsiniz. ### `src/lib/zod.ts` zod'un hata mesajlarını Türkçe yapar. Şemalarınızda zod'u doğrudan değil buradan içe aktarın: ```ts import { z } from "@/lib/zod"; z.string().min(3).parse("a"); // "En az 3 karakter olmalıdır" ``` ### `src/lib/site.ts` Site adı, açıklaması, üst menü ve footer'daki yasal bağlantılar burada. Yeni bir yasal sayfa eklediğinizde (`npx trkit add mesafeli-satis`) bağlantısını `legal` dizisine ekleyin. --- # trkit CLI URL: https://zersjs.github.io/trkit/docs/cli.md > Bileşen ve sayfa ekleme, yasal metinleri kontrol etme ve dışa aktarma komutları. Projede `@trkit-app-pack/cli` geliştirme bağımlılığı olarak kuruludur; `npx trkit` ile çalıştırılır. ### `trkit list` Eklenebilecek tüm öğeleri listeler. ```bash npx trkit list ``` | Öğe | Tür | Açıklama | |---|---|---| | `kvkk`, `acik-riza`, `cerez-politikasi`, `mesafeli-satis`, `on-bilgilendirme`, `teslimat-iade`, `ticari-ileti`, `kvkk-basvuru` | Sayfa | Tek bir yasal sayfa | | `yasal` | Sayfa | Tüm yasal sayfalar | | `cerez-banner` | Bileşen | Çerez onay banner'ı, `ConsentGate`, onay kayıt uç noktası | | `il-ilce-secici` | Bileşen | Bağımlı il/ilçe ` {/* defaultChecked YOK */} Alışveriş tercihlerime göre kişiselleştirilmiş kampanyalar sunulması için verilerimin işlenmesine{" "} Açık Rıza Metni kapsamında onay veriyorum. (İsteğe bağlı) ``` #### 5. Onayları kaydedin Açık rızanın varlığını ispat yükü sizdedir. Kayıtları ekleme-tabanlı (silinmeyen, güncellenmeyen) bir tabloda tutun: ```ts import { createConsentRecord, generate, documentHash } from "@trkit-app-pack/legal"; import config from "@/trkit.config"; const { document } = generate("acik-riza", config); const record = await createConsentRecord({ subjectId: user.id, purpose: "kvkk:acik-riza", granted: true, document: `acik-riza@${document.templateVersion}`, documentHash: await documentHash(document), // kullanıcının gördüğü metnin özeti source: "kayit-formu", ip, salt: process.env.CONSENT_SALT!, // ham IP saklanmaz }); await db.insert(consents).values(record); ``` #### 6. Çerezler Ayrıntılar: [Çerez onayı](/docs/rehber/cerez). ### Sık yapılan hatalar - Aydınlatma metnini onay kutusuna bağlamak - Sözleşme gereği işlenen veri için açık rıza istemek (rıza geri alınınca hizmeti veremezsiniz) - Yurt dışı servisleri aydınlatma metninde belirtmemek - Tüm onayları tek bir kutuda toplamak ("KVKK, ticari ileti ve sözleşmeyi onaylıyorum") - Onay kayıtlarını tutmamak veya üzerine yazmak --- # Çerez onayı URL: https://zersjs.github.io/trkit/docs/rehber/cerez.md > KVKK Çerez Uygulamaları Rehberi'ne uygun çerez banner'ı, script yükleme ve onay kaydı. ### Kurallar (özet) KVKK'nın Çerez Uygulamaları Hakkında Rehberi'ne göre: - **Zorunlu çerezler** (oturum, sepet, güvenlik, tercih kaydı) için açık rıza gerekmez. - **Analitik, pazarlama ve çoğu fonksiyonel çerez** için açık rıza gerekir ve bu çerezler **onaydan önce yerleştirilemez**. - "Reddet" seçeneği "Kabul et" kadar kolay erişilebilir olmalıdır. - Kutular önceden işaretli olamaz. - Kullanıcı tercihini her zaman değiştirebilmelidir. ### Kurulum ```bash npx trkit add cerez-banner cerez-politikasi ``` ```tsx title="app/layout.tsx" import { CookieConsentProvider } from "@/components/trkit/cerez-banner"; {children} ``` Footer'a tercih bağlantısı ekleyin: ```tsx import { CookiePreferencesLink } from "@/components/trkit/cerez-banner"; ``` ### Script'leri onaya bağlamak ```tsx title="app/layout.tsx" import Script from "next/script"; import { ConsentGate } from "@/components/trkit/cerez-banner"; {children} {/* Meta Pixel, TikTok Pixel... */} ``` Bir bileşen içinde: ```tsx "use client"; import { useCookieConsent } from "@/components/trkit/cerez-banner"; const { allowed } = useCookieConsent(); if (allowed("analitik")) { /* ... */ } ``` Sunucu tarafında (ör. middleware/proxy veya server component): ```ts import { cookies } from "next/headers"; import { parseCookieConsent, isAllowed, COOKIE_CONSENT_NAME } from "@trkit-app-pack/legal"; const state = parseCookieConsent((await cookies()).get(COOKIE_CONSENT_NAME)?.value, "1"); isAllowed(state, "pazarlama"); // false ``` ### Çerez listesini güncel tutun Kullandığınız her çerezi `trkit.config.ts`'e ekleyin; çerez politikası sayfası bu listeden üretilir: ```ts cerezler: [ { ad: "trkit_consent", saglayici: "Birinci taraf", amac: "Çerez tercihlerinin saklanması", sure: "6 ay", kategori: "zorunlu" }, { ad: "_ga, _ga_*", saglayici: "Google", amac: "Ziyaret istatistikleri", sure: "2 yıl", kategori: "analitik" }, { ad: "_fbp", saglayici: "Meta", amac: "Reklam ölçümü", sure: "3 ay", kategori: "pazarlama" }, ], ``` Üçüncü taraf çerezler genellikle yurt dışı aktarım içerir; `trkit check` bunu hatırlatır. ### Politika değişince `cerez-banner.tsx` içindeki `CONSENT_VERSION` değerini artırın. Eski sürümle onay vermiş kullanıcılara banner yeniden gösterilir. ### Onay kayıtları Banner her seçimde `/api/consent` uç noktasına kayıt gönderir. `app/api/consent/route.ts` içindeki `kaydet()` fonksiyonunu veritabanınıza bağlayın. IP adresi `CONSENT_SALT` ile tuzlanarak özetlenir, ham hâliyle saklanmaz. --- # Türkçe formlar URL: https://zersjs.github.io/trkit/docs/rehber/form.md > Türkçe hata mesajları, TCKN/IBAN/telefon doğrulama ve il/ilçe seçimiyle form yazma. create-trkit-app projelerindeki `src/app/iletisim/` dizini çalışan bir örnektir. Bu sayfa o örneği adım adım açıklar. ### 1. Şema ```ts title="src/app/iletisim/schema.ts" import { cepTelefonu } from "@trkit-app-pack/validate"; import { isValidDistrict } from "@trkit-app-pack/address"; import { basHarfleriBuyut } from "@trkit-app-pack/format"; import { z } from "@/lib/zod"; // Türkçe hata mesajları export const iletisimSchema = z .object({ adSoyad: z.string().trim().min(3).max(80).transform(basHarfleriBuyut), eposta: z.email(), telefon: cepTelefonu, // "0532 123 45 67" → "+905321234567" il: z.coerce.number().int().min(1, "İl seçiniz").max(81), ilce: z.string({ message: "İlçe seçiniz" }).min(1, "İlçe seçiniz"), mesaj: z.string().trim().min(10).max(2000), ticariIleti: z.boolean().default(false), }) .refine((v) => isValidDistrict(v.il, v.ilce), { path: ["ilce"], message: "Seçilen ilçe bu ile ait değil" }); ``` Hazır mesajlar: "En az 3 karakter olmalıdır", "Geçerli bir e-posta adresi giriniz", "Bu alan zorunludur", "Geçerli bir cep telefonu giriniz (5XX XXX XX XX)". ### 2. Server action ```ts title="src/app/iletisim/actions.ts" "use server"; import { iletisimSchema } from "./schema"; export async function iletisimGonder(_prev: FormState, formData: FormData): Promise { const values = Object.fromEntries(formData) as Record; const parsed = iletisimSchema.safeParse({ ...values, ticariIleti: values.ticariIleti === "on" }); if (!parsed.success) { const errors: Record = {}; for (const i of parsed.error.issues) errors[String(i.path[0])] ??= i.message; return { status: "error", errors, values }; } // parsed.data.telefon E.164 biçiminde, adSoyad düzgün büyük harfli return { status: "success", adSoyad: parsed.data.adSoyad }; } ``` ### 3. Form ```tsx const [state, action, pending] = useActionState(iletisimGonder, { status: "idle" }); const [konum, setKonum] = useState({ il: null, ilce: null });
``` ### Hazır şemalar | Şema | Kabul eder | Dönüştürür | |---|---|---| | `tckn` | 11 hane, algoritma kontrolü | boşlukları temizler | | `vkn` | 10 hane, algoritma kontrolü | | | `vergiNo` | TCKN veya VKN (fatura formları) | | | `iban` | TR IBAN, mod-97 | `TR33 0006 …` → `TR330006…` | | `telefon` | mobil, sabit, 850 | E.164 `+90…` | | `cepTelefonu` | yalnızca 5XX | E.164 | | `plaka` | `34 ABC 123` vb. | `34ABC123` | | `postaKodu` | 5 hane, il kodu 01–81 | | | `mersis` | 16 hane | | Özel mesaj için şema fabrikalarını kullanın: `tcknSchema({ message: "TC kimlik numaranızı kontrol edin" })`, `phoneSchema({ mobileOnly: true })`. ### İpuçları - Telefon alanında `inputMode="tel"` mobilde rakam klavyesini açar. - TCKN algoritma kontrolü numaranın gerçek bir kişiye ait olduğunu göstermez. Kimlik doğrulaması gerekiyorsa NVİ KPS servisi gerekir. - Loglarda `maskTckn()` ve `maskPhone()` kullanın. --- # Ödeme akışı URL: https://zersjs.github.io/trkit/docs/rehber/odeme.md > iyzico veya PayTR ile güvenli ödeme; sepet, onaylar, callback ve iade. ### Kurulum ```bash npx trkit add odeme odeme-onaylari ``` ```bash title=".env.local" TRKIT_PAY_PROVIDER=iyzico # iyzico | paytr | mock IYZICO_API_KEY=sandbox-... IYZICO_SECRET_KEY=sandbox-... IYZICO_SANDBOX=1 ``` Geliştirmede `TRKIT_PAY_PROVIDER=mock` ile gerçek sağlayıcı olmadan tüm akışı deneyebilirsiniz. ### Akış ```text Sepet → Ödeme sayfası (onaylar) → createCheckout() → Sağlayıcı formu → Sağlayıcı /api/odeme/callback'e bildirir → verifyCallback() → sipariş güncellenir → Kullanıcı sonuç sayfasına yönlendirilir ``` ### 1. Ödeme sayfası ve onaylar Mesafeli Sözleşmeler Yönetmeliği'ne göre ön bilgilendirme formu, sipariş onayından **önce** ve sipariş bilgileriyle gösterilmeli: ```tsx title="app/odeme/page.tsx" import { generate, toHtml } from "@trkit-app-pack/legal"; import config from "@/trkit.config"; import { OdemeOnaylari } from "@/components/trkit/odeme-onaylari"; export default async function OdemeSayfasi() { const sepet = await sepetiGetir(); const order = { no: sepet.id, tarih: new Date().toISOString(), odemeYontemi: "Kredi kartı", alici: { adSoyad: sepet.adSoyad, adres: sepet.adres, telefon: sepet.telefon, eposta: sepet.eposta }, urunler: sepet.kalemler.map((k) => ({ ad: k.ad, adet: k.adet, birimFiyat: k.fiyatKurus })), kargoUcreti: sepet.kargoKurus, }; return (
); } ``` ### 2. Ödemeyi başlatma (sunucu) ```ts title="app/odeme/actions.ts" "use server"; import { headers } from "next/headers"; import { redirect } from "next/navigation"; import { pay } from "@/lib/pay"; export async function odemeyiBaslat(formData: FormData) { if (formData.get("onay[sozlesme]") !== "on") throw new Error("Sözleşme onayı gerekli"); const sepet = await sepetiGetir(); const ip = (await headers()).get("x-forwarded-for")?.split(",")[0] ?? "127.0.0.1"; const session = await pay.createCheckout({ orderId: sepet.id, // PayTR: yalnızca harf ve rakam amount: sepet.toplamKurus, // kalemlerin toplamına eşit olmalı buyer: { id: sepet.uyeId, name: sepet.ad, surname: sepet.soyad, email: sepet.eposta, phone: sepet.telefon, ip, address: { city: sepet.il, district: sepet.ilce, line: sepet.adres }, }, items: [ ...sepet.kalemler.map((k) => ({ id: k.id, name: k.ad, category: k.kategori, unitPrice: k.fiyatKurus, quantity: k.adet })), { id: "kargo", name: "Kargo", category: "Kargo", unitPrice: sepet.kargoKurus, type: "virtual" as const }, ], callbackUrl: `${process.env.NEXT_PUBLIC_SITE_URL}/api/odeme/callback`, successUrl: `${process.env.NEXT_PUBLIC_SITE_URL}/odeme/basarili`, failUrl: `${process.env.NEXT_PUBLIC_SITE_URL}/odeme/basarisiz`, installments: [1, 2, 3, 6], }); if (session.paymentPageUrl) redirect(session.paymentPageUrl); // iyzico redirect(`/odeme/form?token=${session.token}`); // PayTR: iframeUrl'i