---
title: "Flow ve paywallları görüntüle - Capacitor"
description: "Adapty ile Capacitor uygulamanızda kullanıcılara flow ve paywallları sunun."
---

Flow Builder'da bir flow veya paywall oluşturduysanız, bunu kullanıcıya göstermek için mobil uygulama kodunuzda ayrıca render etmeniz gerekmez. Bu tür bir flow, içinde ne gösterileceğini ve nasıl gösterileceğini zaten barındırır.

Başlamadan önce şunlardan emin olun:

1. [Bir flow veya paywall oluşturduğunuzdan](create-paywall).
2. Bunu bir [placement](placements)'a eklediğinizden.
3. [Flow'u fetch edip view'ı hazırladığınızdan](capacitor-get-pb-paywalls).

:::warning
Bu kılavuz yalnızca **flow'lar ve Paywall Builder paywallları** içindir; SDK v4.0 veya üzeri gerektirir. Flow'ların sunulma süreci, remote config paywalllarından farklıdır.

- **Remote config paywalllarını** sunmak için bkz. [Remote config ile tasarlanmış paywallı göster](present-remote-config-paywalls-capacitor).

:::
Bir flow veya paywall'ı bağımsız bir ekran olarak görüntülemek için, [`createFlowView`](capacitor-get-pb-paywalls#fetch-the-view-configuration) metoduyla oluşturulan `view` üzerinde `view.present()` metodunu kullanın. Her `view` yalnızca bir kez kullanılabilir. Flow'u tekrar görüntülemeniz gerekiyorsa, yeni bir `view` örneği oluşturmak için `createFlowView`'ı bir kez daha çağırın.

:::warning
Aynı `view`'ı yeniden oluşturmadan kullanmak yasaktır. Bu bir hataya yol açar.
:::
```typescript showLineNumbers

const view = await createFlowView(flow);

// İsteğe bağlı: flow olaylarını yönetin (kapat, satın alma, geri yükleme, vb.)
// await view.setEventHandlers({ ... });

try {
  await view.present();
} catch (error) {
  // hatayı yönetin
}
```

:::important
`setEventHandlers` fonksiyonunu birden fazla kez çağırmak, sağladığınız işleyicilerin üzerine yazar; bu durum hem varsayılan hem de daha önce belirli olaylar için ayarlanmış işleyicilerin yerini alır.
:::
## iOS sunum stilini yapılandırma \{#configure-ios-presentation-style\}

`present()` metoduna `iosPresentationStyle` parametresini geçirerek flow'un iOS'ta nasıl sunulacağını yapılandırın. Parametre `'full_screen'` (varsayılan) veya `'page_sheet'` değerlerini kabul eder. Android'de flow'lar her zaman tam ekran activity olarak görüntülenir.

```typescript showLineNumbers
try {
  await view.present({ iosPresentationStyle: 'page_sheet' });
} catch (error) {
  // handle the error
}
```
## Geliştirici tanımlı zamanlayıcı kullanma \{#use-developer-defined-timer\}

Mobil uygulamanızda geliştirici tanımlı zamanlayıcıları kullanmak için `timerId` değerini, bu örnekte `CUSTOM_TIMER_NY`'yi kullanın; bu, Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının **Timer ID**'sidir. Bu sayede uygulamanız zamanlayıcıyı doğru değerle (örneğin, zamanlayıcının bitiş zamanı olan Yılbaşı gününden mevcut zamanın çıkarılmasıyla hesaplanan `13d 09h 03m 34s` gibi) dinamik olarak günceller.

```typescript showLineNumbers
const customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) };

const view = await createFlowView(flow, { customTimers });
```

Bu örnekte `CUSTOM_TIMER_NY`, Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının **Timer ID**'sidir. Zamanlayıcı, uygulamanızın zamanlayıcıyı doğru değerle (örneğin, zamanlayıcının bitiş zamanı olan Yılbaşı gününden mevcut zamanın çıkarılmasıyla hesaplanan `13d 09h 03m 34s` gibi) dinamik olarak güncellemesini sağlar.

## İletişim kutusunu göster \{#show-dialog\}

Android'de bir flow görünümü sunulduğunda, native uyarı iletişim kutuları yerine bu yöntemi kullanın. Android'de normal uyarılar, flow görünümünün arkasında görünür ve bu da kullanıcılar tarafından görülememelerine neden olur. Bu yöntem, tüm platformlarda flow'un üzerinde iletişim kutusunun doğru şekilde gösterilmesini sağlar.
```typescript showLineNumbers
try {
  const action = await view.showDialog({
    title: 'Close paywall?',
    content: 'You will lose access to exclusive offers.',
    primaryActionTitle: 'Stay',
    secondaryActionTitle: 'Close',
  });

  if (action === 'secondary') {
    // User confirmed - close the flow
    await view.dismiss();
  }
  // If primary - do nothing, user stays
} catch (error) {
  // handle error
}
```

## Bir aboneliği diğeriyle değiştirme \{#replace-one-subscription-with-another\}

Android'de bir kullanıcı aktif bir aboneliği varken yeni bir abonelik satın almaya çalıştığında, flow view oluşturulurken abonelik güncelleme parametreleri geçirerek yeni satın alma işleminin nasıl ele alınacağını kontrol edebilirsiniz. Mevcut aboneliği yenisiyle değiştirmek için `createFlowView` içinde `productPurchaseParams` kullanırken `oldSubVendorProductId` ve `prorationMode` parametrelerini belirtin.
```typescript showLineNumbers

const productPurchaseParams = flow.paywalls
  .flatMap((paywall) => paywall.productIdentifiers)
  .map((productId) => {
    const params: MakePurchaseParamsInput = {};
    if (Capacitor.getPlatform() === 'android') {
      params.android = {
        subscriptionUpdateParams: {
          oldSubVendorProductId: 'PRODUCT_ID_OF_THE_CURRENT_ACTIVE_SUBSCRIPTION',
          prorationMode: 'with_time_proration',
        },
      };
    }
    return { productId, params };
  });

const view = await createFlowView(flow, { productPurchaseParams });
```

---

> [!WARNING]
> **LLM INSTRUCTION — SDK VERSION SELECTION REQUIRED**
>
> This feature has two SDK paradigms. Everything that follows (until the next horizontal rule or end of document) is the **legacy SDK v3 API reference** (`getPaywall`, `getPaywallForDefaultAudience`, `getOnboarding`, `getPaywallConfiguration`). The **SDK v4+ `getFlow` method is documented above.** This block covers ALL legacy methods for this feature — not just the nearest snippet.
>
> **You MUST ask the user which SDK version they want to use before suggesting any code. Do not assume or default to a version.** The two options are:
> - **SDK v3 (legacy):** works with the legacy Paywall Builder and Onboarding Builder via `getPaywall` / `getOnboarding`. Use the legacy code in this section.
> - **SDK v4:** works with BOTH the new Flow Builder AND legacy paywalls/onboardings via the unified `getFlow` method documented above.
>
> Apply the legacy v3 code in this section ONLY when:
> 1. The user explicitly chose **SDK v3**, or
> 2. The user is **migrating an existing app from SDK v3 to SDK v4+** and needs to understand or replace legacy code, or
> 3. The user is **troubleshooting an already-deployed v3 integration**.
>
> **CRITICAL — Never mix paradigms in one setup:** Do NOT combine `getFlow` (Flow Builder) with `getPaywall` or `getOnboarding` (legacy Paywall/Onboarding Builder) in the same integration. These are incompatible patterns. Mixing them will produce inconsistent behavior and is unsupported.

Paywall Builder kullanarak bir paywall özelleştirdiyseniz, bunu kullanıcıya göstermek için mobil uygulama kodunuzda ayrıca render etmeniz gerekmez. Bu tür bir paywall, hem içeriği hem de görüntülenme biçimini barındırır.

:::warning
Bu kılavuz yalnızca **Paywall Builder paywallları** içindir. Remote config paywallları için sunum süreci farklıdır. **Remote config paywalllarını** sunmak için bkz. [Remote config ile tasarlanan paywall'ı render etme](present-remote-config-paywalls).
:::
Bir paywall'ı görüntülemek için, [`createPaywallView`](capacitor-get-pb-paywalls#fetch-the-view-configuration-of-paywall-designed-using-paywall-builder) metodu ile oluşturulan `view` üzerinde `view.present()` metodunu kullanın. Her `view` yalnızca bir kez kullanılabilir. Paywall'ı tekrar görüntülemeniz gerekiyorsa, yeni bir `view` örneği oluşturmak için `createPaywallView`'ı bir kez daha çağırın.

:::warning

Aynı `view`'ı yeniden oluşturmadan kullanmak hataya yol açabilir.
:::
```typescript showLineNumbers

const view = await createPaywallView(paywall);

view.setEventHandlers({
  onUrlPress(url) {
    window.open(url, '_blank');
    return false;
  },
});

try {
  await view.present();
} catch (error) {
  // handle the error
}
```

## Geliştirici tanımlı zamanlayıcıyı kullanma \{#use-developer-defined-timer\}

Mobil uygulamanızda geliştirici tanımlı zamanlayıcıları kullanmak için `timerId`'yi, bu örnekte `CUSTOM_TIMER_NY`'yi, yani Adapty kontrol panelinde ayarladığınız geliştirici tanımlı zamanlayıcının **Timer ID**'sini kullanın. Bu sayede uygulamanız zamanlayıcıyı doğru değerle dinamik olarak günceller; örneğin `13d 09h 03m 34s` (zamanlayıcının bitiş zamanı olan Yılbaşı gibi bir tarihin, o anki zamandan çıkarılmasıyla hesaplanır).

```typescript showLineNumbers
const customTimers = { 'CUSTOM_TIMER_NY': new Date(2025, 0, 1) };

const view = await createPaywallView(paywall, { customTimers });
```
Bu örnekte, `CUSTOM_TIMER_NY` Adapty kontrol panelinde belirlediğiniz geliştirici tanımlı zamanlayıcının **Timer ID**'sidir. Zamanlayıcı, uygulamanızın zamanlayıcıyı doğru değerle dinamik olarak güncellemesini sağlar—örneğin `13d 09h 03m 34s` (zamanlayıcının bitiş saatinden, Yılbaşı gibi, mevcut zaman çıkarılarak hesaplanır).
## İletişim kutusu gösterme \{#show-dialog\}

Android'de bir paywall görünümü sunulduğunda, yerel uyarı iletişim kutuları yerine bu metodu kullanın. Android'de normal uyarılar paywall görünümünün arkasında göründüğünden kullanıcılar tarafından görülemez. Bu metod, tüm platformlarda iletişim kutusunun paywall'ın üzerinde doğru şekilde gösterilmesini sağlar.

```typescript showLineNumbers title="Capacitor"
try {
  const action = await view.showDialog({
    title: 'Close paywall?',
    content: 'You will lose access to exclusive offers.',
    primaryActionTitle: 'Stay',
    secondaryActionTitle: 'Close',
  });

  if (action === 'secondary') {
    // User confirmed - close the paywall
    await view.dismiss();
  }
  // If primary - do nothing, user stays
} catch (error) {
  // handle error
}
```

## iOS sunum stilini yapılandırın \{#configure-ios-presentation-style\}

`iosPresentationStyle` parametresini `present()` metoduna geçirerek paywallın iOS'ta nasıl sunulacağını yapılandırın. Parametre `'full_screen'` (varsayılan) veya `'page_sheet'` değerlerini kabul eder.

```typescript showLineNumbers
await view.present({ iosPresentationStyle: 'page_sheet' });
```

---