Pour toute question, nous sommes à un clic

Poser une question

Mobile SDK Core

Il s'agit plutôt d'une bibliothèque que d'un SDK. Elle est utilisée pour chiffrer les données de carte en seToken, qui peut être transmis et stocké en toute sécurité dans n'importe quel système (par exemple, sur le serveur du vendeur). C'est une bonne solution pour les commerçants qui souhaitent une flexibilité maximale ou qui ne veulent pas traiter les données de carte sur leurs serveurs.

Moyens de paiement pris en charge par ce SDK :

Moyen de paiementSupport
Carte bancaireOui
Identifiants/carte sauvegardésOui
Apple PayNon requis
Google PayNon requis

Processus de paiement SDK Core

Web View pour 3DS

Le diagramme ci-dessous montre le processus de paiement SDK Core avec redirection 3DS via Web View.

sequenceDiagram participant MA as Application mobile participant MS as Serveur mobile participant SDK as SDK participant PG as Passerelle de paiement participant 3DS as 3DSS/ACS/DS MA ->> MS: 1. le client crée une commande MS ->> PG: 2. enregistrement de commande via API PG -->> MS: 3. numéro unique de commande (mdOrder) MA ->> MA: 4. le client saisit les données MA -->> SDK: 5. génération seToken MA ->> MS: 6. envoi seToken au serveur MS ->> PG: 7. appel API de paiement alt Paiement terminé PG -->> MS: 8. réponse avec statut de paiement (Aller à 16) else 3DS2 requis PG -->> MS: 9. réponse avec redirection vers 3DS MS ->> MA: 10. ouverture Web View pour 3DS MA ->> ACS: 11. le client saisit le mot de passe ACS -->> PG: 12. redirection vers la passerelle de paiement PG ->> PG: 13. paiement PG -->> MA: 14. redirection vers returnUrl MA ->> MA: 15. fermeture Web View end opt Notifications Callback configurées PG -->> MS: 16. notification callback end MS ->> PG: 17. vérification du statut de paiement MS ->> MA: 18. affichage du résultat de paiement au client
  1. Le client crée une commande

  2. Le serveur mobile enregistre cette commande dans la passerelle de paiement via register.do. Utilisez le paramètre returnUrl comme marqueur pour fermer Web View après la redirection depuis ACS à l'Étape 14.

  3. Le serveur mobile reçoit en réponse le numéro unique de commande mdOrder.

  4. Le client remplit les données de paiement dans l'application mobile.

  5. L'application mobile appelle le SDK pour créer seToken (secure token). (Android: sdkCore.generateWithCard; iOS: CKCToken.generateWithCard).

    La clé publique requise dans la méthode correspondante doit être prise depuis la ressource en ligne https://dev.bpcbt.com/payment/se/keys.do. Si plusieurs clés sont disponibles via ce lien, il faut utiliser la première clé. (Gardez à l'esprit que des clés différentes sont utilisées pour les environnements de test et de production.)

  6. L'application mobile envoie seToken au serveur mobile.

  7. Le serveur mobile utilise ce seToken pour effectuer le paiement via paymentorder.do.

    • Utilisez seToken au lieu de pan, cvc et date d'expiration.
    • N'oubliez pas de spécifier le nom du titulaire de carte dans le champ TEXT. Si vous ne collectez pas le nom du titulaire de carte, envoyez simplement la valeur CARDHOLDER.
  8. Le serveur mobile reçoit une réponse sans redirection vers ACS. Cela signifie que le paiement est terminé et nous devons passer à l'Étape 16.

  9. Le serveur mobile reçoit une réponse avec redirection vers ACS.

  10. L'application mobile ouvre Web View avec les données de redirection vers ACS.

  11. Le client saisit son mot de passe à usage unique dans le formulaire ACS.

  12. ACS redirige le client vers la passerelle de paiement.

  13. La passerelle de paiement effectue le paiement.

  14. La passerelle de paiement redirige le client vers returnUrl, qui peut être utilisé comme marqueur pour fermer Web View.

  15. L'application mobile ferme Web View.

  16. La passerelle de paiement envoie notification de rappel au serveur du vendeur, si elle est configurée pour le vendeur.

  17. Le serveur mobile vérifie le statut final du paiement via getOrderStatusExtended.do.

  18. L'application mobile montre le résultat du paiement au client.

IOS

Intégration iOS

Intégration SDKCore.framework

Vous pouvez intégrer SDKCore.framework en l'ajoutant manuellement.

SDKCore.framework

Figure 1. Ajout du fichier SDKCore.framework

Figure 2. Modification des propriétés SDKCore.framework

Ensuite, importez le framework dans le fichier ViewController.swift.

//ViewController.swift
...
import SDKCore
...

Travail avec API V2

Dépendances externes

Pour générer le token, il est nécessaire de définir la clé publique.

let publicKey: String =
    "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"

Méthode de génération de token

let sdkCore = SdkCore()

  // TokenResult with NewPaymentMethod
  let newPaymentMethodParams = NewPaymentMethodParams(
       pan: "5536913776755304",
       cvc: "123",
       expiryMMYY: "12/22",
       cardholder: "TEST CARDHOLDER",
       pubKey: publicKey
  )
  let newPaymentMethodConfig = SDKCoreConfig(
      paymentMethodParams: .newPaymentMethodParams(params: newPaymentMethodParams)
  )
  let tokenResult = sdkCore.generateWithConfig(config: newPaymentMethodConfig)

  // TokenResult with StoredPaymentMethod
  let storedPaymentMethodParams = StoredPaymentMethodParams(
      pubKey: publicKey,
      storedPaymentMethodId: "storedPaymentMethodId",
      cvc: "123"
  )
  let storedPaymentMethodConfig = SDKCoreConfig(
      paymentMethodParams: .storedPaymentMethodParams(params: storedPaymentMethodParams)
  )
  let tokenResult = sdkCore.generateWithConfig(config: storedPaymentMethodConfig)

Configuration iOS

Journalisation

Les processus internes sont journalisés avec le tag SDKCore. Vous pouvez également journaliser vos processus.

La journalisation est disponible via l'objet Logger.shared.

...
final class LoggerImplementation: LogInterface {

    func log(class: AnyClass, tag: String, message: String, exception: (any Error)?) {
        // Do something for logging
    }
}

Logger.shared.addLogInterface(logger: LoggerImplementation())
...

Par défaut, le tag SDKCore est utilisé. Vous pouvez définir le vôtre si vous le souhaitez.

...
     Logger.shared.log(classMethod: type(of: self),
                       tag: "MyTag",
                       message: "My process...",
                       exception: nil)
...

Exemple Swift_core (sans interface graphique)

Exemple de formation de cryptogramme

import UIKit
  import SDKCore

  final class MainViewController: UIViewController {

    private let cardNumberValidator = CardNumberValidator()
    private let cardExpiryValidator = CardExpiryValidator()
    private let cardCodeValidator = CardCodeValidator()
    private let cardHolderValidator = CardHolderValidator()
    private let sdkCore = SdkCore()

    private var cardNumberValidationResult: ValidationResult = .VALID
    private var cardExpiryValidationResult: ValidationResult = .VALID
    private var cardCodeValidationResult: ValidationResult = .VALID
    private var cardHolderValidationResult: ValidationResult = .VALID

    private func checkValidation() {
      cardNumberValidationResult = cardNumberValidator.validate(data: cardNumberValue)
      cardExpiryValidationResult = cardNumberValidator.validate(data: cardExpiryValue)
      cardCodeValidationResult = cardNumberValidator.validate(data: cardCodeValue)
      cardHolderValidationResult = cardNumberValidator.validate(data: cardHolderValue)
    }

    private func generateTokenResult() {
      let newPaymentMethodParams = NewPaymentMethodParams(
           pan: cardNumberValue,
           cvc: cardExpiryValue,
           expiryMMYY: cardExpiryValue,
           cardholder: cardHolderValue,
           pubKey: publicKey
      )

      let newPaymentMethodConfig = SDKCoreConfig(
          paymentMethodParams: .newPaymentMethodParams(params: newPaymentMethodParams)
      )
      let tokenResultWithNewPaymentMethod = sdkCore.generateWithConfig(config: newPaymentMethodConfig)


      let storedPaymentMethodParams = StoredPaymentMethodParams(
          pubKey: publicKey,
          storedPaymentMethodId: "storedPaymentMethodId",
          cvc: "123"
      )
      let storedPaymentMethodConfig = SDKCoreConfig(
          paymentMethodParams: .storedPaymentMethodParams(params: storedPaymentMethodParams)
      )
      let tokenResultWithStoredPaymentMethod = sdkCore.generateWithConfig(config: storedPaymentMethodConfig)
    }
  }

Modèles

NewPaymentMethodParams

Nom de la propriétéType de donnéesValeur par défautFacultatifDescription
panString-NonNuméro de carte
cvcString-NonCode secret de la carte code
expiryMMYYString-NonDate d'expiration de la carte
cardHolderString-OuiNom et prénom du porteur de la carte
pubKeyString-NonClé publique

StoredPaymentMethodParams

Nom de la propriétéType de donnéesValeur par défautFacultatifDescription
storedPaymentMethodIdString-NonNuméro de données de paiement sauvegardées pour la carte
cvcString-OuiCode secret de la carte the card
pubKeyString-NonClé publique

TokenResult

Nom de propriétéType de donnéesValeur par défautOptionnelDescription
tokenString-OuiToken comme chaîne de caractères
errorsDictionary<ParamField, String>-NonErreur lors de la génération du token

Erreurs de validation des champs

ParamFieldErreurDescription
UNKNOWN-Erreur inconnue
PANrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatCaractères non autorisés utilisés. Seuls les chiffres sont disponibles.
CVCrequiredChamp vide spécifié
invalidValeur incorrecte
EXPIRYrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatLe format ne correspond pas au modèle MM/YY
CARDHOLDERrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatCaractères non autorisés utilisés. Seuls les caractères latins et les espaces sont disponibles.
PUB_KEYrequiredChamp vide spécifié
STORED_PAYMENT_METHOD_IDinvalidValeur incorrecte
requiredChamp vide spécifié

Travail avec API V1

Dépendances externes

Pour générer un token, il est nécessaire de définir la clé publique.

let publicKey: String =
      "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"

Méthode de génération de jeton

let sdkCore = SdkCore()

let cardParams = CardParams(
     pan: "4111111111111111",
     cvc: "123",
     expiryMMYY: "12/28",
     cardholder: "TEST CARDHOLDER",
     mdOrder: "mdOrder",
     pubKey: publicKey
)

let cardParamsConfig = SDKCoreConfig(
    paymentMethodParams: .cardParams(params: cardParams)
)
let tokenResult = sdkCore.generateWithConfig(config: cardParamsConfig)

let bindignParams = BindingParams(
    pubKey: publicKey,
    bindingId: "das",
    cvc: "123",
    mdOrder: "mdOrder"
)
let bindingParamsConfig = SDKCoreConfig(
    paymentMethodParams: .bindingParams(params: bindignParams)
)
let tokenResult = sdkCore.generateWithConfig(config: bindingParamsConfig)

Modèles

CardParams

Nom de propriétéType de donnéesValeur par défautOptionnelDescription
mdOrderString-NonNuméro de commande
panString-NonNuméro de carte
cvcString-NonCode secret de la carte
expiryMMYYString-NonDate d'expiration de la carte
cardHolderString-OuiNom et prénom du titulaire de la carte
pubKeyString-NonClé publique

BindingParams

Nom de propriétéType de donnéesValeur par défautOptionnelDescription
mdOrderString-NonNuméro de commande
bindingIdString-NonNuméro de données de paiement sauvegardées pour la carte
cvcString-OuiCode secret de la carte
pubKeyString-NonClé publique

Erreurs de validation des champs

ParamFieldErreurDescription
UNKNOWN-Erreur inconnue
PANrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatCaractères non autorisés utilisés. Seuls les chiffres sont disponibles.
CVCrequiredChamp vide spécifié
invalidValeur incorrecte
EXPIRYrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatLe format ne correspond pas au modèle MM/YY
CARDHOLDERrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatCaractères non autorisés utilisés. Seules les lettres et les espaces sont disponibles.
BINDING_IDrequiredChamp vide spécifié
invalidValeur incorrecte
MD_ORDERrequiredChamp vide spécifié
invalidValeur incorrecte
PUB_KEYrequiredChamp vide spécifié

Android

Intégration Android

Connexion au projet Gradle en ajoutant des fichiers .aar de bibliothèque

Il est nécessaire d'ajouter le fichier de bibliothèque sdk_core-release.aar dans le dossier libs, puis spécifier la dépendance de la bibliothèque ajoutée.

build.gradle.kts

allprojects {
    repositories {
        // ...
        flatDir {
            dirs("libs")
        }
    }
}

dependencies {
    // dependency is mandatory to add
    implementation(group = "", name = "sdk_core-release", ext = "aar")
}

build.gradle

allprojects {
    repositories {
        // ...
        flatDir {
            dirs 'libs'
        }
    }
}

dependencies {
    // dependency is mandatory to add
    implementation(group: '', name: 'sdk_core-release', ext: 'aar')
}

Travail avec API V2

Dépendances externes

Pour générer le token, il est nécessaire d'installer la clé publique.

val publicKey: String =
    "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"

Méthode de génération de jeton

val context: Context //android context for getting string resources
val sdkCore: SDKCore = SDKCore(context)

// TokenResult with NewPaymentMethod
val newPaymentMethodCardParams = NewPaymentMethodCardParams(
       pan = "4111111111111111",
       cvc = "123",
       expiryMMYY = "12/28",
       cardHolder = "John Smith",
       pubKey= publicKey
  )
val newPaymentMethodConfig = SDKCoreConfig(paymentCardParams = newPaymentMethodCardParams)
val tokenResult = sdkCore.generateWithConfig(config = newPaymentMethodConfig)

// TokenResult with NewPaymentMethodStoredCard
val newPaymentMethodStoredCardParams = NewPaymentMethodStoredCardParams(
      pubKey = publicKey,
      storedPaymentId = "storedPaymentMethodId",
      cvc = "123"
  )
val storedPaymentMethodConfig = SDKCoreConfig(paymentCardParams = newPaymentMethodStoredCardParams)
val tokenResult = sdkCore.generateWithConfig(config = storedPaymentMethodConfig)

Configuration Android

Journalisation

Les processus internes sont journalisés avec le tag SDK-Core. Vous pouvez également journaliser vos processus.

La journalisation est disponible via l'objet Logger.

...
    Logger.addLogInterface(object : LogInterface {
        override fun log(classMethod: Class<Any>, tag: String, message: String, exception: Exception?) {
                Log.i(tag, "$classMethod: $message", exception)
            }
        })
...

Par défaut, le tag SDK-Core est utilisé. Vous pouvez définir le vôtre si vous le souhaitez.

...
     Logger.log(this.javaClass, "MyTag", "My process...", null)
...

Exemple Kotlin_core (sans interface graphique)

Exemple de formation de cryptogramme

import net.payrdr.mobile.payment.sdk.core.SDKCore
import net.payrdr.mobile.payment.sdk.core.TokenResult
import net.payrdr.mobile.payment.sdk.core.model.BindingParams
import net.payrdr.mobile.payment.sdk.core.model.CardParams
import net.payrdr.mobile.payment.sdk.core.validation.BaseValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardCodeValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardExpiryValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardHolderValidator
import net.payrdr.mobile.payment.sdk.core.validation.CardNumberValidator
import net.payrdr.mobile.payment.sdk.core.validation.OrderNumberValidator

class MainActivity : AppCompatActivity() {
    // initialization of validators for card information entry fields
    private val cardNumberValidator by lazy { CardNumberValidator(this) }
    private val cardExpiryValidator by lazy { CardExpiryValidator(this) }
    private val cardCodeValidator by lazy { CardCodeValidator(this) }
    private val cardHolderValidator by lazy { CardHolderValidator(this) }
    private val orderNumberValidator by lazy { OrderNumberValidator(this) }
    private val sdkCore by lazy { SDKCore(context = this) }
    override fun onCreate(savedInstanceState: Bundle?) {
        // installation of validators on the card information entry fields
        cardNumberInput.setupValidator(cardNumberValidator)
        cardExpiryInput.setupValidator(cardExpiryValidator)
        cardCodeInput.setupValidator(cardCodeValidator)
        cardHolderInput.setupValidator(cardHolderValidator)
        mdOrderInput.setupValidator(orderNumberValidator)

        // creation of an object and initialization of fields for a new card
        val params = NewPaymentMethodCardParams(
            pan = cardNumberInput.text.toString(),
            cvc = cardCodeInput.text.toString(),
            expiryMMYY = cardExpiryInput.text.toString(),
            cardHolder = cardHolderInput.text.toString(),
            pubKey = pubKeyInput.text.toString()
        )
        // method call to get the cryptogram for a new card
        sdkCore.generateWithConfig(SDKCoreConfig(params))

        // Creation of an object and initialization of fields for the linked card
        val params = NewPaymentMethodStoredCardParams(
            storedPaymentId = "storedPaymentMethodId",
            cvc = "123",
            pubKey = pubKeyInput.text.toString()
        )
        // method call to get the cryptogram for the linked card
        sdkCore.generateWithConfig(SDKCoreConfig(params))
    }
}

Modèles

NewPaymentMethodCardParams

Nom de la propriétéType de donnéesValeur par défautFacultatifDescription
panString-NonNuméro de carte
cvcString-NonCode secret de la carte
expiryMMYYString-NonDate d'expiration de la carte
cardHolderString-NonPrénom et nom du porteur de la carte
pubKeyString-NonClé publique

NewPaymentMethodStoredCardParams

Nom de la propriétéType de donnéesValeur par défautFacultatifDescription
storedPaymentIdString-NonNuméro de données de paiement sauvegardées pour la carte
cvcString-NonCode secret de la carte
pubKeyString-NonClé publique

TokenResult

Nom de la propriétéType de donnéesValeur par défautFacultatifDescription
tokenString-NonToken comme chaîne
errorsMap<ParamField, String>-NonErreur lors de la génération du token

Erreurs de validation des champs

ParamFieldErreurDescription
PANrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatCaractères non autorisés utilisés. Seuls les chiffres sont disponibles.
CVCrequiredChamp vide spécifié
invalidValeur incorrecte
EXPIRYrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatLe format ne correspond pas au modèle MM/YY.
CARDHOLDERrequiredChamp vide spécifié
invalidValeur incorrecte
invalid-formatCaractères non autorisés utilisés. Seules les lettres et les espaces sont disponibles.
PUB_KEYrequiredChamp vide spécifié
STORED_PAYMENT_IDrequriredChamp vide spécifié
invalidValeur incorrecte

Travail avec API V1

Dépendances externes

Pour générer le token, il est nécessaire d'installer la clé publique.

val publicKey: String =
    "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoIITqh9xlGx4tWA+aucb0V0YuFC9aXzJb0epdioSkq3qzNdRSZIxe/dHqcbMN2SyhzvN6MRVl3xyjGAV+lwk8poD4BRW3VwPUkT8xG/P/YLzi5N8lY6ILlfw6WCtRPK5bKGGnERcX5dqL60LhOPRDSYT5NHbbp/J2eFWyLigdU9Sq7jvz9ixOLh6xD7pgNgHtnOJ3Cw0Gqy03r3+m3+CBZwrzcp7ZFs41bit7/t1nIqgx78BCTPugap88Gs+8ZjdfDvuDM+/3EwwK0UVTj0SQOv0E5KcEHENL9QQg3ujmEi+zAavulPqXH5907q21lwQeemzkTJH4o2RCCVeYO+YrQIDAQAB-----END PUBLIC KEY-----"

Méthode de génération de token

// TokenResult with CardParams
val cardParams: CardParams = CardParams(
    mdOrder = "mdOrder",
    pan = "4111111111111111",
    cvc = "123",
    expiryMMYY = "12/28",
    cardHolder = "TEST CARDHOLDER",
    pubKey = "publicKey"
)
val tokenResult = sdkCore.generationWithConfig(paymentCardParams = cardParams)

// TokenResult with BindingParams
val bindingParams: BindingParams = BindingParams(
    mdOrder = "mdOrder",
    bindingID = "das",
    cvc = "123",
    pubKey = "publicKey"
)

val tokenResult = sdkCore.generationWithConfig(paymentCardParams = bindingParams)

Frameworks multi-plateformes

Mobile SDK Core peut être utilisé non seulement dans les applications natives : les appels SDK sont transmis au code natif via un pont que vous déclarez du côté de l'application.

React Native

Pour réaliser l'intégration Mobile SDK Core dans une application React Native, il est nécessaire de configurer un pont — une enveloppe en Kotlin/Java ou Swift/Objective-C, qui acceptera les appels depuis JavaScript et les transmettra au code natif du SDK.

Les ponts dans React Native permettent à votre code JS d'appeler les méthodes des bibliothèques natives aussi simplement que des fonctions asynchrones ordinaires : vous déclarez un module natif avec des méthodes qui retournent un résultat via Promise, React Native lie automatiquement ces méthodes avec JavaScript, et ensuite vous travaillez avec elles dans l'application sans connaissances approfondies des API de plateforme.

IOS

  1. Intégrez SDKCore dans votre projet conformément à la section iOS-intégration.

  2. Vérifiez que pour le framework SDKCore.xcframework dans la colonne Embed l'option Embed & Sign est sélectionnée.

  3. Créez un module Swift RadarSdkBridge.swift avec le contenu suivant :

    import Foundation
    import React
    import SDKCore
    
    @objc(RadarSdk)
    class RadarSdkBridge: NSObject {
        private let sdkCore = SdkCore()
    
        @objc
        func generateNewCardToken(
            _ pan: String,
            cvc: String,
            expiryMMYY: String,
            cardHolder: String,
            mdOrder: String,
            pubKey: String,
            resolver resolve: RCTPromiseResolveBlock,
            rejecter reject: RCTPromiseRejectBlock
        ) {
            do {
                let params = CardParams(
                    pan: pan,
                    cvc: cvc,
                    expiryMMYY: expiryMMYY,
                    cardholder: cardHolder,
                    mdOrder: mdOrder,
                    pubKey: pubKey
                )
                let config = SDKCoreConfig(paymentMethodParams: .cardParams(params: params))
                let result = try sdkCore.generateWithConfig(config: config)
                resolve(result.token)
            } catch {
                reject("TOKEN_ERROR", error.localizedDescription, error)
            }
        }
    
        @objc
        func generateStoredCardToken(
            _ storedPaymentId: String,
            cvc: String,
            pubKey: String,
            mdOrder: String,
            resolver resolve: RCTPromiseResolveBlock,
            rejecter reject: RCTPromiseRejectBlock
        ) {
            do {
                let params = BindingParams(
                    pubKey: pubKey,
                    bindingId: storedPaymentId,
                    cvc: cvc,
                    mdOrder: mdOrder
                )
                let config = SDKCoreConfig(paymentMethodParams: .bindingParams(params: params))
                let result = try sdkCore.generateWithConfig(config: config)
                resolve(result.token)
            } catch {
                reject("TOKEN_ERROR", error.localizedDescription, error)
            }
        }
    
        @objc
        static func requiresMainQueueSetup() -> Bool {
            return false
        }
    }
  4. Implémentez le pont Objective-C dans le fichier RadarSdkBridge.m :

    #import <React/RCTBridgeModule.h>
    
    @interface RCT_EXTERN_MODULE(RadarSdk, NSObject)
    
    RCT_EXTERN_METHOD(generateNewCardToken:
      (NSString *)pan
      cvc:(NSString *)cvc
      expiryMMYY:(NSString *)expiryMMYY
      cardHolder:(NSString *)cardHolder
      mdOrder:(NSString *)mdOrder
      pubKey:(NSString *)pubKey
      resolver:(RCTPromiseResolveBlock)resolve
      rejecter:(RCTPromiseRejectBlock)reject
    )
    
    RCT_EXTERN_METHOD(generateStoredCardToken:
      (NSString *)storedPaymentId
      cvc:(NSString *)cvc
      pubKey:(NSString *)pubKey
      mdOrder:(NSString *)mdOrder
      resolver:(RCTPromiseResolveBlock)resolve
      rejecter:(RCTPromiseRejectBlock)reject
    )
    
    @end

Android

  1. Téléchargez les fichiers sdk_core-release.aar et sdk_logs-release.aar et copiez-les dans le dossier android/app/libs/ selon la section Android-intégration.

  2. Ajoutez le dépôt plat et les dépendances dans le fichier android/app/build.gradle :

    android {
        // … reste de la configuration de votre projet …
    }
    
    repositories {
        flatDir {
            dirs 'libs'
        }
    }
    
    dependencies {
        // … autres dépendances …
        implementation(name: 'sdk_core-release', ext: 'aar')
        implementation(name: 'sdk_logs-release', ext: 'aar')
    }

Implémentation du Native Module pour Kotlin

  1. Créez le fichier RadarSdkModule.kt dans le répertoire android/app/src/main/java/.../radar/ :

    package com.mobilesdkdemo.radar
    
    import com.facebook.react.bridge.Promise
    import com.facebook.react.bridge.ReactApplicationContext
    import com.facebook.react.bridge.ReactContextBaseJavaModule
    import com.facebook.react.bridge.ReactMethod
    import net.payrdr.mobile.payment.sdk.core.SDKCore
    import net.payrdr.mobile.payment.sdk.core.model.SDKCoreConfig
    import net.payrdr.mobile.payment.sdk.core.model.CardParams
    import net.payrdr.mobile.payment.sdk.core.model.BindingParams
    
    class RadarSdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
        override fun getName(): String = "RadarSdk"
    
        private val sdkCore by lazy { SDKCore(context = reactApplicationContext) }
    
        @ReactMethod
        fun generateNewCardToken(
            pan: String,
            cvc: String,
            expiryMMYY: String,
            cardHolder: String,
            mdOrder: String,
            pubKey: String,
            promise: Promise
        ) {
            try {
                val params = CardParams(
                    pan = pan,
                    cvc = cvc,
                    expiryMMYY = expiryMMYY,
                    cardHolder = cardHolder,
                    mdOrder = mdOrder,
                    pubKey = pubKey
                )
                val config = SDKCoreConfig(paymentCardParams = params)
                val result = sdkCore.generateWithConfig(config)
                promise.resolve(result.token)
            } catch (e: Exception) {
                promise.reject("TOKEN_ERROR", e)
            }
        }
    
        @ReactMethod
        fun generateStoredCardToken(
            storedPaymentId: String,
            cvc: String,
            pubKey: String,
            mdOrder: String,
            promise: Promise
        ) {
            try {
                val params = BindingParams(
                    bindingID = storedPaymentId,
                    mdOrder = mdOrder,
                    cvc = cvc,
                    pubKey = pubKey
                )
                val config = SDKCoreConfig(paymentCardParams = params)
                val result = sdkCore.generateWithConfig(config)
                promise.resolve(result.token)
            } catch (e: Exception) {
                promise.reject("TOKEN_ERROR", e)
            }
        }
    }
  2. Créez le package RadarSdkPackage.kt dans le même répertoire :

    package com.mobilesdkdemo.radar
    
    import com.facebook.react.ReactPackage
    import com.facebook.react.bridge.NativeModule
    import com.facebook.react.bridge.ReactApplicationContext
    import com.facebook.react.uimanager.ViewManager
    
    class RadarSdkPackage : ReactPackage {
        override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> =
            listOf(RadarSdkModule(reactContext))
    
        override fun createViewManagers(
            reactContext: ReactApplicationContext
        ): List<ViewManager<*, *>> = emptyList()
    }
  3. Enregistrez le package créé dans MainApplication.kt :

    package com.mobilesdkdemo
    
    import android.app.Application
    import com.facebook.react.PackageList
    import com.facebook.react.ReactApplication
    import com.facebook.react.ReactNativeHost
    import com.facebook.react.ReactHost
    import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
    import com.facebook.react.defaults.DefaultReactNativeHost
    import com.facebook.soloader.SoLoader
    import com.mobilesdkdemo.radar.RadarSdkPackage
    
    class MainApplication : Application(), ReactApplication {
    
        override val reactNativeHost: ReactNativeHost =
            object : DefaultReactNativeHost(this) {
                override fun getPackages(): List<ReactPackage> =
                    PackageList(this).packages.apply {
                        add(RadarSdkPackage()) // Enregistrons le package
                    }
    
                override fun getJSMainModuleName(): String = "index"
                override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
                override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
                override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
            }
    
        override val reactHost: ReactHost
            get() = getReactNativeHost(applicationContext, reactNativeHost)
    
        override fun onCreate() {
            super.onCreate()
            SoLoader.init(this, false)
            if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
                load()
            }
        }
    }

Utilisation

Utilisez les méthodes depuis JavaScript/TypeScript de la manière suivante :

import { NativeModules } from 'react-native';
const { RadarSdk } = NativeModules;

// Génération de token pour une nouvelle carte
const token = await RadarSdk.generateNewCardToken(
  '4111111111111111', // PAN
  '123',              // CVC
  '12/25',            // Expiry MM/YY
  'CARDHOLDER NAME',  // Nom du détenteur de la carte
  'mdOrder',          // Numéro obtenu lors de l'enregistrement de la commande
  '-----BEGIN PUBLIC KEY-----...' // Clé publique de /payment/se/keys.do
);

// Génération de token pour une carte liée
const bindToken = await RadarSdk.generateStoredCardToken(
  'bindingId',        // ID de la carte sauvegardée
  '123',              // CVC
  '-----BEGIN PUBLIC KEY-----…', // Clé publique de /payment/se/keys.do
  'mdOrder'           // Numéro obtenu lors de l'enregistrement de la commande
);

Application de démonstration

Un exemple d'intégration de Mobile Sdk Core dans une application React Native peut être consulté sur GitHub.

Flutter

Pour implémenter l'intégration du Mobile SDK Core dans une application Flutter, il est nécessaire de configurer un platform channel — un canal par lequel le code Dart appelle les méthodes natives du SDK sur Android et iOS.

Le Platform channel relie le code Dart et le code natif par le nom du canal : vous déclarez MethodChannel avec le même nom des deux côtés, appelez la méthode depuis Dart et obtenez le résultat via Future. Le nom du canal est la seule chose qui relie les deux côtés, donc en cas de non-correspondance, l'appel se terminera par une exception MissingPluginException à l'exécution, et non par une erreur de compilation.

Les arguments sont transmis comme Map<String, dynamic> et sont analysés côté natif par les noms des clés. Seules les valeurs comprises par le codec standard passent par le canal — primitives, listes et dictionnaires ; les objets SDK sont créés côté natif et ne sont pas transmis par le canal.

iOS

  1. Intégrez SDKCore dans votre projet conformément à la section Intégration iOS.

  2. Vérifiez que pour le framework SDKCore.xcframework dans la colonne Embed, Embed & Sign est sélectionné. Le framework à l'intérieur de xcframework est une bibliothèque dynamique : si elle est seulement liée mais pas intégrée, le projet se compilera, mais l'application plantera au démarrage.

  3. Créez le fichier RadarSdkBridge.swift dans le target Runner :

    import Flutter
    import Foundation
    import SDKCore
    
    final class RadarSdkBridge: NSObject {
        static let channelName = "radar_sdk"
    
        private let channel: FlutterMethodChannel
        private let sdkCore = SdkCore()
    
        init(messenger: FlutterBinaryMessenger) {
            channel = FlutterMethodChannel(name: RadarSdkBridge.channelName, binaryMessenger: messenger)
            super.init()
            channel.setMethodCallHandler { [weak self] call, result in
                self?.handle(call, result: result)
            }
        }
    
        private func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
            switch call.method {
            case "generateNewCardToken":
                generateNewCardToken(call, result: result)
            case "generateStoredCardToken":
                generateStoredCardToken(call, result: result)
            default:
                result(FlutterMethodNotImplemented)
            }
        }
    
        private func generateNewCardToken(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
            guard
                let args = call.arguments as? [String: Any],
                let pan = args["pan"] as? String,
                let cvc = args["cvc"] as? String,
                let expiryMMYY = args["expiryMMYY"] as? String,
                let cardHolder = args["cardHolder"] as? String,
                let mdOrder = args["mdOrder"] as? String,
                let pubKey = args["pubKey"] as? String
            else {
                result(FlutterError(code: "TOKEN_ERROR", message: "Invalid arguments", details: nil))
                return
            }
    
            do {
                let params = CardParams(
                    pan: pan,
                    cvc: cvc,
                    expiryMMYY: expiryMMYY,
                    cardholder: cardHolder,
                    mdOrder: mdOrder,
                    pubKey: pubKey
                )
                let config = SDKCoreConfig(paymentMethodParams: .cardParams(params: params))
                let tokenResult = try sdkCore.generateWithConfig(config: config)
                result(tokenResult.token)
            } catch {
                result(FlutterError(code: "TOKEN_ERROR", message: error.localizedDescription, details: nil))
            }
        }
    
        private func generateStoredCardToken(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
            guard
                let args = call.arguments as? [String: Any],
                let storedPaymentId = args["storedPaymentId"] as? String,
                let cvc = args["cvc"] as? String,
                let pubKey = args["pubKey"] as? String,
                let mdOrder = args["mdOrder"] as? String
            else {
                result(FlutterError(code: "TOKEN_ERROR", message: "Invalid arguments", details: nil))
                return
            }
    
            do {
                let params = BindingParams(
                    pubKey: pubKey,
                    bindingId: storedPaymentId,
                    cvc: cvc,
                    mdOrder: mdOrder
                )
                let config = SDKCoreConfig(paymentMethodParams: .bindingParams(params: params))
                let tokenResult = try sdkCore.generateWithConfig(config: config)
                result(tokenResult.token)
            } catch {
                result(FlutterError(code: "TOKEN_ERROR", message: error.localizedDescription, details: nil))
            }
        }
    }
  4. Enregistrez le pont dans AppDelegate.swift :

    import Flutter
    import UIKit
    
    @main
    @objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
        // Le pont doit être stocké dans une propriété : un objet créé dans une
        // variable locale est libéré et cesse silencieusement de répondre aux appels depuis Dart.
        private var radarSdkBridge: RadarSdkBridge?
    
        func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
            GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
    
            if let messenger = engineBridge.pluginRegistry.registrar(forPlugin: "RadarSdkBridge")?.messenger() {
                radarSdkBridge = RadarSdkBridge(messenger: messenger)
            }
        }
    }

Android

  1. Téléchargez les fichiers sdk_core-release.aar et sdk_logs-release.aar et copiez-les dans le dossier android/app/libs/ selon la section Intégration Android.

  2. Ajoutez les dépendances dans le fichier android/app/build.gradle.kts :

    android {
        // … reste de la configuration de votre projet …
    }
    
    dependencies {
        // … autres dépendances …
        implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
    }
  3. Créez le fichier RadarSdkBridge.kt dans le répertoire android/app/src/main/kotlin/.../ :

    package com.mobilesdkdemo
    
    import android.content.Context
    import io.flutter.plugin.common.BinaryMessenger
    import io.flutter.plugin.common.MethodCall
    import io.flutter.plugin.common.MethodChannel
    
    import net.payrdr.mobile.payment.sdk.core.SDKCore
    import net.payrdr.mobile.payment.sdk.core.model.BindingParams
    import net.payrdr.mobile.payment.sdk.core.model.CardParams
    import net.payrdr.mobile.payment.sdk.core.model.SDKCoreConfig
    
    private const val CHANNEL_NAME = "radar_sdk"
    
    class RadarSdkBridge(private val context: Context) : MethodChannel.MethodCallHandler {
    
        private val sdkCore by lazy { SDKCore(context = context) }
    
        fun register(messenger: BinaryMessenger) {
            MethodChannel(messenger, CHANNEL_NAME).setMethodCallHandler(this)
        }
    
        override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
            when (call.method) {
                "generateNewCardToken" -> generateNewCardToken(call, result)
                "generateStoredCardToken" -> generateStoredCardToken(call, result)
                else -> result.notImplemented()
            }
        }
    
        private fun generateNewCardToken(call: MethodCall, result: MethodChannel.Result) {
            try {
                val params = CardParams(
                    pan = call.argument<String>("pan")!!,
                    cvc = call.argument<String>("cvc")!!,
                    expiryMMYY = call.argument<String>("expiryMMYY")!!,
                    cardHolder = call.argument<String>("cardHolder")!!,
                    mdOrder = call.argument<String>("mdOrder")!!,
                    pubKey = call.argument<String>("pubKey")!!
                )
                val config = SDKCoreConfig(paymentCardParams = params)
                val token = sdkCore.generateWithConfig(config).token
    
                result.success(token)
            } catch (e: Exception) {
                result.error("TOKEN_ERROR", e.message, null)
            }
        }
    
        private fun generateStoredCardToken(call: MethodCall, result: MethodChannel.Result) {
            try {
                val params = BindingParams(
                    bindingID = call.argument<String>("storedPaymentId")!!,
                    mdOrder = call.argument<String>("mdOrder")!!,
                    cvc = call.argument<String>("cvc")!!,
                    pubKey = call.argument<String>("pubKey")!!
                )
                val config = SDKCoreConfig(paymentCardParams = params)
                val token = sdkCore.generateWithConfig(config).token
    
                result.success(token)
            } catch (e: Exception) {
                result.error("TOKEN_ERROR", e.message, null)
            }
        }
    }
  4. Enregistrez le pont dans MainActivity.kt :

    package com.mobilesdkdemo
    
    import io.flutter.embedding.android.FlutterActivity
    import io.flutter.embedding.engine.FlutterEngine
    
    class MainActivity : FlutterActivity() {
        override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
            super.configureFlutterEngine(flutterEngine)
            RadarSdkBridge(applicationContext).register(flutterEngine.dartExecutor.binaryMessenger)
        }
    }

Utilisation

  1. Créez un wrapper au-dessus du canal dans lib/radar_sdk.dart. Le nom du canal et les noms des clés dans les arguments doivent correspondre au côté natif :

    import 'package:flutter/services.dart';
    
    class RadarSdk {
        const RadarSdk._();
    
        static const MethodChannel _channel = MethodChannel('radar_sdk');
    
        static Future<String?> generateNewCardToken({
            required String pan,
            required String cvc,
            required String expiryMMYY,
            required String cardHolder,
            required String mdOrder,
            required String pubKey,
        }) {
            return _channel.invokeMethod<String>('generateNewCardToken', {
                'pan': pan,
                'cvc': cvc,
                'expiryMMYY': expiryMMYY,
                'cardHolder': cardHolder,
                'mdOrder': mdOrder,
                'pubKey': pubKey,
            });
        }
    
        static Future<String?> generateStoredCardToken({
            required String storedPaymentId,
            required String cvc,
            required String pubKey,
            required String mdOrder,
        }) {
            return _channel.invokeMethod<String>('generateStoredCardToken', {
                'storedPaymentId': storedPaymentId,
                'cvc': cvc,
                'pubKey': pubKey,
                'mdOrder': mdOrder,
            });
        }
    }
  2. Utilisez les méthodes depuis Dart de la manière suivante :

    // Génération de jeton pour une nouvelle carte
    final token = await RadarSdk.generateNewCardToken(
      pan: '4111111111111111',  // PAN
      cvc: '123',               // CVC
      expiryMMYY: '12/25',      // Date d'expiration MM/YY
      cardHolder: 'CARDHOLDER NAME', // Nom du porteur de la carte
      mdOrder: 'mdOrder',       // Numéro obtenu lors de l'enregistrement de la commande
      pubKey: '-----BEGIN PUBLIC KEY-----...', // Clé publique depuis /payment/se/keys.do
    );
    
    // Génération de jeton pour une carte liée
    final bindToken = await RadarSdk.generateStoredCardToken(
      storedPaymentId: 'bindingId', // ID de la carte sauvegardée
      cvc: '123',                   // CVC
      pubKey: '-----BEGIN PUBLIC KEY-----…', // Clé publique depuis /payment/se/keys.do
      mdOrder: 'mdOrder',           // Numéro obtenu lors de l'enregistrement de la commande
    );

Les erreurs du côté natif arrivent dans Dart comme PlatformException : en cas d'échec de génération de jeton, le pont répond avec le code TOKEN_ERROR, et le texte d'erreur du SDK est transmis dans le champ message.

try {
  final token = await RadarSdk.generateNewCardToken(/* … */);
} on PlatformException catch (e) {
  // e.code == 'TOKEN_ERROR', e.message — texte d'erreur du SDK
}

Application de démonstration

Un exemple d'intégration du Mobile SDK Core dans une application Flutter peut être consulté sur GitHub.

Mobile SDK Source

iOS

Sources iOS sur GitHub

Versions iOS sur GitHub

Exigences : iOS 10.0 ou supérieur

Android

Sources Android sur GitHub

Versions Android sur GitHub

Exigences : Android 5.0 ou supérieur

Catégories:
eCommerceSDK
Catégories
Résultats de recherche