---
title: "Включение покупок с помощью Flow Builder в React Native SDK"
description: "Краткое руководство по подключению встроенных покупок с помощью Adapty Flow Builder."
---

Чтобы подключить встроенные покупки, нужно разобраться с тремя ключевыми понятиями:
- [**Продукты**](product) – всё, что пользователи могут купить (подписки, расходуемые покупки, пожизненный доступ)
- [**Флоу**](adapty-flow-builder) – последовательности экранов для представления продуктов пользователям, созданные в no-code Flow Builder. SDK получает их через `getFlow`. Если вы предпочитаете строить UI в собственном коде, используйте пейвол — см. [Ручная реализация пейволов](react-native-quickstart-manual).
- [**Плейсменты**](placements) – где и когда вы показываете флоу в приложении (например, `main`, `onboarding`, `settings`). Вы привязываете флоу к плейсментам на дашборде, а затем запрашиваете их по ID плейсмента в коде. Это упрощает проведение A/B-тестов и показ разных флоу разным пользователям.
Adapty предлагает три способа подключить покупки в вашем приложении. Выберите подходящий в зависимости от требований:
| Реализация | Сложность | Когда использовать |
|---|---|---|
| Adapty Flow Builder | ✅ Просто | Вы [создаёте готовый к покупкам флоу в no-code конструкторе](quickstart-paywalls). Adapty автоматически отображает его и берёт на себя весь сложный процесс покупки, валидацию чеков и управление подписками. |
| Пейволы, созданные вручную | 🟡 Средне | Вы реализуете UI пейвола в коде приложения, но всё равно получаете объект флоу от Adapty, сохраняя гибкость в настройке продуктов. См. [гайд](react-native-quickstart-manual). |
| Observer mode | 🔴 Сложно | У вас уже есть собственная инфраструктура для обработки покупок и вы хотите её сохранить. Обратите внимание, что observer mode имеет ограничения в Adapty. См. [статью](observer-vs-full-mode). |
:::important
**Шаги ниже показывают, как реализовать флоу, созданное в Adapty Flow Builder.**

Если вы предпочитаете создавать UI пейвола самостоятельно, см. [Реализация пейволов вручную](react-native-quickstart-manual).
:::

Чтобы отобразить флоу, созданное в Adapty Flow Builder, в коде приложения нужно выполнить всего несколько шагов:

1. **Получите флоу**: Запросите его из Adapty.
2. **Отобразите его — Adapty возьмёт покупки на себя**: Покажите view в приложении.
3. **Обработайте действия кнопок**: Свяжите действия пользователя с реакцией вашего приложения на них. Например, открывайте ссылки или закрывайте флоу при нажатии кнопок.
## Перед началом работы \{#before-you-start\}

Выполните следующие шаги:

1. Подключите приложение к [App Store](initial_ios) и/или [Google Play](initial-android) в дашборде Adapty.
2. [Создайте продукты](create-product) в Adapty.
3. [Создайте пейвол и добавьте в него продукты](create-paywall).
4. [Создайте плейсмент и добавьте пейвол в него](create-placement).
5. [Установите и активируйте Adapty SDK](sdk-installation-reactnative) в коде приложения.

:::tip
Быстрее всего выполнить эти шаги можно с помощью [quickstart-гайда](quickstart) или создав пейволы и плейсменты через [Developer CLI](developer-cli-quickstart).
:::

## 1. Получите флоу \{#1-get-the-flow\}

Флоу привязаны к плейсментам, настроенным в дашборде. Плейсменты позволяют показывать разные флоу разным аудиториям или запускать [A/B-тесты](ab-tests).

Чтобы получить флоу, созданный в Adapty Flow Builder, получите объект `flow` по идентификатору [плейсмента](placements) с помощью метода `getFlow`. Флоу содержит элементы интерфейса и стили, необходимые для его отображения.
```typescript showLineNumbers title="React Native"

try {
  const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');
  // the requested flow
} catch (error) {
  // handle the error
}
```

## 2. Отображение флоу \{#display-the-flow\}

Теперь, когда у вас есть флоу, достаточно добавить несколько строк для его отображения.

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>

Чтобы встроить флоу в существующее дерево компонентов, используйте компонент `AdaptyFlowView` непосредственно в иерархии компонентов React Native:
```typescript showLineNumbers title="React Native (TSX)"

function MyFlow({ flow }) {
  const onPurchaseCompleted = useCallback<FlowEventHandlers['onPurchaseCompleted']>(
    (result, product) => result.type !== 'user_cancelled',
    [],
  );

  return (
    <AdaptyFlowView
      flow={flow}
      style={{ flex: 1 }}
      onPurchaseCompleted={onPurchaseCompleted}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">

Чтобы отобразить флоу как отдельный экран, создайте `view` с помощью метода `createFlowView`, задайте обработчики событий, затем вызовите `view.present()`. Каждый `view` можно использовать только один раз. Если вам нужно снова показать флоу, вызовите `createFlowView` ещё раз, чтобы создать новый экземпляр `view`.
```typescript showLineNumbers title="React Native"

try {
  const view = await createFlowView(flow);

  view.setEventHandlers({
    onPurchaseCompleted(result, product) {
      return result.type !== 'user_cancelled';
    },
  });

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

</TabItem>
</Tabs>

:::tip
Подробнее о том, как отобразить флоу, читайте в нашем [гайде](react-native-present-paywalls).
:::
## 3. Обработка действий кнопок \{#handle-button-actions\}

Когда пользователи нажимают кнопки во флоу, React Native SDK автоматически обрабатывает покупки, восстановление, закрытие флоу и открытие URL.

Однако у других кнопок есть пользовательские или предопределённые идентификаторы, требующие обработки действий в вашем коде. Или вы можете захотеть переопределить их поведение по умолчанию.

Например, ниже показано поведение по умолчанию для кнопки закрытия. Добавлять это в код не нужно, но здесь вы можете увидеть, как это делается при необходимости.

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>
For the React component, handle actions directly in the `AdaptyFlowView` component:
```typescript showLineNumbers title="React Native (TSX)"

function MyFlow({ flow }) {
  const onCloseButtonPress = useCallback<FlowEventHandlers['onCloseButtonPress']>(
    () => true, // allow the flow to close
    [],
  );
  const onCustomAction = useCallback<FlowEventHandlers['onCustomAction']>(
    (actionId) => false,
    [],
  );

  return (
    <AdaptyFlowView
      flow={flow}
      style={{ flex: 1 }}
      onCloseButtonPress={onCloseButtonPress}
      onCustomAction={onCustomAction}
    />
  );
}
```

</TabItem>
<TabItem value="standalone" label="Модальное представление">

Для модального представления реализуйте обработчики событий с помощью `setEventHandlers`:

```typescript showLineNumbers title="React Native"
const unsubscribe = view.setEventHandlers({
  onCloseButtonPress() {
    return true; // allow the flow to close
  },
});
```

</TabItem>
</Tabs>

:::tip
Прочитайте наши гайды по обработке [действий](react-native-handle-paywall-actions) и [событий](react-native-handling-events-1) кнопок.
:::
## Следующие шаги \{#next-steps\}

:::tip
Есть вопросы или возникли проблемы? Загляните на наш [форум поддержки](https://adapty.featurebase.app/), где можно найти ответы на распространённые вопросы или задать свой. Наша команда и сообщество всегда готовы помочь!
:::

Пейвол готов к отображению в приложении. Протестируйте покупки в [песочнице App Store](test-purchases-in-sandbox) или в [Google Play Store](testing-on-android), чтобы убедиться, что тестовая покупка через пейвол проходит успешно.

Теперь нужно [проверить уровень доступа пользователей](react-native-check-subscription-status), чтобы показывать пейвол или предоставлять доступ к платным функциям только нужным пользователям.

## Полный пример \{#full-example\}

Вот как все шаги из этого гайда можно объединить в вашем приложении.

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React компонент" default>
```javascript showLineNumbers title="React Native (TSX)"

export default function FlowScreen() {
  const [flow, setFlow] = useState(null);

  const loadFlow = async () => {
    try {
      const flowData = await adapty.getFlow('YOUR_PLACEMENT_ID');
      setFlow(flowData);
    } catch (error) {
      console.warn('Error loading flow:', error);
    }
  };

  const onCloseButtonPress = useCallback<FlowEventHandlers['onCloseButtonPress']>(
    () => true,
    [],
  );

  const onPurchaseCompleted = useCallback<FlowEventHandlers['onPurchaseCompleted']>(
    (result, product) => result.type !== 'user_cancelled',
    [],
  );

  useEffect(() => {
    loadFlow();
  }, []);

  return (
    <View style={{ flex: 1 }}>
      {flow ? (
        <AdaptyFlowView
          flow={flow}
          style={{ flex: 1 }}
          onCloseButtonPress={onCloseButtonPress}
          onPurchaseCompleted={onPurchaseCompleted}
        />
      ) : (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
          <Button title="Load Flow" onPress={loadFlow} />
        </View>
      )}
    </View>
  );
}
```

</TabItem>
<TabItem value="standalone" label="Modal presentation">
```javascript showLineNumbers title="React Native"

export default function FlowScreen() {
  const showFlow = async () => {
    try {
      const flow = await adapty.getFlow('YOUR_PLACEMENT_ID');

      const view = await createFlowView(flow);

      view.setEventHandlers({
        onCloseButtonPress() {
          return true;
        },
        onPurchaseCompleted(result, product) {
          return result.type !== 'user_cancelled';
        },
      });

      await view.present();
    } catch (error) {
      // handle any error that may occur during the process
      console.warn('Error showing flow:', error);
    }
  };

  // you can add a button to manually trigger the flow for testing purposes
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="Show Flow" onPress={showFlow} />
    </View>
  );
}
```

</TabItem>
</Tabs>