---
title: "Habilitar compras con Flow Builder en React Native SDK"
description: "Guía de inicio rápido para habilitar compras in-app con Adapty Flow Builder."
---

Para habilitar las compras in-app, necesitas entender tres conceptos clave:
- [**Productos**](product) – todo lo que los usuarios pueden comprar (suscripciones, consumibles, acceso de por vida)
- [**Flows**](adapty-flow-builder) – secuencias de pantallas que presentan productos a los usuarios, creadas en el Flow Builder sin código. El SDK las recupera mediante `getFlow`. Si prefieres construir la interfaz en tu propio código, usa un paywall en su lugar — consulta [Implementar paywalls manualmente](react-native-quickstart-manual).
- [**Placements**](placements) – dónde y cuándo mostrar los flows en tu app (como `main`, `onboarding`, `settings`). Asocias los flows a los placements en el dashboard y luego los solicitas por ID de placement en tu código. Esto facilita ejecutar pruebas A/B y mostrar flows distintos a diferentes usuarios.
Adapty te ofrece tres formas de habilitar compras en tu aplicación. Elige la que mejor se adapte a tus necesidades:
| Implementación | Complejidad | Cuándo usar |
|---|---|---|
| Adapty Flow Builder | ✅ Fácil | [Creas un flow completo y listo para compras en el builder sin código](quickstart-paywalls). Adapty lo renderiza automáticamente y gestiona todo el flujo de compra, la validación de recibos y la gestión de suscripciones en segundo plano. |
| Paywalls creados manualmente | 🟡 Media | Implementas la UI de tu paywall en el código de tu app, pero obtienes el objeto flow de Adapty para mantener flexibilidad en las ofertas de productos. Consulta la [guía](react-native-quickstart-manual). |
| Modo observador | 🔴 Difícil | Ya tienes tu propia infraestructura de gestión de compras y quieres seguir usándola. Ten en cuenta que el modo observador tiene sus limitaciones en Adapty. Consulta el [artículo](observer-vs-full-mode). |
:::important
**Los pasos a continuación muestran cómo implementar un flow creado en el Adapty Flow Builder.**

Si prefieres construir la UI del paywall tú mismo, consulta [Implementar paywalls manualmente](react-native-quickstart-manual).
:::

Para mostrar un flow creado en el Adapty Flow Builder, en el código de tu app solo necesitas:

1. **Obtener el flow**: Obténlo desde Adapty.
2. **Mostrarlo y Adapty gestionará las compras por ti**: Muestra la vista en tu app.
3. **Gestionar las acciones de los botones**: Asocia las interacciones del usuario con la respuesta de tu app. Por ejemplo, abrir enlaces o cerrar el flow cuando los usuarios pulsen botones.
## Antes de empezar \{#before-you-start\}

Antes de empezar, completa estos pasos:

1. Conecta tu app al [App Store](initial_ios) y/o [Google Play](initial-android) en el Adapty Dashboard.
2. [Crea tus productos](create-product) en Adapty.
3. [Crea un paywall y añade productos](create-paywall).
4. [Crea un placement y añade tu paywall](create-placement).
5. [Instala y activa el SDK de Adapty](sdk-installation-reactnative) en el código de tu app.

:::tip
La forma más rápida de completar estos pasos es seguir la [guía de inicio rápido](quickstart) o crear paywalls y placements usando el [CLI para desarrolladores](developer-cli-quickstart).
:::

## 1. Obtén el flow \{#1-get-the-flow\}

Tus flows están asociados con placements configurados en el dashboard. Los placements te permiten ejecutar distintos flows para diferentes audiencias o realizar [pruebas A/B](ab-tests).

Para obtener un flow creado en el Adapty Flow Builder, obtén el objeto `flow` mediante el ID del [placement](placements) usando el método `getFlow`. El flow contiene los elementos de UI y el estilo necesarios para mostrarlo.
```typescript showLineNumbers title="React Native"

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

## 2. Mostrar el flow \{#display-the-flow\}

Ahora que tienes el flow, basta con añadir unas pocas líneas para mostrarlo.

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

Para insertar un flow dentro de tu árbol de componentes existente, usa el componente `AdaptyFlowView` directamente en la jerarquía de componentes de 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">

Para mostrar el flow como una pantalla independiente, crea un `view` con el método `createFlowView`, define sus manejadores de eventos y llama a `view.present()`. Cada `view` solo puede usarse una vez. Si necesitas mostrar el flow de nuevo, llama a `createFlowView` otra vez para crear una nueva instancia de `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
Para más detalles sobre cómo mostrar un flow, consulta nuestra [guía](react-native-present-paywalls).
:::
## 3. Gestionar las acciones de los botones \{#3-handle-button-actions\}

Cuando los usuarios pulsan botones en el flow, el SDK de React Native gestiona automáticamente las compras, la restauración, el cierre del flow y la apertura de URLs.

Sin embargo, otros botones tienen IDs personalizados o predefinidos y requieren gestionar las acciones en tu código. O puede que quieras sobreescribir su comportamiento predeterminado.

Por ejemplo, aquí tienes el comportamiento predeterminado del botón de cerrar. No necesitas añadirlo en el código, pero aquí puedes ver cómo se hace si fuera necesario.

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="React component" default>
Para el componente React, gestiona las acciones directamente en el componente `AdaptyFlowView`:
```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="Presentación modal">

Para la presentación modal, implementa los manejadores de eventos usando `setEventHandlers`:

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

</TabItem>
</Tabs>

:::tip
Lee nuestras guías sobre cómo gestionar [acciones](react-native-handle-paywall-actions) y [eventos](react-native-handling-events-1) de botones.
:::
## Próximos pasos \{#next-steps\}

:::tip
¿Tienes preguntas o estás teniendo algún problema? Consulta nuestro [foro de soporte](https://adapty.featurebase.app/) donde encontrarás respuestas a preguntas frecuentes o podrás plantear las tuyas. ¡Nuestro equipo y la comunidad están aquí para ayudarte!
:::

Tu paywall está listo para mostrarse en la app. Prueba tus compras en el [sandbox del App Store](test-purchases-in-sandbox) o en [Google Play Store](testing-on-android) para asegurarte de que puedes completar una compra de prueba desde el paywall.

Ahora necesitas [comprobar el nivel de acceso de los usuarios](react-native-check-subscription-status) para asegurarte de mostrar un paywall o dar acceso a las funciones de pago a los usuarios correctos.

## Ejemplo completo \{#full-example\}

Aquí se muestra cómo integrar todos los pasos de esta guía en tu aplicación.

<Tabs groupId="presentation-method" queryString>
<TabItem value="platform" label="Componente 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="Presentación modal">
```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>