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 paiement | Support |
|---|---|
| Carte bancaire | Oui |
| Identifiants/carte sauvegardés | Oui |
| Apple Pay | Non requis |
| Google Pay | Non 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.
-
Le client crée une commande
-
Le serveur mobile enregistre cette commande dans la passerelle de paiement via register.do. Utilisez le paramètre
returnUrlcomme marqueur pour fermer Web View après la redirection depuis ACS à l'Étape 14. -
Le serveur mobile reçoit en réponse le numéro unique de commande
mdOrder. -
Le client remplit les données de paiement dans l'application mobile.
-
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.)
-
L'application mobile envoie seToken au serveur mobile.
-
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 valeurCARDHOLDER.
-
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.
-
Le serveur mobile reçoit une réponse avec redirection vers ACS.
-
L'application mobile ouvre Web View avec les données de redirection vers ACS.
-
Le client saisit son mot de passe à usage unique dans le formulaire ACS.
-
ACS redirige le client vers la passerelle de paiement.
-
La passerelle de paiement effectue le paiement.
-
La passerelle de paiement redirige le client vers
returnUrl, qui peut être utilisé comme marqueur pour fermer Web View. -
L'application mobile ferme Web View.
-
La passerelle de paiement envoie notification de rappel au serveur du vendeur, si elle est configurée pour le vendeur.
-
Le serveur mobile vérifie le statut final du paiement via getOrderStatusExtended.do.
-
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
-
Téléchargez la dernière version du framework ici.
-
Sélectionnez le fichier
SDKCore.frameworket ajoutez-le dans le dossier du projet.

- Ouvrez la page Targets -> General -> Frameworks, Libraries, and Embedded Content. Pour
SDKCore.frameworkdans la colonne Embed, remplacezDo not EmbedparEmbed & Sign.

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.
-
Pour ajouter des interfaces de log, il est nécessaire d'appeler la méthode
LoggeraddLogInterface().Exemple :
...
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.
-
Pour journaliser vos propres événements, il est nécessaire d'appeler la méthode
Logger.sharedlog().Exemple :
...
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ées | Valeur par défaut | Facultatif | Description |
|---|---|---|---|---|
| pan | String | - | Non | Numéro de carte |
| cvc | String | - | Non | Code secret de la carte code |
| expiryMMYY | String | - | Non | Date d'expiration de la carte |
| cardHolder | String | - | Oui | Nom et prénom du porteur de la carte |
| pubKey | String | - | Non | Clé publique |
StoredPaymentMethodParams
| Nom de la propriété | Type de données | Valeur par défaut | Facultatif | Description |
|---|---|---|---|---|
| storedPaymentMethodId | String | - | Non | Numéro de données de paiement sauvegardées pour la carte |
| cvc | String | - | Oui | Code secret de la carte the card |
| pubKey | String | - | Non | Clé publique |
TokenResult
| Nom de propriété | Type de données | Valeur par défaut | Optionnel | Description |
|---|---|---|---|---|
| token | String | - | Oui | Token comme chaîne de caractères |
| errors | Dictionary<ParamField, String> | - | Non | Erreur lors de la génération du token |
Erreurs de validation des champs
| ParamField | Erreur | Description |
|---|---|---|
| UNKNOWN | - | Erreur inconnue |
| PAN | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Caractères non autorisés utilisés. Seuls les chiffres sont disponibles. | |
| CVC | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| EXPIRY | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Le format ne correspond pas au modèle MM/YY | |
| CARDHOLDER | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Caractères non autorisés utilisés. Seuls les caractères latins et les espaces sont disponibles. | |
| PUB_KEY | required | Champ vide spécifié |
| STORED_PAYMENT_METHOD_ID | invalid | Valeur incorrecte |
| required | Champ 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ées | Valeur par défaut | Optionnel | Description |
|---|---|---|---|---|
| mdOrder | String | - | Non | Numéro de commande |
| pan | String | - | Non | Numéro de carte |
| cvc | String | - | Non | Code secret de la carte |
| expiryMMYY | String | - | Non | Date d'expiration de la carte |
| cardHolder | String | - | Oui | Nom et prénom du titulaire de la carte |
| pubKey | String | - | Non | Clé publique |
BindingParams
| Nom de propriété | Type de données | Valeur par défaut | Optionnel | Description |
|---|---|---|---|---|
| mdOrder | String | - | Non | Numéro de commande |
| bindingId | String | - | Non | Numéro de données de paiement sauvegardées pour la carte |
| cvc | String | - | Oui | Code secret de la carte |
| pubKey | String | - | Non | Clé publique |
Erreurs de validation des champs
| ParamField | Erreur | Description |
|---|---|---|
| UNKNOWN | - | Erreur inconnue |
| PAN | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Caractères non autorisés utilisés. Seuls les chiffres sont disponibles. | |
| CVC | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| EXPIRY | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Le format ne correspond pas au modèle MM/YY | |
| CARDHOLDER | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Caractères non autorisés utilisés. Seules les lettres et les espaces sont disponibles. | |
| BINDING_ID | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| MD_ORDER | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| PUB_KEY | required | Champ 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.
-
Pour ajouter des interfaces log, il est nécessaire d'appeler la méthode
addLogInterface()deLogger.Exemple pour la journalisation dans LogCat:
...
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.
-
Pour journaliser vos propres événements, il est nécessaire d'appeler la méthode
log()deLogger.Exemple:
...
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ées | Valeur par défaut | Facultatif | Description |
|---|---|---|---|---|
| pan | String | - | Non | Numéro de carte |
| cvc | String | - | Non | Code secret de la carte |
| expiryMMYY | String | - | Non | Date d'expiration de la carte |
| cardHolder | String | - | Non | Prénom et nom du porteur de la carte |
| pubKey | String | - | Non | Clé publique |
NewPaymentMethodStoredCardParams
| Nom de la propriété | Type de données | Valeur par défaut | Facultatif | Description |
|---|---|---|---|---|
| storedPaymentId | String | - | Non | Numéro de données de paiement sauvegardées pour la carte |
| cvc | String | - | Non | Code secret de la carte |
| pubKey | String | - | Non | Clé publique |
TokenResult
| Nom de la propriété | Type de données | Valeur par défaut | Facultatif | Description |
|---|---|---|---|---|
| token | String | - | Non | Token comme chaîne |
| errors | Map<ParamField, String> | - | Non | Erreur lors de la génération du token |
Erreurs de validation des champs
| ParamField | Erreur | Description |
|---|---|---|
| PAN | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Caractères non autorisés utilisés. Seuls les chiffres sont disponibles. | |
| CVC | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| EXPIRY | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Le format ne correspond pas au modèle MM/YY. | |
| CARDHOLDER | required | Champ vide spécifié |
| invalid | Valeur incorrecte | |
| invalid-format | Caractères non autorisés utilisés. Seules les lettres et les espaces sont disponibles. | |
| PUB_KEY | required | Champ vide spécifié |
| STORED_PAYMENT_ID | requrired | Champ vide spécifié |
| invalid | Valeur 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
-
Intégrez SDKCore dans votre projet conformément à la section iOS-intégration.
-
Vérifiez que pour le framework
SDKCore.xcframeworkdans la colonne Embed l'option Embed & Sign est sélectionnée. -
Créez un module Swift
RadarSdkBridge.swiftavec 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 } } -
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
-
Téléchargez les fichiers
sdk_core-release.aaretsdk_logs-release.aaret copiez-les dans le dossierandroid/app/libs/selon la section Android-intégration. -
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
-
Créez le fichier
RadarSdkModule.ktdans le répertoireandroid/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) } } } -
Créez le package
RadarSdkPackage.ktdans 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() } -
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
-
Intégrez SDKCore dans votre projet conformément à la section Intégration iOS.
-
Vérifiez que pour le framework
SDKCore.xcframeworkdans la colonne Embed, Embed & Sign est sélectionné. Le framework à l'intérieur dexcframeworkest 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. -
Créez le fichier
RadarSdkBridge.swiftdans le targetRunner: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)) } } } -
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
-
Téléchargez les fichiers
sdk_core-release.aaretsdk_logs-release.aaret copiez-les dans le dossierandroid/app/libs/selon la section Intégration Android. -
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")))) } -
Créez le fichier
RadarSdkBridge.ktdans le répertoireandroid/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) } } } -
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
-
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, }); } } -
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
Exigences : iOS 10.0 ou supérieur
Android
Exigences : Android 5.0 ou supérieur