Saltar al contenido principal
En esta página

Utilice el SDK de DEUNA para React Native para compartir integraciones de Widget de pago, Bóveda de pagos, Click to Pay, siguiente acción, cupones y billeteras nativas en aplicaciones iOS y Android.

Requisitos#

Para usar el SDK de React Native de DEUNA, necesita:

  • Node.js: 20 o superior
  • Gestor de paquetes: Yarn o npm
  • React: 18.2.0 o superior
  • Reaccionar nativo: 0.73.0 o superior
  • React Native WebView: 13.15.0 o superior
  • SDK de Expo: 50 o superior (para aplicaciones con Expo)
  • Credenciales de DEUNA: Una cuenta activa y credenciales válidas de DEUNA (contacte a support@deuna.com si experimenta algún retraso)
  • Proyecto de Android: minSdkVersion 24 o superior
  • Dispositivos Huawei: HarmonyOS 2.0 o superior

Instale el SDK#

Comience la inicialización del SDK.

1. Agregue dependencias

Agregue el SDK de DEUNA a su proyecto:

yarn add @deuna/react-native-sdk

Agregue los requeridos react-native-webview (≥ 13.15.0) dependencia de pares:

yarn add react-native-webview

2. Vinculación

A partir de la versión 2.1.0, el SDK incluye un módulo nativo que habilita las hojas de pago nativas de Google Pay y Apple Pay.

Reaccionar CLI nativa

correr pod install para vincular el módulo nativo en iOS:

Shell
cd ios && pod install

Expo (flujo de trabajo administrado)

Agregue el complemento de configuración a app.json. Proporcione solo las habilitaciones de billetera y los proveedores de fraude que usa su aplicación:

app.jsonJSON
{
  "expo": {
    "plugins": [
      [
        "@deuna/react-native-sdk",
        {
          "merchantIdentifiers": ["merchant.com.example"],
          "googlePay": true,
          "fraudProviders": []
        }
      ]
    ]
  }
}

Ejecute prebuild para regenerar los directorios ios/ y android/ nativos con el módulo registrado:

Shell
npx expo prebuild

3. Guía de migración de 1.x a 2.x.x

Inicializa y monta el renderizador#

Cree una instancia del SDK y manténgala a lo largo de las renderizaciones. Monte exactamente una DeunaWidget para esa instancia. El componente renderiza tanto los flujos de modal como de WebView incrustado; llamar al inicializador solo configura su controlador.

JavaScript
import {useMemo} from 'react';
import {DeunaSDK, DeunaWidget} from '@deuna/react-native-sdk';

export function CheckoutScreen() {
  const deunaSDK = useMemo(
    () =>
      DeunaSDK.initialize({
        publicApiKey: 'YOUR_PUBLIC_API_KEY',
        environment: 'sandbox',
      }),
    []
  );

  return (
    <>
      <CheckoutContent deunaSDK={deunaSDK} />
      <DeunaWidget instance={deunaSDK} />
    </>
  );
}

Abrir widget de pago#

El Widget de Pago es un componente integrado que te permite ofrecer múltiples métodos de pago a los clientes:

  • Tarjetas de crédito y débito: Visa, Mastercard, American Express y tarjetas co-branded.
  • Métodos de pago alternativos (APMs): OXXO, KueskiPay, Aplazo, Daviplata, Nequi y más.
  • Carteras digitales: PayPal, Apple Pay y Google Pay.

Mostrar en un modal

Uso Mode.MODAL (por defecto) para una hoja modal gestionada por el SDK. El <DeunaWidget instance={deunaSDK} /> montado se presenta automáticamente sobre tu pantalla:

JavaScript
import {Mode} from '@deuna/react-native-sdk';

const onShowPaymentWidget = async () => {
  await deunaSDK.initPaymentWidget({
    orderToken: 'YOUR_ORDER_TOKEN',
    mode: Mode.MODAL,
    language: 'en',
    callbacks: {
      onSuccess: async (order) => {
        await deunaSDK.close(); // Closes modal and releases widget resources
        navigation.navigate('PaymentSuccess', {order});
      },
      onError: (error) => showRetry(error),
      onClosed: (action) => navigation.goBack(),
      onPaymentProcessing: () => disablePayButton(),
      onEventDispatch: (event, payload) => {
        analytics.track(event, payload);
      },
    },
  });
};

Referencia de parámetros

AtributoTipoModalIntegradoDescripción
orderTokenstring✅✅Requerido. Token único para la orden creada a través de la API de DEUNA.

importante: Al crear la orden a través de la API de DEUNA, no definas un redirect_url si quieres que la onSuccess callback se ejecute dentro de la aplicación móvil.
callbacksobject✅✅Requerido. Funciones callback que manejan eventos del widget (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onDownloadFile, onEventDispatch).
modeMode✅✅Mode.MODAL (predeterminado) o Mode.EMBEDDED.
userTokenstring✅✅Opcional. Token de portador (bearer) de DEUNA del cliente.

importante: Para que aparezcan tarjetas guardadas, el correo electrónico vinculado al userToken debe coincidir con el billing_address.email debe coincidir con el pasado durante la creación de la orden.
styleFilestring✅✅Opcional. UUID proporcionado por DEUNA para aplicar personalización de marca de tema personalizado (colores, tipografía, logo).
paymentMethodsobject[]✅✅Opcional. Array que define un único método de pago para lanzar directamente al flujo de formularios (ej. [{ paymentMethod: 'bnpl', processors: ['kueski'] }]). El widget se abre directamente en el formulario de ese método sin mostrar el selector de métodos. Nota: los sistemas de checkout internos actualmente admiten un solo elemento.
languagestring✅✅Opcional. Código de idioma ("es", "en", "pt"). Anula la configuración predeterminada del comerciante.
behaviorobject✅✅Opcional. Personalización del flujo, como behavior: { paymentMethods: { flowType: "twoStep" } } para PayPal.
fraudCredentialsobject✅✅Opcional. Credenciales del proveedor de fraude (ej. { RISKIFIED: { storeDomain: 'example.com' } }).
domainstring✅✅Opcional. Anula el host base predeterminado (https://pay.deuna.io).
hidePayButtonboolean❌✅Opcional. Oculta el botón de pago integrado en modo integrado cuando tu aplicación renderiza un botón de pago nativo.

Integrar un widget#

Para mostrar el widget directamente dentro del diseño de tu pantalla, inicializa con mode: Mode.EMBEDDED.

JavaScript
import { useEffect } from 'react';
import { View, Button } from 'react-native';
import { DeunaSDK, DeunaWidget, Mode } from '@deuna/react-native-sdk';

export function EmbeddedCheckoutScreen({ deunaSDK, orderToken }) {
  // Release widget resources on unmount
  useEffect(() => {
    return () => {
      deunaSDK.close();
    };
  }, [deunaSDK]);

  const handleOpenEmbedded = async () => {
    await deunaSDK.initPaymentWidget({
      orderToken,
      mode: Mode.EMBEDDED,
      callbacks: {
        onSuccess: async (order) => {
          await deunaSDK.close();
          navigateToReceipt(order);
        },
        onError: (error) => handlePaymentError(error),
      },
    });
  };

  return (
    <View style={{ flex: 1 }}>
      <View style={{ flex: 1, width: '100%' }}>
        <DeunaWidget instance={deunaSDK} />
      </View>
      <Button title="Cargar formulario de pago" onPress={handleOpenEmbedded} />
    </View>
  );
}

Botón de pago personalizado (hidePayButton)

Si tu aplicación renderiza su propio botón de pago, pasa hidePayButton: true y ejecuta las validaciones y el envío manualmente:

JavaScript
await deunaSDK.initPaymentWidget({
  orderToken,
  mode: Mode.EMBEDDED,
  hidePayButton: true,
  callbacks,
});

const handleCustomSubmit = async () => {
  // 1. Validate entered card/payment fields
  const isValid = await deunaSDK.isValid();
  if (!isValid) return;

  // 2. Submit payment
  const result = await deunaSDK.submit();
  if (result.status === 'error') {
    console.error('Submit failed:', result.message);
  }
};
MétodoDescripciónValor de retorno
deunaSDK.isValid()Valida la entrada del usuario en el formulario de pago activo.Promise<boolean>
deunaSDK.submit()Envía el pago equivalente a hacer clic en el botón del widget.Promise<{ status: 'success' | 'error', message?: string }>

Filtrar y configurar métodos de pago#

Flujo de formularios directos (paymentMethods)

Las arquitecturas de checkout de DEUNA (checkout-base y modular-checkout) permiten lanzar directamente a un formulario de pago individual, un patrón conocido como flujo de formularios.

Aunque el parámetro del SDK paymentMethods está tipado como un arreglo, los motores de checkout internos actualmente admiten solo un elemento en esta lista. Proporcionar un único método de pago abre el widget directamente en el formulario específico de ese método de pago (por ejemplo, Kueski Pay BNPL), omitiendo la pantalla de selección de método de pago.

JavaScript
await deunaSDK.initPaymentWidget({
  orderToken,
  paymentMethods: [
    { paymentMethod: 'bnpl', processors: ['kueski'] },
  ],
  callbacks,
});

Resolución de prioridad de configuración

Al determinar qué métodos y formularios de pago mostrar, DEUNA resuelve las configuraciones en el siguiente orden:

PrioridadFuenteComportamiento
1 (Mayor prioridad)paymentMethods en .initPaymentWidget()Flujo de formularios directos: Se abre inmediatamente en el formulario del método de pago único especificado (por ejemplo, Kueski), omitiendo el selector de métodos.
2include_payment_options en la creación de la ordenSelección de múltiples métodos: Muestra solo los métodos de pago especificados durante la creación de la orden que estén activos en tu cuenta.
3 (Respaldo)Configuración a nivel de comerciante (/payment-methods)Selector completo: Si se omite tanto en la llamada al SDK como en el payload de la orden, muestra todos los métodos de pago activos configurados para tu cuenta de comerciante.

Configuraciones de PayPal

Tipo de flujo (flowType)

Controla si PayPal muestra un resumen del pedido antes del pago o pasa directamente a la autorización:

JavaScript
await deunaSDK.initPaymentWidget({
  orderToken,
  behavior: {
    paymentMethods: {
      flowType: 'twoStep', // 'twoStep' (order summary first) or 'singleStep' (direct payment)
    },
  },
  callbacks,
});

Compra automática (express)

Cuando los clientes han autorizado previamente pagos rápidos con PayPal, habilita el procesamiento inmediato:

JavaScript
await deunaSDK.initPaymentWidget({
  orderToken,
  paymentMethods: [
    {
      paymentMethod: 'wallet',
      processors: ['paypal_wallet'],
      configuration: {
        express: true, // Default: true. Set false to prompt user account confirmation.
      },
    },
  ],
  callbacks,
});

Estilo dinámico y actualización del pedido#

Personaliza la apariencia de forma dinámica (setCustomStyle)

Actualiza colores, logotipos o fuentes del widget dinámicamente (por ejemplo, cambiar la marca del encabezado al detectar el BIN de la tarjeta):

JavaScript
await deunaSDK.setCustomStyle({
  theme: {
    colors: {
      primaryTextColor: '#023047',
      buttonPrimaryFill: '#FFB703',
      buttonPrimaryText: '#000000',
    },
  },
});

Actualiza totales del pedido (refetchOrder)

Al ofrecer promociones específicas de franquicia (por ejemplo, "15% de descuento con Mastercard"), escucha onCardBinDetected, recalcula los totales del pedido en tu backend y notifica al widget:

JavaScript
callbacks: {
  onCardBinDetected: async (metadata) => {
    if (metadata?.cardBrand === 'Mastercard') {
      // 1. Notify your backend to apply discount to order
      await applyDiscountOnBackend(orderId, 'MASTERCARD_15');

      // 2. Refresh widget to display updated totals
      const updatedOrder = await deunaSDK.refetchOrder();
      console.log('Order refreshed with discount:', updatedOrder);
    }
  },
}

Experiencias disponibles#

ExperienciaMétodoInformación necesaria
Widget de pagoinitPaymentWidget(...)orderToken, callbacks, opcional mode
Caja de PagoinitElements(...)callbacks types puede omitirse
Haga clic para pagarinitElements(...)types: [{name: 'click_to_pay'}]
Siguiente AccióninitNextAction(...)token de pedido, notificaciones y mode
valeinitVoucherWidget(...)token de pedido, notificaciones y mode

El SDK también expone setCustomStyle(...), refetchOrder(), getWidgetState(), isValid(), submit()y close() Para el controlador activo.

Almacén de pagos y Pago con un clic#

La solución Card Vault y Elements integra tokenización de tarjetas, gestión de billeteras de clientes y Click to Pay sin requerir una transacción de pago inmediata:

  • Card Vault: Permite a los clientes agregar, almacenar y gestionar tarjetas de crédito y débito de forma segura para compras futuras.
  • Haga clic para pagar: Ofrece una experiencia de checkout sin fricciones aprovechando tokens de red global (Visa, Mastercard, etc.).

Mostrar en un modal

Sigue estos pasos para mostrar el widget Card Vault o Elements en un modal:

JavaScript
import { DeunaSDK, DeunaWidget, Mode } from '@deuna/react-native-sdk';

const onShowVaultModal = async () => {
  await deunaSDK.initElements({
    userToken: '<DEUNA_USER_TOKEN>', // Optional
    userInfo: {
      firstName: 'Ada',
      lastName: 'Lovelace',
      email: 'ada@example.com', // Required
    },
    types: [{ name: 'vault' }], // Default experience
    mode: Mode.MODAL,
    callbacks: {
      onSuccess: async (data) => {
        await deunaSDK.close(); // Close modal and release resources
        console.log('Card tokenized successfully:', data);
      },
      onError: async (error) => {
        console.error('Vault error:', error);
        await deunaSDK.close();
      },
      onClosed: (action) => {
        console.log('Vault closed:', action);
      },
      onEventDispatch: (type, response) => {
        console.log('Vault event:', type, response);
      },
    },
    widgetExperience: {
      userExperience: {
        showSavedCardFlow: true, // Optional: toggle for saving card
        defaultCardFlow: false,  // Optional: toggle for saving card as default
      },
    },
  });
};

Mostrar en modo incrustado

Para incrustar el formulario Vault o Click to Pay dentro del diseño de tu pantalla, pasa mode: Mode.EMBEDDED. Asegúrate de que <DeunaWidget /> esté envuelto en un contenedor que defina sus dimensiones:

JavaScript
import { useEffect } from 'react';
import { View, Button } from 'react-native';
import { DeunaSDK, DeunaWidget, Mode } from '@deuna/react-native-sdk';

export function EmbeddedVaultScreen({ deunaSDK }) {
  useEffect(() => {
    return () => {
      deunaSDK.close(); // Release resources on screen unmount
    };
  }, [deunaSDK]);

  const handleOpenEmbeddedVault = async () => {
    await deunaSDK.initElements({
      mode: Mode.EMBEDDED,
      userInfo: {
        email: 'ada@example.com',
      },
      callbacks: {
        onSuccess: async (data) => {
          await deunaSDK.close();
          console.log('Tokenization successful:', data);
        },
        onError: (error) => console.error(error),
      },
    });
  };

  return (
    <View style={{ flex: 1 }}>
      <View style={{ flex: 1, width: '100%' }}>
        <DeunaWidget instance={deunaSDK} />
      </View>
      <Button title="Agregar tarjeta guardada" onPress={handleOpenEmbeddedVault} />
    </View>
  );
}

Referencia de parámetros para initElements

ParámetroTipoDescripción
callbacksobjectRequerido. Oyentes de eventos para onSuccess, onError, onClosed, onCardBinDetectedy onEventDispatch.
userInfoobjectInformación del cliente. email es requerido (incluso al pasar un userToken). firstName y lastName son opcionales si userToken se proporciona.
userTokenstringOpcional. Token de portador del usuario de DEUNA.

importante: Al pasar ambos userToken y orderToken, el correo electrónico vinculado a userToken debe coincidir con el billing_address.email del pedido para mostrar tarjetas guardadas por motivos de seguridad.
orderTokenstringOpcional. Token del pedido al tokenizar en el contexto de un pedido de checkout existente.
typesobject[]Opcional. Experiencia del widget a renderizar: [{ name: 'vault' }] (predeterminado) o [{ name: 'click_to_pay' }]. Si se omite, el valor predeterminado es Vault.
modeModeMode.MODAL (predeterminado) o Mode.EMBEDDED.
widgetExperienceobjectOpcional. Anula la configuración del comerciante: userExperience.showSavedCardFlow (muestra el interruptor para guardar tarjeta) y userExperience.defaultCardFlow (muestra el interruptor para guardar tarjeta como predeterminada).
styleFilestringOpcional. UUID de una hoja de estilos/tema personalizado configurado en DEUNA.
languagestringOpcional. Código de idioma ("es", "en", "pt"). Anula el valor predeterminado del comerciante.
hidePayButtonbooleanOpcional. Cuando está embebido, oculta el botón de acción para ejecución manual con isValid() y submit().
domainstringOpcional. Anula el host base (reemplaza https://elements.deuna.com/vault con su dominio personalizado).

Integración Click to Pay

Para renderizar el widget Click to Pay, establezca types: [{ name: 'click_to_pay' }].

JavaScript
await deunaSDK.initElements({
  userInfo: {
    firstName: 'Ada',
    lastName: 'Lovelace',
    email: 'ada@example.com', // Required for Click to Pay
  },
  types: [
    {
      name: 'click_to_pay',
    },
  ],
  callbacks: {
    onSuccess: async (data) => {
      await deunaSDK.close();
      console.log('Click to Pay success:', data);
    },
    onError: (error) => console.error('Click to Pay error:', error),
    onClosed: (action) => console.log('Widget closed:', action),
  },
});

Soporte nativo para Apple Pay y Google Pay#

Verifique la configuración del comerciante y el soporte de dispositivos antes de mostrar el botón de la billetera. Los valores devueltos son: apple_pay y google_pay.

JavaScript
const userInfo = {email: 'ada@example.com'};
const wallets = await deunaSDK.getWalletsAvailable({
  orderToken,
  userInfo,
});

setShowApplePay(wallets.includes('apple_pay'));
setShowGooglePay(wallets.includes('google_pay'));

Una vez que la disponibilidad se haya confirmado, inicie la hoja nativa al pulsar el botón. Para Apple Pay, mantenga esta llamada directamente en la acción del usuario.

JavaScript
const launchWallet = (provider: 'apple_pay' | 'google_pay') => {
  const type = provider === 'apple_pay' ? 'APPLE_PAY' : 'GOOGLE_PAY';

  deunaSDK.initElements({
    orderToken,
    userInfo,
    types: [{name: type}],
    callbacks: {
      onSuccess: (credential) => useSavedCredential(credential),
      onError: (error) => showRetry(error),
      onClosed: () => showPaymentMethods(),
    },
  });
};

Apple Pay requiere la autorización iOS y el identificador del comerciante. Google Pay requiere la habilitación del comerciante y un dispositivo Android compatible. Consulte de Apple Pay y pago de google.

Continúe con una acción pendiente#

Utilice el mismo token de pedido cuando DEUNA informe que el pago requiere un desafío o redirección 3DS compatible.

JavaScript
await deunaSDK.initNextAction({
  orderToken,
  mode: Mode.MODAL,
  callbacks: {
    onSuccess: (order) => showConfirmation(order),
    onError: (error) => showRetry(error),
    onClosed: () => showPaymentMethods(),
  },
});

Abrir un cupón#

JavaScript
await deunaSDK.initVoucherWidget({
  orderToken,
  mode: Mode.MODAL,
  callbacks: {
    onSuccess: (order) => showVoucherInstructions(order),
    onError: (error) => showRetry(error),
    onClosed: () => showPaymentMethods(),
    onDownloadFile: (file) => saveVoucher(file),
  },
});

Maneje las redirecciones externas#

A partir de v2.0.0, los métodos de pago que requieren funcionalidad nativa del navegador (como Billetera Mercado Pago) deben abrirse en Custom Tabs (Android) o Safari View Controller (iOS) para garantizar el manejo seguro de sesiones y la persistencia de cookies. Para admitir esto, proporcione un inAppBrowserAdapter que implemente la interfaz InAppBrowserAdapter durante DeunaSDK.initialize.

Opción A: Usando @deuna/react-native-in-app-browser (Metro / Expo)

Si usa Metro o Expo, instale @deuna/react-native-in-app-browser y pase ExpoWebBrowserAdapter:

JavaScript
import { DeunaSDK } from '@deuna/react-native-sdk';
import { ExpoWebBrowserAdapter } from '@deuna/react-native-in-app-browser';

const deunaSDK = DeunaSDK.initialize({
  publicApiKey: 'YOUR_PUBLIC_API_KEY',
  environment: 'sandbox',
  inAppBrowserAdapter: new ExpoWebBrowserAdapter(),
});

Opción B: Usando react-native-inappbrowser-reborn (Webpack / Personalizado)

Si usa Webpack o empaquetadores personalizados incompatibles con los módulos de Expo, use react-native-inappbrowser-reborn:

Shell
npm install react-native-inappbrowser-reborn
# or
yarn add react-native-inappbrowser-reborn

Implemente el adaptador:

JavaScript
import { Linking } from 'react-native';
import InAppBrowser from 'react-native-inappbrowser-reborn';
import { InAppBrowserAdapter, DeunaSDK } from '@deuna/react-native-sdk';

class InAppBrowserRebornAdapter implements InAppBrowserAdapter {
  async openUrl(url: string): Promise<void> {
    try {
      if (await InAppBrowser.isAvailable()) {
        await InAppBrowser.open(url, {
          dismissButtonStyle: 'cancel',
          preferredBarTintColor: '#023047',
          preferredControlTintColor: '#FFFFFF',
          readerMode: false,
          animated: true,
        });
      } else {
        // Fallback to external browser
        await Linking.openURL(url);
      }
    } catch (error) {
      console.error('Error opening in-app browser:', error);
      throw error;
    }
  }
}

const deunaSDK = DeunaSDK.initialize({
  publicApiKey: 'YOUR_PUBLIC_API_KEY',
  environment: 'sandbox',
  inAppBrowserAdapter: new InAppBrowserRebornAdapter(),
});

Datos del dispositivo y huella digital para fraude#

Usa la DeunaSDK.initializeFraudProviders(...) función estática para preparar proveedores en segundo plano, y el deunaSDK.generateFraudId(...) método de instancia (o el parámetro fraudCredentials en los inicializadores del widget) para generar una carga útil de fraude unificada de DEUNA.

El SDK de React Native de DEUNA usa una arquitectura modular basada en reflexión (sin bloat): no incluye SDKs de fraude de terceros por defecto. Solo agregue el(los) proveedor(es) específico(s) que planea usar. Si no usa un proveedor, no paga penalización de tamaño de aplicación.

Proveedores compatibles

ProveedorDescripciónParámetros requeridos
MERCADOPAGOPerfilado de comportamiento del dispositivo de Mercado Pago(Ninguno requerido)
RISKIFIEDBeaconing de Riskified BeaconstoreDomain
CYBERSOURCEPerfilado de CyberSource ThreatMetrixorgId, merchantId (Opcional: fpServer)
SIGNIFYDPerfilado de Signifyd ThreatMetrixorgId (Opcional: fpServer)
ACCERTIFYPerfilado de Accertify InMobileArchivos de configuración en assets/bundle (Opcional: locationConsent, phoneConsent)
KOUNTRecolector de datos de KountmerchantId, clientId, dataCollectorUrl, environment
SIFTPerfilado de dispositivos de Sift ScienceaccountId, beaconKey

Vinculación de dependencias

Sigue la configuración correspondiente a tu entorno de proyecto (exposición o Reaccionar CLI nativa).

A. Expo (Config Plugin)

En proyectos de Expo que usan Generación Nativa Continua (CNG) o EAS Build, habilita solo los proveedores que tienes contratados listándolos en el fraudProviders array en app.json:

app.jsonJSON
{
  "expo": {
    "plugins": [
      [
        "@deuna/react-native-sdk",
        {
          "fraudProviders": [
            "mercadopago",
            "riskified"
          ]
        }
      ]
    ]
  }
}

Claves admitidas en fraudProviders: "mercadopago", "riskified", "cybersource", "signifyd", "accertify", "kount", "sift".

Después de actualizar app.json, regenera los proyectos nativos:

Shell
npx expo prebuild --clean

B. React Native CLI

En proyectos estándar de React Native CLI, agrega dependencias nativas solo para los proveedores que necesitas en tus archivos de aplicación host:

Configuración de Android
  1. Repositorio Maven de Mercado Pago: Si usas Mercado Pago, asegúrate de que el repositorio Maven de Mercado Libre esté incluido en android/build.gradle (o settings.gradle):
GROOVY
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://artifacts.mercadolibre.com/repository/android-releases/" }
    }
}
  1. Ubicación de AAR del proveedor: Si usas Cybersource, Signifyd o Accertify, descarga los AAR del proveedor y colócalos en android/app/libs/:

    • fuente cibernética: Coloca los archivos AAR en android/app/libs/cybersource/.
    • significado: Coloca los archivos AAR en android/app/libs/signifyd/.
    • Acreditar: Coloca inmobile y inmobile-common Archivos AAR en android/app/libs/accertify/.
  2. Dependencias: Agrega solo los proveedores que necesites dentro de android/app/build.gradle bajo dependencies { ... }:

android/app/build.gradleGROOVY
dependencies {
    // --- Add ONLY the providers you use ---

    // Mercado Pago
    implementation("com.mercadolibre.android.device:sdk:4.0.1")

    // Riskified
    implementation("com.riskified:android-sdk:1.11.0:nogoogle@aar")

    // CyberSource (AARs placed in app/libs/cybersource)
    implementation(fileTree(dir: "libs/cybersource", include: ["*.aar"]))

    // Signifyd (AARs placed in app/libs/signifyd)
    implementation(fileTree(dir: "libs/signifyd", include: ["*.aar"]))

    // Accertify (AARs placed in app/libs/accertify + required transitive dependencies)
    implementation(fileTree(dir: "libs/accertify", include: ["*.aar"]))
    implementation("io.insert-koin:koin-core:3.5.6")
    implementation("androidx.biometric:biometric:1.1.0")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")

    // Kount
    implementation("com.kount:kount-data-collector:4.1.0")

    // Sift
    implementation("sift-android:sift-android:0.14.0")
}
  1. Recursos de Accertify:
    • androide: Coloca server_keys_message_hosted.json y inmobile.properties en android/app/src/main/assets/.
    • iOS: Agrega server_keys_message_hosted.json y InMobile.plist a tu proyecto de Xcode bajo Copy Bundle Resources target.
Configuración de iOS (ios/Podfile)

Dentro de tu bloque target 'YourApp' do , agrega solo los subspecs para los proveedores que necesites:

ios/PodfileRuby
target 'YourApp' do
  # Add ONLY the subspecs you need:
  pod 'DeunaSDK/MercadoPago'
  pod 'DeunaSDK/Riskified'
  pod 'DeunaSDK/Cybersource'
  pod 'DeunaSDK/Signifyd'
  pod 'DeunaSDK/Kount'
  pod 'DeunaSDK/Sift'
  pod 'DeunaSDK/Accertify'
end

Luego ejecuta:

Shell
cd ios && pod install

Detalles y restricciones del proveedor

RISKIFIED

  • Requerido: storeDomain
  • Ejemplo de configuración:
    JSON
    {
      "RISKIFIED": {
        "storeDomain": "yourdomain.com"
      }
    }

CYBERSOURCE

  • Requerido: orgId, merchantId
  • Opcional: fpServer (predeterminado: h.online-metrix.net)
  • Ejemplo de configuración:
    JSON
    {
      "CYBERSOURCE": {
        "orgId": "your_org_id",
        "merchantId": "your_merchant_id"
      }
    }

SIGNIFYD

  • Requerido: orgId
  • Opcional: fpServer (predeterminado: imgs.signifyd.com)
  • Ejemplo de configuración:
    JSON
    {
      "SIGNIFYD": {
        "orgId": "your_org_id"
      }
    }

ACCERTIFY

  • Opcional: locationConsent (predeterminado: true), phoneConsent (predeterminado: true)
  • Archivos requeridos: El archivo de clave de cifrado pública server_keys_message_hosted.json y las propiedades del endpoint (inmobile.properties en Android src/main/assets/ y InMobile.plist en los recursos del bundle de iOS) deben obtenerse de Accertify durante la incorporación del comercio.
  • Dependencias transitivas (Android): El AAR de Accertify requiere Koin DI (io.insert-koin:koin-core:3.5.6), AndroidX Biometric (androidx.biometric:biometric:1.1.0) y Kotlinx Serialization (org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3).
  • Ejemplo de configuración:
    JSON
    {
      "ACCERTIFY": {
        "locationConsent": true,
        "phoneConsent": false
      }
    }

KOUNT

  • Requerido: merchantId, clientId, dataCollectorUrl, environment
  • Ejemplo de configuración:
    JSON
    {
      "KOUNT": {
        "merchantId": "your_merchant_id",
        "clientId": "your_client_id",
        "dataCollectorUrl": "https://...",
        "environment": "TEST"
      }
    }

SIFT

  • Requerido: accountId, beaconKey
  • Ejemplo de configuración:
    JSON
    {
      "SIFT": {
        "accountId": "your_account_id",
        "beaconKey": "your_beacon_key"
      }
    }

MERCADOPAGO

  • Requerido: Ninguno ({})
  • androide: Requiere el repositorio Maven de Mercado Libre (https://artifacts.mercadolibre.com/repository/android-releases/) y la dependencia com.mercadolibre.android.device:sdk:4.0.1.
  • iOS: Vinculado mediante pod 'DeunaSDK/MercadoPago'.
  • Ejemplo de configuración:
    JSON
    {
      "MERCADOPAGO": {}
    }

Inicialización en segundo plano temprana

Debido a que initializeFraudProviders es un método estático, se puede ejecutar en segundo plano antes de instanciar o lanzar cualquier widget de checkout:

JavaScript
import { useEffect } from 'react';
import { DeunaSDK } from '@deuna/react-native-sdk';

const CartScreen = () => {
  useEffect(() => {
    // Pre-warm fraud SDKs as soon as the cart or store view mounts
    DeunaSDK.initializeFraudProviders({
      MERCADOPAGO: {},
    });
  }, []);

  return (
    // Your cart UI components
  );
};

Opciones de implementación

Opción 1: Llamada directa mediante método de instancia (generateFraudId)

generateFraudId es un método de instancia en tu instancia inicializada de DeunaSDK . Utiliza automáticamente tu configuración de publicApiKey y environment:

JavaScript
import { DeunaSDK } from '@deuna/react-native-sdk';

const deunaSDK = DeunaSDK.initialize({
  publicApiKey: 'YOUR_PUBLIC_API_KEY',
  environment: 'production',
});

async function getFraudToken() {
  const fraudId = await deunaSDK.generateFraudId({
    RISKIFIED: {
      storeDomain: 'yourdomain.com',
    },
    MERCADOPAGO: {},
  });

  // Returns a Base64-encoded JSON string or null
  console.log('Base64 Fraud ID:', fraudId);

  if (fraudId) {
    const decoded = atob(fraudId);
    console.log('Decoded Tokens:', JSON.parse(decoded));
  }
}

Opción 2: Pasar fraudCredentials directamente a los widgets

Al usar widgets de pago de DEUNA (initPaymentWidget, initElements, initNextAction, initVoucherWidget), pasa tu configuración de proveedor directamente mediante fraudCredentials. El SDK llama a generateFraudId internamente en el momento de la compra:

JavaScript
await deunaSDK.initPaymentWidget({
  orderToken: 'YOUR_ORDER_TOKEN',
  mode: Mode.MODAL,
  callbacks: {
    onSuccess: (data) => console.log('Payment success:', data),
    onError: (error) => console.error('Payment error:', error),
    onClosed: () => console.log('Widget closed'),
  },
  fraudCredentials: {
    RISKIFIED: {
      storeDomain: 'yourdomain.com',
    },
    MERCADOPAGO: {},
  },
});

Comportamiento y características de tiempo de ejecución

  • Sin inflado y seguro ante fallos: Si un proveedor está incluido en la solicitud JSON pero su dependencia nativa no se agregó a la aplicación, la reflexión nativa lo ignora de forma segura sin lanzar una excepción no controlada o causar un fallo.
  • Ejecución en paralelo: Todos los proveedores solicitados se perfilan concurrentemente en hilos en segundo plano.
  • Comportamiento de respaldo: Si no hay proveedores válidos configurados o disponibles en el dispositivo, generateFraudId se resuelve a null.

Referencia del ciclo de vida y llamadas de retorno#

El initPaymentWidget y los inicializadores de Elements aceptan callbacks tipados para observar el progreso del pago, actualizar la UI y liberar recursos.

CallbackModalIntegrado¿Cuándo se activa?
onSuccess✅✅Pago exitoso. Contiene datos de pedido en JSON. Siempre llama a await deunaSDK.close() para liberar los recursos del widget.
onError✅✅Ocurrió un error durante la carga o el procesamiento del checkout. Recibe un PaymentsError.
onClosed✅❌Modal cerrado. Recibe userAction (cerrado por el cliente) o systemAction (cerrado mediante close()). Nota: no se activa en modo embebido.
onPaymentProcessing✅✅El cliente hizo clic en el botón de pago y el procesamiento ha comenzado. Úselo para deshabilitar botones y mostrar indicadores de progreso.
onCardBinDetected✅✅Se activa cuando se detecta o se borra un BIN de tarjeta (devuelve null cuando el usuario borra el número). Úselo para descuentos de franquicia.
onInstallmentSelected✅✅Se activa cuando el cliente selecciona un plan de cuotas (devuelve null en el pago único completo).
onDownloadFile✅✅Se activa cuando el cliente solicita la descarga de un comprobante o recibo.
onEventDispatch✅✅Emite todas las ocurrencias subyacentes de CheckoutEvent para registro personalizado y análisis.

Manejo de errores (onError)

Inspeccione el error type para distinguir fallas de inicialización de rechazos de pago:

JavaScript
onError: async (error) => {
  switch (error.type) {
    case 'INITIALIZATION_FAILED':
      // Widget could not load; release controller and retry or notify user
      await deunaSDK.close();
      showToast('Payment system currently unavailable');
      break;
    case 'PAYMENT_ERROR':
      // Card declined or processor rejection
      showRetryScreen(error.message);
      break;
    default:
      console.warn('Unhandled payment error:', error);
      break;
  }
}

Manejo de descargas de archivos (onDownloadFile)

Cuando las instrucciones de pago con voucher o en efectivo ofrecen recibos o códigos de barras:

JavaScript
callbacks: {
  onDownloadFile: (file) => {
    const { type, data } = file;
    if (type === 'url') {
      // Download or open external receipt URL
      Linking.openURL(data);
    } else if (type === 'base64') {
      // Save base64 image or PDF to local file system
      saveBase64ToGallery(data);
    }
  },
}

Liberación de recursos (close)

El close() El método libera los controladores internos de WebView y elimina las suscripciones a eventos. Llame siempre a deunaSDK.close() en onSuccess y en los hooks de desmontaje de pantalla (useEffect cleanup) para widgets incrustados.

Ejemplos y código fuente oficiales#

Ver ModalScreen.tsx, EmbeddedScreen.tsxy WalletsScreen.tsx Para flujos completos y ejecutables.

En esta sección