Aller au contenu principal
Sur cette page

Utilisez le SDK React Native DEUNA pour partager les intégrations de Widget de paiement, Coffre-fort de paiement, Click to Pay, action suivante, bon et portefeuille natif entre les applications iOS et Android.

Exigences#

Pour utiliser le SDK React Native DEUNA, vous avez besoin de :

  • Node.js: 20 ou supérieur
  • Gestionnaire de paquets: Yarn ou npm
  • React: 18.2.0 ou supérieur
  • Réagir à l'initié: 0.73.0 ou supérieur
  • React Native WebView: 13.15.0 ou supérieur
  • Expo SDK: 50 ou supérieur (pour les applications avec Expo)
  • Identifiants DEUNA: Un compte actif et des identifiants DEUNA valides (contactez support@deuna.com si vous rencontrez des retards)
  • Projet Android: minSdkVersion 24 ou supérieur
  • Appareils Huawei: HarmonyOS 2.0 ou supérieur

Installer le SDK#

Commencez l'initialisation du SDK.

1. Ajouter les dépendances

Ajoutez le SDK DEUNA à votre projet :

yarn add @deuna/react-native-sdk

Ajoutez la dépendance peer requise react-native-webview (≥ 13.15.0) :

yarn add react-native-webview

2. Liaison

À partir de la version 2.1.0, le SDK inclut un module natif qui permet d'utiliser les feuilles de paiement natives Google Pay et Apple Pay.

Réagir à la CLI native

Courir pod install pour lier le module natif sur iOS :

Shell
cd ios && pod install

Expo (workflow géré)

Ajoutez le plugin de configuration à app.json. Fournissez uniquement les droits de portefeuille et les fournisseurs de fraude que votre application utilise :

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

Exécutez prebuild pour régénérer les répertoires natifs ios/ et android/ avec le module enregistré :

Shell
npx expo prebuild

3. Guide de migration de 1.x vers 2.x.x

Initialisez et montez le rendu#

Créez une seule instance de l'SDK et conservez-la entre les rendus. Montez exactement une DeunaWidget pour cette instance. Le composant gère à la fois les flux de modal et d'intégration WebView ; l'appel à un initialiseur configure uniquement son contrôleur.

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

Ouvrir le widget de paiement#

Le Widget de Paiement est un composant intégré qui vous permet d'offrir plusieurs méthodes de paiement aux clients :

  • Cartes de crédit et de débit: Visa, Mastercard, American Express et les cartes co-brandées.
  • Méthodes de paiement alternatives (APM): OXXO, KueskiPay, Aplazo, Daviplata, Nequi, et plus.
  • Portefeuilles numériques: PayPal, Apple Pay et Google Pay.

Affichage dans une modale

Utilisation Mode.MODAL (par défaut) pour une feuille modale gérée par le SDK. Le <DeunaWidget instance={deunaSDK} /> monté présente automatiquement par-dessus votre écran :

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

Référence des paramètres

AttributTapezModalIntégréDescriptif
orderTokenstring✅✅Obligatoire. Jeton unique pour la commande créée via l'API DEUNA.

Important: Lors de la création de la commande via l'API DEUNA, ne définissez pas de redirect_url si vous voulez que le onSuccess callback s'exécute à l'intérieur de l'application mobile.
callbacksobject✅✅Obligatoire. Fonctions de callback gérant les événements du widget (onSuccess, onError, onClosed, onCardBinDetected, onInstallmentSelected, onPaymentProcessing, onDownloadFile, onEventDispatch).
modeMode✅✅Mode.MODAL (par défaut) ou Mode.EMBEDDED.
userTokenstring✅✅Facultatif. Jeton porteur DEUNA du client.

Important: Pour que les cartes enregistrées apparaissent, l'email lié au userToken doit correspondre à billing_address.email transmis lors de la création de la commande.
styleFilestring✅✅Facultatif. UUID fourni par DEUNA pour appliquer une personnalisation de thème (couleurs, typographie, logo).
paymentMethodsobject[]✅✅Facultatif. Tableau définissant une seule méthode de paiement pour lancer directement le flux de formulaires (par ex. [{ paymentMethod: 'bnpl', processors: ['kueski'] }]). Le widget s'ouvre directement dans le formulaire de cette méthode sans afficher le sélecteur de méthode. Remarque : les systèmes de paiement internes prennent actuellement en charge un seul élément.
languagestring✅✅Facultatif. Code de langue ("es", "en", "pt"). Remplace la configuration par défaut du marchand.
behaviorobject✅✅Facultatif. Personnalisation du flux, comme behavior: { paymentMethods: { flowType: "twoStep" } } pour PayPal.
fraudCredentialsobject✅✅Facultatif. Identifiants du fournisseur de fraude (par ex. { RISKIFIED: { storeDomain: 'example.com' } }).
domainstring✅✅Facultatif. Remplace l'hôte de base par défaut (https://pay.deuna.io).
hidePayButtonboolean❌✅Facultatif. Masque le bouton de paiement intégré en mode intégré lorsque votre application affiche un bouton de paiement natif.

Intégrer un widget#

Pour afficher le widget directement dans la mise en page de votre écran, initialisez avec 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="Charger le formulaire de paiement" onPress={handleOpenEmbedded} />
    </View>
  );
}

Bouton de paiement personnalisé (hidePayButton)

Si votre application affiche son propre bouton de paiement, passez hidePayButton: true et exécutez les validations et la soumission manuellement :

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éthodeDescriptifValeur de retour
deunaSDK.isValid()Valide la saisie de l'utilisateur dans le formulaire de paiement actif.Promise<boolean>
deunaSDK.submit()Soumet le paiement équivalent à un clic sur le bouton du widget.Promise<{ status: 'success' | 'error', message?: string }>

Filtrer et configurer les méthodes de paiement#

Flux de formulaires directs (paymentMethods)

Les architectures de checkout DEUNA (checkout-base et modular-checkout) prennent en charge le lancement direct dans un formulaire de paiement individuel — un modèle connu sous le nom de flux de formulaires.

Bien que le paramètre SDK paymentMethods soit typé comme un tableau, les moteurs de checkout internes prennent actuellement en charge un seul élément dans cette liste. Fournir un seul moyen de paiement ouvre le widget directement dans le formulaire spécifique de ce moyen de paiement (par exemple, Kueski Pay BNPL), en contournant l'écran de sélection des moyens de paiement.

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

Résolution de priorité de configuration

Lors de la détermination des moyens de paiement et des formulaires à afficher, DEUNA résout les configurations dans l'ordre suivant :

PrioritéSourceComportement
1 (Priorité la plus élevée)paymentMethods dans .initPaymentWidget()Flux de formulaires directs : Ouvre immédiatement le formulaire du moyen de paiement unique spécifié (par exemple, Kueski), en contournant le sélecteur de méthode.
2include_payment_options dans la création de commandeSélection multi-méthodes : Affiche uniquement les moyens de paiement spécifiés lors de la création de la commande qui sont actifs sur votre compte.
3 (Fallback)Configuration au niveau marchand (/payment-methods)Sélecteur complet : Si omis à la fois dans l'appel SDK et dans le payload de commande, affiche tous les moyens de paiement actifs configurés pour votre compte marchand.

Configurations PayPal

Type de flux (flowType)

Contrôle si PayPal affiche un récapitulatif de commande avant le paiement ou passe directement à l'autorisation :

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

Achat automatique (express)

Lorsque les clients ont précédemment autorisé des paiements rapides avec PayPal, activez le traitement immédiat :

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

Style dynamique et rafraîchissement de commande#

Personnalisez dynamiquement l'apparence (setCustomStyle)

Mettez à jour les couleurs, logos ou polices du widget dynamiquement (par exemple, changer le branding de l'en-tête lors de la détection du BIN de carte) :

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

Rafraîchissez les totaux de commande (refetchOrder)

Lorsque vous proposez des promotions spécifiques à une franchise (par exemple, "15 % de réduction avec Mastercard"), écoutez onCardBinDetected, recalculez les totaux de commande sur votre backend et notifiez le 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);
    }
  },
}

Expériences disponibles#

ExpérienceMéthodeInformations importantes
Widget de paiementinitPaymentWidget(...)orderToken, fonctions de rappel, optionnel mode
Coffre-fort de paiementinitElements(...)Gestion des appels de retour. types Peut être omis
Cliquez pour payerinitElements(...)types: [{name: 'click_to_pay'}]
Prochaine étapeinitNextAction(...)jeton de commande, notifications et mode
Bon de réductioninitVoucherWidget(...)jeton de commande, notifications et mode

Le SDK expose également setCustomStyle(...), refetchOrder(), getWidgetState(), isValid(), submit()et close() Pour le contrôleur actif.

Coffre-fort de paiement et Paiement en un clic#

La solution Card Vault et Elements intègre la tokenisation de carte, la gestion du portefeuille client et Click to Pay sans nécessiter une transaction de paiement immédiate :

  • Card Vault: Permet aux clients d'ajouter, stocker et gérer en toute sécurité des cartes de crédit et de débit pour des achats futurs.
  • Cliquez pour payer: Offre une expérience de checkout sans friction en s'appuyant sur les jetons de réseau globaux (Visa, Mastercard, etc.).

Affichage dans une modale

Suivez ces étapes pour afficher le widget Card Vault ou Elements dans une modale :

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

Affichage en mode intégré

Pour intégrer le formulaire Vault ou Click to Pay dans la mise en page de votre écran, passez mode: Mode.EMBEDDED. Assurez-vous que <DeunaWidget /> est encapsulé dans un conteneur qui définit ses dimensions :

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="Ajouter une carte enregistrée" onPress={handleOpenEmbeddedVault} />
    </View>
  );
}

Référence des paramètres pour initElements

ParamètreTapezDescriptif
callbacksobjectObligatoire. Écouteurs d'événements pour onSuccess, onError, onClosed, onCardBinDetectedet onEventDispatch.
userInfoobjectInformations client. email est requis (même en passant un userToken). firstName et lastName sont facultatifs si userToken est fourni.
userTokenstringFacultatif. Jeton porteur utilisateur DEUNA.

Important: Lors du passage des deux userToken et orderToken, l'e-mail lié à userToken doit correspondre à billing_address.email de la commande pour afficher les cartes enregistrées pour des raisons de sécurité.
orderTokenstringFacultatif. Jeton de commande lors de la tokenisation dans le contexte d'une commande de paiement existante.
typesobject[]Facultatif. Expérience de widget à afficher : [{ name: 'vault' }] (par défaut) ou [{ name: 'click_to_pay' }]. Si omis, par défaut Vault.
modeModeMode.MODAL (par défaut) ou Mode.EMBEDDED.
widgetExperienceobjectFacultatif. Remplace les paramètres du marchand : userExperience.showSavedCardFlow (affiche le bouton d'enregistrement de carte) et userExperience.defaultCardFlow (affiche le bouton d'enregistrement par défaut de la carte).
styleFilestringFacultatif. UUID d'une feuille de style/thème personnalisé configuré dans DEUNA.
languagestringFacultatif. Code de langue ("es", "en", "pt"). Remplace la valeur par défaut du marchand.
hidePayButtonbooleanFacultatif. Lorsqu'embarqué, masque le bouton d'action pour une exécution manuelle avec isValid() et submit().
domainstringFacultatif. Remplace l'hôte de base (remplace https://elements.deuna.com/vault par votre domaine personnalisé).

Intégration Click to Pay

Pour afficher le widget Click to Pay, définissez 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),
  },
});

Intégration native avec Apple Pay et Google Pay#

Vérifiez la configuration du commerçant et la prise en charge des appareils avant d'afficher le bouton de portefeuille. Les valeurs retournées sont : apple_pay et 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'));

Une fois la disponibilité confirmée, lancez la feuille native en réponse au clic sur le bouton. Pour Apple Pay, effectuez cette opération directement dans l'action de l'utilisateur.

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 nécessite l'autorisation iOS et l'identifiant du commerçant. Google Pay nécessite l'activation du commerçant et un appareil Android compatible. Voir Apple Payer et Google Payer.

Poursuivre une action en attente#

Utilisez le même jeton de commande lorsque DEUNA signale que le paiement nécessite un défi ou une redirection 3DS pris en charge.

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

Ouvrir un bon de réduction#

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

Gérez les redirections externes#

À partir de v2.0.0, les méthodes de paiement nécessitant une fonctionnalité native du navigateur (comme Porte-monnaie Mercado Pago) doivent s'ouvrir dans Onglets personnalisés (Android) ou Safari View Controller (iOS) pour garantir la gestion sécurisée des sessions et la persistance des cookies. Pour prendre en charge cela, fournissez un inAppBrowserAdapter implémentant l'interface InAppBrowserAdapter pendant DeunaSDK.initialize.

Option A : Utilisation de @deuna/react-native-in-app-browser (Metro / Expo)

Si vous utilisez Metro ou Expo, installez @deuna/react-native-in-app-browser et passez 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(),
});

Option B : Utilisation de react-native-inappbrowser-reborn (Webpack / Personnalisé)

Si vous utilisez Webpack ou des bundlers personnalisés incompatibles avec les modules Expo, utilisez react-native-inappbrowser-reborn:

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

Implémentez l'adaptateur :

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

Données de fraude-appareil et empreinte numérique#

Utilisez la DeunaSDK.initializeFraudProviders(...) fonction statique pour préchauffer les fournisseurs en arrière-plan, et la méthode d'instance deunaSDK.generateFraudId(...) (ou le paramètre fraudCredentials dans les initialiseurs de widget) pour générer une charge utile de fraude DEUNA unifiée.

Le SDK React Native DEUNA utilise une architecture modulaire, basée sur la réflexion (zéro encombrement): il ne regroupe pas les SDK de fraude tiers par défaut. Ajoutez uniquement le(s) fournisseur(s) spécifique(s) que vous prévoyez d'utiliser. Si vous n'utilisez pas un fournisseur, vous ne subissez aucune pénalité de taille d'application.

Fournisseurs pris en charge

FournisseurDescriptifParamètres requis
MERCADOPAGOProfilage du comportement de l'appareil Mercado Pago(Aucun requis)
RISKIFIEDBalise Riskified BeaconstoreDomain
CYBERSOURCEProfilage CyberSource ThreatMetrixorgId, merchantId (Optionnel : fpServer)
SIGNIFYDProfilage Signifyd ThreatMetrixorgId (Optionnel : fpServer)
ACCERTIFYProfilage Accertify InMobileFichiers de configuration dans assets/bundle (Optionnel : locationConsent, phoneConsent)
KOUNTCollecteur de données KountmerchantId, clientId, dataCollectorUrl, environment
SIFTProfilage d'appareil Sift ScienceaccountId, beaconKey

Liaison des dépendances

Suivez la configuration correspondant à votre environnement de projet (Exposition ou Réagir à la CLI native).

A. Expo (Plugin de configuration)

Dans les projets Expo utilisant Génération native continue (CNG) ou EAS Build, activez uniquement les fournisseurs que vous avez sous contrat en les listant dans le tableau fraudProviders dans app.json:

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

Clés prises en charge dans fraudProviders: "mercadopago", "riskified", "cybersource", "signifyd", "accertify", "kount", "sift".

Après avoir mis à jour app.json, régénérez les projets natifs :

Shell
npx expo prebuild --clean

B. React Native CLI

Dans les projets React Native CLI standard, ajoutez les dépendances natives uniquement pour les fournisseurs dont vous avez besoin dans vos fichiers d'application hôte :

Configuration Android
  1. Dépôt Maven Mercado Pago: Si vous utilisez Mercado Pago, assurez-vous que le dépôt Maven Mercado Libre est inclus dans android/build.gradle (ou settings.gradle):
GROOVY
allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url "https://artifacts.mercadolibre.com/repository/android-releases/" }
    }
}
  1. Placement des AAR du fournisseur: Si vous utilisez Cybersource, Signifyd ou Accertify, téléchargez les AAR du fournisseur et placez-les dans android/app/libs/:

    • Cybersource: Placez les fichiers AAR dans android/app/libs/cybersource/.
    • Signifiée: Placez les fichiers AAR dans android/app/libs/signifyd/.
    • Certifier: Placez inmobile et inmobile-common Fichiers AAR dans android/app/libs/accertify/.
  2. Dépendances: Ajoutez uniquement les fournisseurs que vous exigez à l'intérieur de android/app/build.gradle sous 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. Ressources Accertify:
    • Android: Placez server_keys_message_hosted.json et inmobile.properties dans android/app/src/main/assets/.
    • iOS: Ajoutez server_keys_message_hosted.json et InMobile.plist à votre projet Xcode sous Copy Bundle Resources target.
Configuration iOS (ios/Podfile)

À l'intérieur de votre bloc target 'YourApp' do , ajoutez uniquement les sous-spécifications pour les fournisseurs dont vous avez besoin :

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

Puis exécutez :

Shell
cd ios && pod install

Détails et contraintes des fournisseurs

RISKIFIED

  • Obligatoire: storeDomain
  • Exemple de configuration:
    JSON
    {
      "RISKIFIED": {
        "storeDomain": "yourdomain.com"
      }
    }

CYBERSOURCE

  • Obligatoire: orgId, merchantId
  • Facultatif: fpServer (par défaut : h.online-metrix.net)
  • Exemple de configuration:
    JSON
    {
      "CYBERSOURCE": {
        "orgId": "your_org_id",
        "merchantId": "your_merchant_id"
      }
    }

SIGNIFYD

  • Obligatoire: orgId
  • Facultatif: fpServer (par défaut : imgs.signifyd.com)
  • Exemple de configuration:
    JSON
    {
      "SIGNIFYD": {
        "orgId": "your_org_id"
      }
    }

ACCERTIFY

  • Facultatif: locationConsent (par défaut : true), phoneConsent (par défaut : true)
  • Fichiers requis: Le fichier de clé publique de chiffrement server_keys_message_hosted.json et les propriétés de point de terminaison (inmobile.properties dans Android src/main/assets/ et InMobile.plist dans les ressources du bundle iOS) doivent être obtenus auprès d'Accertify lors de l'intégration du marchand.
  • Dépendances transitives (Android): L'AAR Accertify nécessite Koin DI (io.insert-koin:koin-core:3.5.6), AndroidX Biometric (androidx.biometric:biometric:1.1.0) et Kotlinx Serialization (org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3).
  • Exemple de configuration:
    JSON
    {
      "ACCERTIFY": {
        "locationConsent": true,
        "phoneConsent": false
      }
    }

KOUNT

  • Obligatoire: merchantId, clientId, dataCollectorUrl, environment
  • Exemple de configuration:
    JSON
    {
      "KOUNT": {
        "merchantId": "your_merchant_id",
        "clientId": "your_client_id",
        "dataCollectorUrl": "https://...",
        "environment": "TEST"
      }
    }

SIFT

  • Obligatoire: accountId, beaconKey
  • Exemple de configuration:
    JSON
    {
      "SIFT": {
        "accountId": "your_account_id",
        "beaconKey": "your_beacon_key"
      }
    }

MERCADOPAGO

  • Obligatoire: Aucun ({})
  • Android: Nécessite le dépôt Maven Mercado Libre (https://artifacts.mercadolibre.com/repository/android-releases/) et la dépendance com.mercadolibre.android.device:sdk:4.0.1.
  • iOS: Lié via pod 'DeunaSDK/MercadoPago'.
  • Exemple de configuration:
    JSON
    {
      "MERCADOPAGO": {}
    }

Initialisation en arrière-plan anticipée

Parce que initializeFraudProviders est une méthode statique, elle peut être exécutée en arrière-plan avant d'instancier ou de lancer tout widget de paiement :

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

Options d'implémentation

Option 1 : Appel direct via méthode d'instance (generateFraudId)

generateFraudId est une méthode d'instance sur votre instance initialisée de DeunaSDK . Elle utilise automatiquement votre configuration publicApiKey et 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));
  }
}

Option 2 : Transmettre fraudCredentials directement aux widgets

Lors de l'utilisation des widgets de paiement DEUNA (initPaymentWidget, initElements, initNextAction, initVoucherWidget), transmettez votre configuration de fournisseur directement via fraudCredentials. Le SDK appelle generateFraudId en interne au moment de l'achat :

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

Comportement et caractéristiques d'exécution

  • Zéro surcharge et résistant aux plantages: Si un fournisseur est inclus dans la requête JSON mais que sa dépendance native n'a pas été ajoutée à l'application, la réflexion native l'ignore en toute sécurité sans lever d'exception non gérée ni planter.
  • Exécution parallèle: Tous les fournisseurs demandés effectuent le profilage simultanément sur des threads d'arrière-plan.
  • Comportement de repli: Si aucun fournisseur valide n'est configuré ou disponible sur l'appareil, generateFraudId se résout en null.

Référence des callbacks et du cycle de vie#

Le initPaymentWidget et les initialiseurs d'Elements acceptent des rappels typés pour observer la progression du paiement, mettre à jour l'interface utilisateur et libérer les ressources.

NotificationModalIntégréQuand est-il déclenché ?
onSuccess✅✅Paiement réussi. Contient les données JSON de la commande. Appelez toujours await deunaSDK.close() pour libérer les ressources du widget.
onError✅✅Erreur survenue pendant le chargement ou le traitement du paiement. Reçoit un PaymentsError.
onClosed✅❌typé. userAction Modal fermé. Reçoit systemAction (fermé par le client) ou close()). (fermé via
onPaymentProcessing✅✅Note : non déclenché en mode intégré.
onCardBinDetected✅✅Le client a cliqué sur le bouton de paiement et le traitement a commencé. Utilisez ceci pour désactiver les boutons et afficher des indicateurs de progression. null Déclenché lorsqu'un BIN de carte est détecté ou effacé (retourne
onInstallmentSelected✅✅lorsque l'utilisateur supprime le numéro). À utiliser pour les remises de franchise. null Déclenché lorsque le client sélectionne un plan de paiement échelonné (retourne
onDownloadFile✅✅en cas de paiement unique complet).
onEventDispatch✅✅Déclenché lorsque le client demande le téléchargement d'un bon ou d'un reçu. CheckoutEvent Émet toutes les occurrences sous-jacentes de

pour la journalisation personnalisée et l'analyse.onError)

Gestion des erreurs ( type Inspectez l'erreur

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

pour distinguer les échecs d'initialisation des refus de paiement :onDownloadFile)

Gestion des téléchargements de fichiers (

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

Lorsque les instructions de paiement par bon ou en espèces proposent des reçus ou des codes-barres :close)

Le close() La méthode libère les contrôleurs WebView internes et efface les abonnements aux événements. Appelez-la toujours deunaSDK.close() dans onSuccess et dans les hooks de démontage d'écran (useEffect nettoyage) pour les widgets intégrés.

Exemples et code source officiels#

Voir ModalScreen.tsx, EmbeddedScreen.tsxet WalletsScreen.tsx Pour des flux complets et exécutables.

Dans cette section