Pular para o conteúdo principal
Nesta página

Use o SDK React Native da DEUNA para compartilhar integrações de Widget de Pagamento, Payment Vault, Click to Pay, next-action, voucher e carteiras nativas entre aplicativos iOS e Android.

Requisitos#

Para usar o SDK React Native da DEUNA, você precisa de:

  • Node.js: 20 ou superior
  • Gerenciador de pacotes: Yarn ou npm
  • React: 18.2.0 ou superior
  • Reagir nativo: 0.73.0 ou superior
  • React Native WebView: 13.15.0 ou superior
  • Expo SDK: 50 ou superior (para apps com Expo)
  • Credenciais da DEUNA: Uma conta ativa e credenciais válidas da DEUNA (entre em contato com support@deuna.com se tiver algum atraso)
  • Projeto Android: minSdkVersion 24 ou superior
  • Dispositivos Huawei: HarmonyOS 2.0 ou superior

Instale o SDK#

Inicie a inicialização do SDK.

1. Adicione dependências

Adicione o SDK da DEUNA ao seu projeto:

yarn add @deuna/react-native-sdk

Adicione a dependência peer obrigatória react-native-webview (≥ 13.15.0):

yarn add react-native-webview

2. Linking

A partir da versão 2.1.0, o SDK inclui um módulo nativo que habilita telas de pagamento nativas do Google Pay e Apple Pay.

Reagir CLI nativo

Execute pod install para vincular o módulo nativo no iOS:

Shell
cd ios && pod install

Expo (managed workflow)

Adicione o config plugin ao app.json. Forneça apenas os entitlements de carteira e provedores de fraude que seu aplicativo usa:

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

Execute prebuild para regenerar os diretórios nativos ios/ e android/ com o módulo registrado:

Shell
npx expo prebuild

3. Guia de Migração de 1.x para 2.x.x

Inicialize e monte o renderer#

Crie uma única instância do SDK e mantenha-a durante as renderizações. Monte apenas uma DeunaWidget para essa instância. O componente renderiza tanto os fluxos modais quanto os WebViews incorporados; chamar o inicializador apenas configura seu 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 pagamento#

O Widget de Pagamento é um componente integrado que permite oferecer múltiplos métodos de pagamento aos clientes:

  • Cartões de crédito e débito: Visa, Mastercard, American Express e cartões co-branded.
  • Métodos de pagamento alternativos (APMs): OXXO, KueskiPay, Aplazo, Daviplata, Nequi e mais.
  • Carteiras digitais: PayPal, Apple Pay e Google Pay.

Exibir em um Modal

Uso Mode.MODAL (padrão) para uma folha modal gerenciada pelo SDK. O <DeunaWidget instance={deunaSDK} /> montado apresenta-se automaticamente sobre sua tela:

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);
      },
    },
  });
};

Referência de Parâmetros

AtributoTipoModalEmbutidoDescrição
orderTokenstring✅✅Obrigatório. Token único para o pedido criado via API DEUNA.

Importante: Ao criar o pedido via API DEUNA, não defina um redirect_url se desejar que o onSuccess callback seja executado dentro do aplicativo móvel.
callbacksobject✅✅Obrigatório. Funções de callback que tratam eventos do widget (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onDownloadFile, onEventDispatch).
modeMode✅✅Mode.MODAL (padrão) ou Mode.EMBEDDED.
userTokenstring✅✅Opcional. Token de portador DEUNA do cliente.

Importante: Para cartões salvos aparecerem, o email vinculado ao userToken deve corresponder ao billing_address.email passado durante a criação do pedido.
styleFilestring✅✅Opcional. UUID fornecido pela DEUNA para aplicar personalização de tema (cores, tipografia, logo).
paymentMethodsobject[]✅✅Opcional. Array que define um único método de pagamento para iniciar diretamente no fluxo de formulários (ex. [{ paymentMethod: 'bnpl', processors: ['kueski'] }]). O widget abre diretamente no formulário desse método sem exibir o seletor de métodos. Nota: sistemas de checkout internos atualmente suportam um elemento.
languagestring✅✅Opcional. Código de idioma ("es", "en", "pt"). Substitui a configuração padrão do lojista.
behaviorobject✅✅Opcional. Personalização de fluxo, como behavior: { paymentMethods: { flowType: "twoStep" } } para PayPal.
fraudCredentialsobject✅✅Opcional. Credenciais do provedor de fraude (ex. { RISKIFIED: { storeDomain: 'example.com' } }).
domainstring✅✅Opcional. Substitui o host base padrão (https://pay.deuna.io).
hidePayButtonboolean❌✅Opcional. Oculta o botão de pagamento embutido no modo embutido quando seu aplicativo renderiza um botão de pagamento nativo.

Incorpore um widget#

Para exibir o widget diretamente dentro do layout da sua tela, inicialize com 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="Carregar Formulário de Pagamento" onPress={handleOpenEmbedded} />
    </View>
  );
}

Botão de Pagamento Personalizado (hidePayButton)

Se seu aplicativo renderiza seu próprio botão de pagamento, passe hidePayButton: true e execute validações e envio 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étodoDescriçãoValor de Retorno
deunaSDK.isValid()Valida a entrada do usuário no formulário de pagamento ativo.Promise<boolean>
deunaSDK.submit()Envia o pagamento equivalente a clicar no botão do widget.Promise<{ status: 'success' | 'error', message?: string }>

Filtrar e configurar métodos de pagamento#

Fluxo de formulários diretos (paymentMethods)

As arquiteturas de checkout da DEUNA (checkout-base e modular-checkout) suportam o lançamento direto em um formulário de pagamento individual — um padrão conhecido como fluxo de formulários.

Embora o parâmetro do SDK paymentMethods seja tipado como um array, os motores de checkout internos atualmente suportam apenas um elemento nesta lista. Fornecer um único método de pagamento abre o widget diretamente naquele formulário específico de método de pagamento (ex.: Kueski Pay BNPL), contornando a tela de seleção de método de pagamento.

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

Resolução de prioridade de configuração

Ao determinar quais métodos e formulários de pagamento exibir, a DEUNA resolve as configurações na seguinte ordem:

PrioridadeFonteComportamento
1 (Mais alta)paymentMethods em .initPaymentWidget()Fluxo de formulários diretos: Abre imediatamente no formulário do método de pagamento único especificado (ex.: Kueski), contornando o seletor de método.
2include_payment_options na criação do pedidoSeleção de múltiplos métodos: Exibe apenas os métodos de pagamento especificados durante a criação do pedido que estão ativos na sua conta.
3 (Fallback)Configuração no nível do merchant (/payment-methods)Seletor completo: Se omitido tanto na chamada do SDK quanto no payload do pedido, exibe todos os métodos de pagamento ativos configurados para sua conta de merchant.

Configurações do PayPal

Tipo de Fluxo (flowType)

Controle se o PayPal exibe um resumo do pedido antes do pagamento ou vai diretamente para a autorização:

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

Compra Automática (express)

Quando os clientes já autorizaram pagamentos rápidos com o PayPal anteriormente, habilite o processamento imediato:

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

Estilização dinâmica e atualização do pedido#

Personalize a aparência dinamicamente (setCustomStyle)

Atualize cores, logos ou fontes do widget dinamicamente (ex.: alterando a marcação do cabeçalho após detecção do BIN do cartão):

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

Atualize totais do pedido (refetchOrder)

Ao oferecer promoções específicas de franquia (ex.: "15% de desconto com Mastercard"), escute onCardBinDetected, recalcule os totais do pedido no seu backend e notifique o 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);
    }
  },
}

Experiências disponíveis#

ExperiênciaMétodoEntrada importante
Widget de pagamentoinitPaymentWidget(...)orderToken, callbacks, opcional mode
Cofre de PagamentosinitElements(...)callbacks; types pode ser omitido
Clique para pagarinitElements(...)types: [{name: 'click_to_pay'}]
Próxima AçãoinitNextAction(...)token de pedido, callbacks, e mode
VoucherinitVoucherWidget(...)token de pedido, callbacks, e mode

O SDK também disponibiliza setCustomStyle(...), refetchOrder(), getWidgetState(), isValid(), submit()e close() para o controlador ativo.

Armazenamento de Pagamentos e Pagamento com Clique#

A solução Card Vault e Elements integra tokenização de cartão, gerenciamento de carteira do cliente e Click to Pay sem exigir uma transação de pagamento imediata:

  • Card Vault: Permite que os clientes adicionem, armazenem e gerenciem cartões de crédito e débito de forma segura para compras futuras.
  • Clique para pagar: Oferece uma experiência de checkout sem atrito aproveitando tokens de rede globais (Visa, Mastercard, etc.).

Exibir em um Modal

Siga estas etapas para exibir o widget do Card Vault ou Elements em um 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
      },
    },
  });
};

Exibir no Modo Embutido

Para embutir o formulário do Vault ou Click to Pay dentro do layout da sua tela, passe mode: Mode.EMBEDDED. Certifique-se de que <DeunaWidget /> esteja envolvido por um contêiner que define suas dimensões:

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="Adicionar Cartão Salvo" onPress={handleOpenEmbeddedVault} />
    </View>
  );
}

Referência de Parâmetros para initElements

ParâmetroTipoDescrição
callbacksobjectObrigatório. Ouvintes de evento para onSuccess, onError, onClosed, onCardBinDetectede onEventDispatch.
userInfoobjectInformações do cliente. email é obrigatório (mesmo ao passar um userToken). firstName e lastName são opcionais se userToken for fornecido.
userTokenstringOpcional. Token de portador do usuário DEUNA.

Importante: Ao passar ambos userToken e orderToken, o e-mail vinculado ao userToken deve corresponder ao billing_address.email do pedido para exibir cartões salvos por motivos de segurança.
orderTokenstringOpcional. Token do pedido ao tokenizar no contexto de um pedido de checkout existente.
typesobject[]Opcional. Experiência do widget a renderizar: [{ name: 'vault' }] (padrão) ou [{ name: 'click_to_pay' }]. Se omitido, o padrão é Vault.
modeModeMode.MODAL (padrão) ou Mode.EMBEDDED.
widgetExperienceobjectOpcional. Substitui configurações do lojista: userExperience.showSavedCardFlow (mostra o alternador de salvamento de cartão) e userExperience.defaultCardFlow (mostra o alternador de salvar cartão como padrão).
styleFilestringOpcional. UUID de uma folha de estilo/tema personalizado configurado na DEUNA.
languagestringOpcional. Código de idioma ("es", "en", "pt"). Substitui o padrão do lojista.
hidePayButtonbooleanOpcional. Quando incorporado, oculta o botão de ação para execução manual com isValid() e submit().
domainstringOpcional. Substitui o host base (substitui https://elements.deuna.com/vault pelo seu domínio personalizado).

Integração Click to Pay

Para renderizar o widget Click to Pay, defina 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),
  },
});

Apple Pay e Google Pay nativos#

Verifique a configuração do comerciante e o suporte do dispositivo antes de renderizar um botão de carteira. Os valores retornados são apple_pay e 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'));

Após a verificação, inicie a folha nativa a partir do toque no botão. Para o Apple Pay, mantenha essa chamada diretamente na ação do usuário.

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(),
    },
  });
};

O Apple Pay requer a entitlement e o identificador do comerciante. O Google Pay requer a ativação do comerciante e um dispositivo Android compatível. Consulte Apple Pague e Google Pay.

Continue uma ação pendente#

Utilize o mesmo token de pedido quando a DEUNA informar que o pagamento requer um desafio ou redirecionamento 3DS suportado.

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

Abra um cupom#

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

Gerenciar redirecionamentos externos#

A partir de v2.0.0, métodos de pagamento que exigem funcionalidade nativa do navegador (como Carteira Mercado Pago) devem abrir em Abas Personalizadas (Android) ou Safari View Controller (iOS) para garantir o manuseio seguro da sessão e a persistência de cookies. Para suportar isso, forneça um inAppBrowserAdapter implementando a interface InAppBrowserAdapter durante DeunaSDK.initialize.

Opção A: Usando @deuna/react-native-in-app-browser (Metro / Expo)

Se estiver usando Metro ou Expo, instale @deuna/react-native-in-app-browser e passe 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(),
});

Opção B: Usando react-native-inappbrowser-reborn (Webpack / Personalizado)

Se estiver usando Webpack ou empacotadores personalizados incompatíveis com módulos Expo, use react-native-inappbrowser-reborn:

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

Implemente o 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(),
});

Dados do dispositivo e fingerprinting antifraude#

Use a DeunaSDK.initializeFraudProviders(...) função estática para aquecer provedores em segundo plano, e o método de instância deunaSDK.generateFraudId(...) (ou o parâmetro fraudCredentials nos inicializadores de widget) para gerar uma carga útil de fraude DEUNA unificada.

O SDK DEUNA React Native usa uma arquitetura modular baseada em reflexão (zero inchaço): ele não agrupa SDKs de fraude de terceiros por padrão. Adicione apenas o(s) provedor(es) específico(s) que você planeja usar. Se você não usar um provedor, não há penalidade de tamanho no aplicativo.

Provedores suportados

ProvedorDescriçãoParâmetros obrigatórios
MERCADOPAGOPerfil de comportamento do dispositivo Mercado Pago(Nenhum obrigatório)
RISKIFIEDBeaconing Riskified BeaconstoreDomain
CYBERSOURCEPerfil CyberSource ThreatMetrixorgId, merchantId (Opcional: fpServer)
SIGNIFYDPerfil Signifyd ThreatMetrixorgId (Opcional: fpServer)
ACCERTIFYPerfil Accertify InMobileArquivos de configuração em assets/bundle (Opcional: locationConsent, phoneConsent)
KOUNTColetor de dados KountmerchantId, clientId, dataCollectorUrl, environment
SIFTPerfilamento de dispositivo Sift ScienceaccountId, beaconKey

Vinculação de dependências

Siga a configuração correspondente ao ambiente do seu projeto (Expo ou Reagir CLI nativo).

A. Expo (Plugin de Configuração)

Em projetos Expo que usam Geração Nativa Contínua (CNG) ou EAS Build, habilite apenas os provedores que você contratou listando-os no fraudProviders array em app.json:

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

Chaves suportadas em fraudProviders: "mercadopago", "riskified", "cybersource", "signifyd", "accertify", "kount", "sift".

Após atualizar app.json, regenere os projetos nativos:

Shell
npx expo prebuild --clean

B. React Native CLI

Em projetos padrão do React Native CLI, adicione dependências nativas apenas para os provedores que você precisa nos arquivos do aplicativo host:

Configuração Android
  1. Repositório Maven do Mercado Pago: Se usar Mercado Pago, certifique-se de que o repositório Maven do Mercado Libre está incluído em android/build.gradle (ou settings.gradle):
GROOVY
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://artifacts.mercadolibre.com/repository/android-releases/" }
    }
}
  1. Posicionamento de AARs do fornecedor: Se usar Cybersource, Signifyd ou Accertify, baixe os AARs do fornecedor e coloque-os em android/app/libs/:

    • Fonte cibernética: Coloque arquivos AAR em android/app/libs/cybersource/.
    • Significativo: Coloque arquivos AAR em android/app/libs/signifyd/.
    • Certificar: Coloque inmobile e inmobile-common Arquivos AAR em android/app/libs/accertify/.
  2. Dependências: Adicione apenas os provedores que você requer dentro de android/app/build.gradle sob 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. Assets do Accertify:
    • Android: Coloque server_keys_message_hosted.json e inmobile.properties em android/app/src/main/assets/.
    • iOS: Adicione server_keys_message_hosted.json e InMobile.plist ao seu projeto Xcode sob o Copy Bundle Resources target.
Configuração iOS (ios/Podfile)

Dentro do seu target 'YourApp' do bloco, adicione apenas os subspecs para os provedores que você precisa:

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

Em seguida, execute:

Shell
cd ios && pod install

Detalhes e restrições dos provedores

RISKIFIED

  • Obrigatório: storeDomain
  • Exemplo de configuração:
    JSON
    {
      "RISKIFIED": {
        "storeDomain": "yourdomain.com"
      }
    }

CYBERSOURCE

  • Obrigatório: orgId, merchantId
  • Opcional: fpServer (padrão: h.online-metrix.net)
  • Exemplo de configuração:
    JSON
    {
      "CYBERSOURCE": {
        "orgId": "your_org_id",
        "merchantId": "your_merchant_id"
      }
    }

SIGNIFYD

  • Obrigatório: orgId
  • Opcional: fpServer (padrão: imgs.signifyd.com)
  • Exemplo de configuração:
    JSON
    {
      "SIGNIFYD": {
        "orgId": "your_org_id"
      }
    }

ACCERTIFY

  • Opcional: locationConsent (padrão: true), phoneConsent (padrão: true)
  • Arquivos Obrigatórios: O arquivo de chave pública de criptografia server_keys_message_hosted.json e as propriedades de endpoint (inmobile.properties no Android src/main/assets/ e InMobile.plist nos recursos do bundle iOS) devem ser obtidos do Accertify durante o onboarding do merchant.
  • Dependências Transitivas (Android): O AAR do Accertify requer Koin DI (io.insert-koin:koin-core:3.5.6), AndroidX Biometric (androidx.biometric:biometric:1.1.0), e Kotlinx Serialization (org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3).
  • Exemplo de configuração:
    JSON
    {
      "ACCERTIFY": {
        "locationConsent": true,
        "phoneConsent": false
      }
    }

KOUNT

  • Obrigatório: merchantId, clientId, dataCollectorUrl, environment
  • Exemplo de configuração:
    JSON
    {
      "KOUNT": {
        "merchantId": "your_merchant_id",
        "clientId": "your_client_id",
        "dataCollectorUrl": "https://...",
        "environment": "TEST"
      }
    }

SIFT

  • Obrigatório: accountId, beaconKey
  • Exemplo de configuração:
    JSON
    {
      "SIFT": {
        "accountId": "your_account_id",
        "beaconKey": "your_beacon_key"
      }
    }

MERCADOPAGO

  • Obrigatório: Nenhum ({})
  • Android: Requer o repositório Maven do Mercado Libre (https://artifacts.mercadolibre.com/repository/android-releases/) e a dependência com.mercadolibre.android.device:sdk:4.0.1.
  • iOS: Vinculado via pod 'DeunaSDK/MercadoPago'.
  • Exemplo de configuração:
    JSON
    {
      "MERCADOPAGO": {}
    }

Inicialização em segundo plano antecipada

Porque initializeFraudProviders é um método estático, ele pode ser executado em segundo plano antes de instanciar ou lançar qualquer 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
  );
};

Opções de implementação

Opção 1: Chamada direta via método de instância (generateFraudId)

generateFraudId é um método de instância na sua instância inicializada de DeunaSDK . Ele usa automaticamente sua configuração de publicApiKey e 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));
  }
}

Opção 2: Passe fraudCredentials diretamente para os widgets

Ao usar widgets de pagamento da DEUNA (initPaymentWidget, initElements, initNextAction, initVoucherWidget), passe sua configuração de provedor diretamente via fraudCredentials. O SDK chama generateFraudId internamente no momento da 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: {},
  },
});

Comportamento e características de execução

  • Sem inchaço e seguro contra falhas: Se um provedor estiver incluído na requisição JSON, mas sua dependência nativa não foi adicionada ao app, a reflexão nativa o ignora com segurança sem lançar uma exceção não tratada ou causar falha.
  • Execução paralela: Todos os provedores solicitados realizam perfilamento simultaneamente em threads em segundo plano.
  • Comportamento de fallback: Se nenhum provedor válido estiver configurado ou disponível no dispositivo, generateFraudId resolve para null.

Referência do ciclo de vida e callbacks#

O initPaymentWidget e os inicializadores de Elements aceitam callbacks tipados para observar o progresso do pagamento, atualizar a UI e liberar recursos.

CallbackModalEmbutidoQuando é acionado?
onSuccess✅✅Pagamento bem-sucedido. Contém dados do pedido em JSON. Sempre chame await deunaSDK.close() para liberar os recursos do widget.
onError✅✅Ocorreu um erro durante o carregamento ou processamento do checkout. Recebe um PaymentsError.
onClosed✅❌tipado. userAction Modal fechado. Recebe systemAction (fechado pelo cliente) ou close()). (fechado via
onPaymentProcessing✅✅Nota: não acionado no modo embutido.
onCardBinDetected✅✅Cliente clicou no botão de pagar e o processamento começou. Use para desabilitar botões e mostrar indicadores de progresso. null Acionado quando um BIN de cartão é detectado ou limpo (retorna
onInstallmentSelected✅✅quando o usuário apaga o número). Use para descontos de franquia. null Acionado quando o cliente seleciona um plano de parcelamento (retorna
onDownloadFile✅✅no pagamento único integral).
onEventDispatch✅✅Acionado quando o cliente solicita o download de voucher ou recibo. CheckoutEvent Emite todas as ocorrências subjacentes de

para registro personalizado e análises.onError)

Tratamento de erros ( type Inspecione o erro

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;
  }
}

para distinguir falhas de inicialização de recusas de pagamento:onDownloadFile)

Tratamento de downloads de arquivos (

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);
    }
  },
}

Quando instruções de pagamento com voucher ou dinheiro oferecem recibos ou códigos de barras:close)

O close() O método libera os controladores internos do WebView e limpa as assinaturas de eventos. Sempre chame deunaSDK.close() em onSuccess e nos hooks de desmontagem de tela (useEffect cleanup) para widgets incorporados.

Exemplos e código-fonte oficiais#

Veja ModalScreen.tsx, EmbeddedScreen.tsxe WalletsScreen.tsx Para fluxos completos e executáveis.

Nesta seção