İçeriğe geç
Docs

Ücretlendirme ve Hak Ediş

Uygulama planları, KDV, abonelik durumları, %80 geliştirici payı ve partner ödemesi.

Son güncelleme:

Uygulamanız aylık ya da yıllık planlar satabilir. Tahsilatı Tecof yapar (iyzico); KDV hariç tutarın varsayılan %80'i iade penceresi dolduktan sonra partner defterinize yazılır ve partner programının aylık ödeme akışıyla size ödenir. Planı olmayan uygulama ücretsizdir.


Planlar#

Planlar tecof.app.json içindeki plans dizisinde tanımlanır (en fazla 4):

JSON
{
  "plans": [
    {
      "key": "standart",
      "name": { "tr": "Standart", "en": "Standard" },
      "description": { "tr": "Küçük mağazalar için", "en": "For small stores" },
      "price": 199,
      "currency": "TRY",
      "interval": "month",
      "trialDays": 14,
      "features": [
        { "tr": "Sınırsız fatura", "en": "Unlimited invoices" },
        { "tr": "Toplu faturalama", "en": "Bulk invoicing" }
      ]
    },
    {
      "key": "yillik",
      "name": { "tr": "Yıllık", "en": "Yearly" },
      "description": { "tr": "İki ay hediye", "en": "Two months free" },
      "price": 1990,
      "currency": "TRY",
      "interval": "year",
      "trialDays": 0,
      "features": [{ "tr": "Standart planın tüm özellikleri", "en": "Everything in Standard" }]
    }
  ]
}
AlanKural
keyPlan anahtarı (uygulama içinde tekil)
name, description{ tr, en }
priceKDV hariç, sıfırdan büyük
currencyTRY, USD, EUR
intervalmonth ya da year
trialDays0–30
features{ tr, en } listesi; plan kartında gösterilir

Onaylanmış uygulamada plan değişiklikleri canlıya hemen yansır. Ücretli plan içeren public bir uygulamayı incelemeye göndermek için partner doğrulamanız (KYC + IBAN) onaylı olmalıdır. private dağıtım incelemeye girmediği için yayında KYC istenmez; ancak hak ediş ödemesi her durumda onaylı KYC ve IBAN ister. Bkz. Yayınlama ve İnceleme.

KDV#

Mağazanın ödeyeceği tutar:

Metin
ödenecek = price × (1 + KDV oranı)
Para birimiKDV oranı
TRYTecof fatura ayarlarındaki KDV oranı (bugün %20)
USD, EURTecof fatura ayarlarındaki ihracat KDV oranı (varsayılan %0)

Fiyatı her zaman KDV hariç girin; katalog ve ödeme ekranı KDV'yi ekleyerek gösterir.


Mağaza Satın Alma Akışı#

sequenceDiagram
    participant M as Mağaza (panel)
    participant T as Tecof
    participant I as iyzico
    participant A as Uygulamanız

    M->>T: Kurulum: POST /api/merchant/apps/install { appId, acceptedScopes, planKey }
    alt Ücretsiz plan ya da deneme süresi var
        T-->>M: next.type = "open"
        T->>A: app.installed (+ deneme varsa app.subscription.updated: trialing)
    else Ücretli, denemesiz plan
        T-->>M: next.type = "checkout" (billing.status = pending)
        M->>T: POST /installations/:id/billing/checkout { planKey, customer }
        T-->>M: iyzico ödeme formu
        M->>I: Kart bilgisi
        I->>T: Dönüş (callback) → iyzico'dan geri sorgu
        T->>T: Dönem açılır / uzatılır
        T->>A: app.subscription.updated (active)
        T-->>M: /app/apps/my-apps/<kurulum>?billing=success
    end
Diyagram
  • Ödeme iyzico'nun tek seferlik ödeme formuyla alınır; her ödeme bir dönem (ay ya da yıl) açar ya da uzatır.
  • Ödeme dönüşü (callback) kaçırılırsa bir mutabakat işi pending kalan ödemeleri iyzico'dan sorgulayıp tamamlar.
  • Panel dönüşte billing=success, billing=error ya da billing=processing gösterir.
  • Mağaza plan seçim ekranını panelden açabilir; uygulamanızın arayüzünden açmak için App Bridge openBilling() kullanın.

Mağazanın gördüğü uçlar (bilgi için): GET /api/merchant/apps/installations/:id/billing → { plans, subscription, charges }, POST /api/merchant/apps/installations/:id/billing/checkout.


Abonelik Durumları#

DurumAnlamı
trialingDeneme süresinde
activeÖdenmiş dönem sürüyor
past_dueDönem bitti, yenileme ödemesi bekleniyor (3 günlük tolerans)
expiredTolerans doldu, ödeme yapılmadı
cancelledUygulama kaldırıldı
stateDiagram-v2
    [*] --> trialing: Kurulum (denemeli plan)
    [*] --> active: Ödeme
    trialing --> active: Ödeme
    trialing --> past_due: Deneme bitti, ödeme yok
    active --> active: Yenileme ödemesi (dönem uzar)
    active --> past_due: Dönem sonu
    past_due --> active: Ödeme
    past_due --> expired: 3 gün tolerans doldu
    expired --> active: Ödeme
    trialing --> cancelled: Kaldırma
    active --> cancelled: Kaldırma
    past_due --> cancelled: Kaldırma
    expired --> cancelled: Kaldırma
Diyagram

v1 yaşam döngüsü kuralları#

  • Otomatik yenileme yoktur (v1). Dönem sonundan 7 gün önce (varsayılan) mağazaya hatırlatma gider; mağaza yenilemeyi elle öder.
  • Dönem bitince abonelik past_due olur; 3 günlük (varsayılan) tolerans sonunda expired'a geçer.
  • Deneme süresi ödeme yapılmadan biterse de aynı yol izlenir: trialing → past_due (3 gün) → expired.
  • Bir mağaza aynı uygulamanın deneme süresini yalnız bir kez kullanabilir; kaldırıp yeniden kurmak ikinci deneme açmaz.
  • Uygulama kaldırılınca abonelik cancelled olur; otomatik iade yapılmaz.
  • Her durum geçişi uygulamanıza app.subscription.updated webhook'u gönderir:
JSON
{
  "event": "app.subscription.updated",
  "data": {
    "planKey": "standart",
    "status": "active",
    "trialEndsAt": null,
    "currentPeriodEnd": "2026-11-10T09:16:10.000Z",
    "chargeId": "6720dd00ee11ff22aa33bb66"
  }
}

Otomatik yenilenen abonelik (iyzico abonelik API'si) v2'de planlanmıştır.


Özellikleri Plana Göre Açmak#

Erişimi kısıtlamak uygulamanın kararıdır; Tecof süresi dolan abonelikte panelde yalnız bir uyarı bandı gösterir. Plan durumunu şu yerlerden öğrenirsiniz:

YerKullanım
App Bridge bağlamıcontext.installation.plan = { key, status } ya da null — arayüzde göstermek/gizlemek için
app.subscription.updated webhook'uSunucu tarafında durumu saklamak için
api.installation()Sunucu tarafında anlık durum (subscription)

Sunucu tarafı örnek — webhook ile gelen durumu ayarlarda tutup her işte kontrol etmek:

TypeScript
// lib/billing.ts
import { tecof } from "@/lib/tecof";

type PlanState = { planKey: string | null; status: string; currentPeriodEnd: string | null };

const ALLOWED = new Set(["trialing", "active", "past_due"]); // past_due: 3 günlük toleransta çalışmayı sürdür

export async function savePlanState(installationId: string, data: PlanState) {
  await tecof.client(installationId).settings.set({ billing: data }, { merge: true });
}

export async function hasPaidAccess(installationId: string): Promise<boolean> {
  const { settings } = await tecof.client(installationId).settings.get();
  const billing = settings.billing as PlanState | undefined;
  return !!billing && ALLOWED.has(billing.status);
}
TypeScript
// app/api/webhooks/route.ts — createWebhookHandler({ app: tecof, handlers: { … } }) içinde
"app.subscription.updated": async (event) => {
  await savePlanState(event.installationId, event.data as PlanState);
},

Anlık durumu webhook'a bağlı kalmadan da okuyabilirsiniz: api.installation() yanıtındaki subscription alanı (plan yoksa null). Bkz. API ile Veri Erişimi.

Arayüz tarafı örnek:

TSX
"use client";

import { useAppBridge, useAppContext } from "@tecof/app-bridge/react";

export function PaidFeature({ children }: { children: React.ReactNode }) {
  const bridge = useAppBridge();
  const { installation } = useAppContext();
  const status = installation.plan?.status;

  if (status === "trialing" || status === "active" || status === "past_due") return <>{children}</>;

  return (
    <div>
      <p>Bu özellik ücretli planda kullanılabilir.</p>
      <button onClick={() => bridge.openBilling()}>Planları gör</button>
    </div>
  );
}

billing anahtarını yerel ayar formunuzdaki (settings şeması) anahtarlardan farklı seçin. past_due durumunda çalışmayı sürdürüp sürdürmemek ve deneme süresinde hangi özelliklerin açık olacağı sizin ürün kararınızdır.


Geliştirici Hak Edişi#

KuralDeğer
Platform komisyonuVarsayılan %20 → geliştirici payı %80
Hesap tabanıTahsilatın KDV hariç tutarı
İade penceresiVarsayılan 14 gün
Defter satırıÖdemeden 14 gün sonra, iade edilmemişse partner defterine kind: "accrual", sourceType: "app-charge" satırı yazılır
DönemSatırın dönemi, ödenebilir tarihin (ödeme + 14 gün) ayıdır (İstanbul saati)
Pencere içi kısmi iadeİade edilen tutar tahakkuktan düşülür; satır kalan tutar üzerinden yazılır
Pencere sonrası iadePartner defterine geri kesinti (kind: "clawback", sourceType: "app-refund") yazılır
Test mağazası satın alımıGeliştiricinin kendi test mağazalarından yapılan satın alma gerçek satış sayılmaz: satır held (app-test-store) yazılır; Tecof yöneticisi serbest bırakabilir

Bundan sonrası partner programının mevcut ödeme akışıdır:

  1. Aylık kapanış. Dönemi önceki ay ya da daha eski olan, ödemeye girmemiş satırlar partner × para birimi bazında toplanır.

  2. Ödeme açılma koşulları. Partner aktif, partner doğrulaması (KYC) onaylı, partner sözleşmesi onaylanmış ve toplam asgari tutarın üstünde olmalı. Aksi hâlde satırlar sonraki aya devreder.

    Para birimiAsgari ödeme
    TRY1.000 TL
    EUR50 €
    USD50 $
  3. Partner faturası. Şahıs ve kurumsal partner, ödeme tutarı için KDV eklenmiş fatura yükler (Türkiye'de %20; yurt dışı partnerde 0). Bireysel partnerde fatura adımı yoktur.

  4. Onay ve ödeme. Tecof yöneticisi faturayı onaylar (doğrulama ve IBAN şarttır) ve ödemeyi kaydeder. Fatura reddedilirse yeniden yüklenir.

Tahsilatları geliştirici API'sinden izleyebilirsiniz: GET /api/developer/apps/:id/charges.

Sayısal örnek#

Plan: Standart, 199 TL/ay (KDV hariç), Türkiye'deki kurumsal bir partner.

AdımHesapTutar
Mağazanın ödediği199 × 1,20238,80 TL
KDV hariç taban—199,00 TL
Platform komisyonu (%20)199 × 0,2039,80 TL
Geliştirici payı (%80)199 × 0,80159,20 TL

Zaman çizelgesi (ödeme 20 Ekim 2026):

TarihOlay
20.10.2026Mağaza öder; abonelik active, app.subscription.updated
03.11.202614 günlük iade penceresi doldu; defterde 159,20 TL accrual, dönem 2026-11
Aralık 2026 başıKasım dönemi kapanışa girer

Aynı ay 7 mağazadan bu planla tahsilat yapıldığını varsayalım: 7 × 159,20 = 1.114,40 TL ≥ 1.000 TL asgari tutar → ödeme açılır. Kurumsal partner 1.114,40 TL + %20 KDV = 1.337,28 TL tutarında fatura yükler; yönetici onayından sonra ödeme yapılır. Toplam 1.000 TL'nin altında kalsaydı satırlar bir sonraki kapanışa devrederdi.

Mağaza 14 gün içinde tam iade alırsa defter satırı hiç yazılmaz; kısmi iadede tahakkuk iade oranında azalır: örneğin 238,80 TL'lik ödemenin 118,80 TL'si (KDV dahil) pencere içinde iade edilirse kalan KDV hariç tutar 199 × 120 / 238,80 = 100,00 TL, defter satırı 100,00 × 0,80 = 80,00 TL olur. Pencereden sonra tam iade yapılırsa iade dönemine −159,20 TL'lik clawback satırı düşer. İadeleri (tam ya da kısmi) Tecof yöneticisi yapar.


Açık Konular#

  • Uygulama tahsilatının mağazaya Tecof tarafından faturalanması (e-Arşiv) henüz netleşmedi.
  • Otomatik yenileme v2'ye bırakıldı.
  • Birinci parti (partnersiz) uygulamalarda hak ediş satırı yazılmaz.