SDK de React Native
Instale el SDK de React Native de DEUNA e integre widgets, carteras nativas, redirecciones y flujos de fraude de dispositivos.
En esta página
- Requisitos
- Instale el SDK
- Inicializa y monta el renderizador
- Abrir widget de pago
- Integrar un widget
- Filtrar y configurar métodos de pago
- Estilo dinámico y actualización del pedido
- Experiencias disponibles
- Almacén de pagos y Pago con un clic
- Soporte nativo para Apple Pay y Google Pay
- Continúe con una acción pendiente
- Abrir un cupón
- Maneje las redirecciones externas
- Datos del dispositivo y huella digital para fraude
- Referencia del ciclo de vida y llamadas de retorno
- Ejemplos y código fuente oficiales
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 24o 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-sdknpm i @deuna/react-native-sdkpnpm add @deuna/react-native-sdkAgregue los requeridos react-native-webview (≥ 13.15.0) dependencia de pares:
yarn add react-native-webviewnpm i react-native-webviewpnpm add react-native-webview2. 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:
cd ios && pod installExpo (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:
{
"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:
npx expo prebuild3. 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.
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:
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
| Atributo | Tipo | Modal | Integrado | Descripción |
|---|---|---|---|---|
orderToken | string | ✅ | ✅ | 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. |
callbacks | object | ✅ | ✅ | Requerido. Funciones callback que manejan eventos del widget (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onDownloadFile, onEventDispatch). |
mode | Mode | ✅ | ✅ | Mode.MODAL (predeterminado) o Mode.EMBEDDED. |
userToken | string | ✅ | ✅ | 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. |
styleFile | string | ✅ | ✅ | Opcional. UUID proporcionado por DEUNA para aplicar personalización de marca de tema personalizado (colores, tipografía, logo). |
paymentMethods | object[] | ✅ | ✅ | 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. |
language | string | ✅ | ✅ | Opcional. Código de idioma ("es", "en", "pt"). Anula la configuración predeterminada del comerciante. |
behavior | object | ✅ | ✅ | Opcional. Personalización del flujo, como behavior: { paymentMethods: { flowType: "twoStep" } } para PayPal. |
fraudCredentials | object | ✅ | ✅ | Opcional. Credenciales del proveedor de fraude (ej. { RISKIFIED: { storeDomain: 'example.com' } }). |
domain | string | ✅ | ✅ | Opcional. Anula el host base predeterminado (https://pay.deuna.io). |
hidePayButton | boolean | ❌ | ✅ | 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.
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:
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étodo | Descripción | Valor 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.
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:
| Prioridad | Fuente | Comportamiento |
|---|---|---|
| 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. |
| 2 | include_payment_options en la creación de la orden | Selecció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:
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:
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):
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:
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#
| Experiencia | Método | Información necesaria |
|---|---|---|
| Widget de pago | initPaymentWidget(...) | orderToken, callbacks, opcional mode |
| Caja de Pago | initElements(...) | callbacks types puede omitirse |
| Haga clic para pagar | initElements(...) | types: [{name: 'click_to_pay'}] |
| Siguiente Acción | initNextAction(...) | token de pedido, notificaciones y mode |
| vale | initVoucherWidget(...) | 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:
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:
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ámetro | Tipo | Descripción |
|---|---|---|
callbacks | object | Requerido. Oyentes de eventos para onSuccess, onError, onClosed, onCardBinDetectedy onEventDispatch. |
userInfo | object | Información del cliente. email es requerido (incluso al pasar un userToken). firstName y lastName son opcionales si userToken se proporciona. |
userToken | string | Opcional. 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. |
orderToken | string | Opcional. Token del pedido al tokenizar en el contexto de un pedido de checkout existente. |
types | object[] | Opcional. Experiencia del widget a renderizar: [{ name: 'vault' }] (predeterminado) o [{ name: 'click_to_pay' }]. Si se omite, el valor predeterminado es Vault. |
mode | Mode | Mode.MODAL (predeterminado) o Mode.EMBEDDED. |
widgetExperience | object | Opcional. 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). |
styleFile | string | Opcional. UUID de una hoja de estilos/tema personalizado configurado en DEUNA. |
language | string | Opcional. Código de idioma ("es", "en", "pt"). Anula el valor predeterminado del comerciante. |
hidePayButton | boolean | Opcional. Cuando está embebido, oculta el botón de acción para ejecución manual con isValid() y submit(). |
domain | string | Opcional. 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' }].
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.
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.
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.
await deunaSDK.initNextAction({
orderToken,
mode: Mode.MODAL,
callbacks: {
onSuccess: (order) => showConfirmation(order),
onError: (error) => showRetry(error),
onClosed: () => showPaymentMethods(),
},
});Abrir un cupón#
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:
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:
npm install react-native-inappbrowser-reborn
# or
yarn add react-native-inappbrowser-rebornImplemente el adaptador:
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
| Proveedor | Descripción | Parámetros requeridos |
|---|---|---|
MERCADOPAGO | Perfilado de comportamiento del dispositivo de Mercado Pago | (Ninguno requerido) |
RISKIFIED | Beaconing de Riskified Beacon | storeDomain |
CYBERSOURCE | Perfilado de CyberSource ThreatMetrix | orgId, merchantId (Opcional: fpServer) |
SIGNIFYD | Perfilado de Signifyd ThreatMetrix | orgId (Opcional: fpServer) |
ACCERTIFY | Perfilado de Accertify InMobile | Archivos de configuración en assets/bundle (Opcional: locationConsent, phoneConsent) |
KOUNT | Recolector de datos de Kount | merchantId, clientId, dataCollectorUrl, environment |
SIFT | Perfilado de dispositivos de Sift Science | accountId, 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:
{
"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:
npx expo prebuild --cleanB. 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
- 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(osettings.gradle):
allprojects {
repositories {
google()
mavenCentral()
maven { url "https://artifacts.mercadolibre.com/repository/android-releases/" }
}
}-
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
inmobileyinmobile-commonArchivos AAR enandroid/app/libs/accertify/.
- fuente cibernética: Coloca los archivos AAR en
-
Dependencias: Agrega solo los proveedores que necesites dentro de
android/app/build.gradlebajodependencies { ... }:
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")
}- Recursos de Accertify:
- androide: Coloca
server_keys_message_hosted.jsonyinmobile.propertiesenandroid/app/src/main/assets/. - iOS: Agrega
server_keys_message_hosted.jsonyInMobile.plista tu proyecto de Xcode bajo Copy Bundle Resources target.
- androide: Coloca
Configuración de iOS (ios/Podfile)
Dentro de tu bloque target 'YourApp' do , agrega solo los subspecs para los proveedores que necesites:
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'
endLuego ejecuta:
cd ios && pod installDetalles 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.jsony las propiedades del endpoint (inmobile.propertiesen Androidsrc/main/assets/yInMobile.plisten 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 dependenciacom.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:
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:
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:
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,
generateFraudIdse resuelve anull.
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.
| Callback | Modal | Integrado | ¿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:
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:
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.