Lite SDK (Paiement iOS)
SDK recommandéNous recommandons d'utiliser le SDK Seamless iOS pour une expérience d'intégration fluide. Cette option offre une solution de paiement flexible avec des composants d'interface utilisateur (UI) pré-construits et des options de personnalisation.
Ce guide vous aide à intégrer le SDK Lite iOS de Yuno pour les paiements dans votre projet.
Prérequis
Avant d'implémenter le SDK iOS de Yuno, assurez-vous que vous remplissez les conditions suivantes :
- Ajouter CocoaPods ou Swift Package Manager à votre projet.
- Utiliser la version iOS 14.0 ou supérieure.
Étape 1 : Inclure la bibliothèque dans votre projet
Vous pouvez ajouter la bibliothèque en utilisant CocoaPods ou Swift Package Manager.
CocoaPods
Ajoutez le SDK Yuno à votre projet iOS en utilisant CocoaPods. Si vous n'avez pas de Podfile, suivez le guide CocoaPods pour en créer un. Ajoutez ensuite la ligne suivante à votre Podfile :
pod 'YunoSDK', '~> 1.1.22'Puis exécutez l'installation :
installation du pod
Swift Package Manager
Ajoutez le SDK Yuno à l'aide du gestionnaire de paquets Swift. Ajoutez YunoSDK en tant que dépendance dans votre fichier Package.swift :
dépendances : [
.package(url : "https://github.com/yuno-payments/yuno-sdk-ios.git", .upToNextMajor(from : "1.1.17"))
]Étape 2 : Initialiser le SDK avec la clé publique
Initialisez le SDK iOS de Yuno avec votre clé API publique :
import YunoSDK
Yuno.initialize(
apiKey: "PUBLIC_API_KEY",
config: YunoConfig(),
callback: { (value: Bool) in }
)
UISceneDelegateSi votre application utilise un UISceneDelegate, vous devrez placer votre code d'initialisation Yuno dans votre SceneDelegate.
Configurez l'apparence et le comportement du SDK en utilisant la classe YunoConfig . Cette option est facultative et vous permet de personnaliser l'expérience de paiement :
final class YunoConfig {
let cardFormType: CardFormType,
let appearance: Yuno.Appearance,
let saveCardEnabled: Bool,
let keepLoader: Bool
}Configurez le SDK avec les options suivantes :
| Paramètres | Description |
|---|---|
cardFormType | Ce champ peut être utilisé pour choisir le flux de paiement et d'inscription. Il s'agit d'une propriété facultative qui prend en compte .oneStep par défaut. |
appearance | Ce champ optionnel définit l'apparence du paiement. Par défaut, il utilise les styles Yuno. |
saveCardEnabled | Ce champ optionnel peut être utilisé pour choisir si la case à cocher Enregistrer la carte est affichée dans les flux de carte. Il est faux par défaut. |
keepLoader | Ce champ optionnel permet de contrôler quand masquer le loader. S'il est défini sur true, la fonction hideLoader() doit être appelée pour masquer le chargeur. Par défaut, elle est définie à false. |
hideCardholderName | Ce champ facultatif vous permet de masquer le champ du nom du titulaire de la carte dans le formulaire de carte. Lorsqu'il est défini sur true, le champ du nom du titulaire de la carte n'est pas affiché. Lorsqu'il n'est pas spécifié ou défini sur false, le champ du nom du titulaire de la carte s'affiche (comportement par défaut). Le fait de masquer ce champ n'a aucune incidence sur le PAN, la date d'expiration, la collecte du CVV, la logique BIN ou les validations 3DS/fournisseur. Le commerçant est tenu de s'assurer que le nom du titulaire de la carte est fourni lorsque son fournisseur de services de paiement l'exige. |
Accès à votre Clé APIVous pouvez récupérer votre Clé API depuis la section Développeurs dans le Tableau de Bord Yuno.
Étape 3 : Démarrer le processus de paiement
Créez un ViewController qui adopte le protocole YunoPaymentDelegate :
DépréciationLe champ
startCheckouta été déclarée obsolète dans les versions récentes du SDK iOS.
protocol YunoPaymentDelegate: AnyObject {
var checkoutSession: String { get }
var countryCode: String { get }
var language: String? { get }
var viewController: UIViewController? { get }
func yunoCreatePayment(with token: String)
func yunoCreatePayment(with token: String, information: [String: Any])
func yunoPaymentResult(_ result: Yuno.Result)
}
class ViewController: YunoPaymentDelegate {
func viewDidLoad() {
super.viewDidLoad()
}
}Paramètres
| Paramètres | Description |
|---|---|
checkoutSession | Fait référence à la session de paiement du paiement actuel. |
countryCode | Ce paramètre détermine le pays pour lequel le processus de paiement est configuré. La liste complète des pays pris en charge et de leur code pays est disponible sur la page Couverture des pays. |
language | Définit la langue à utiliser dans les formulaires de paiement. Vous pouvez choisir l'une des options linguistiques disponibles :
|
viewController | Cette propriété représente le UIViewController utilisé pour présenter le flux de paiement. Même si cette propriété reste facultative pour des raisons de compatibilité ascendante, vous devez fournir un contrôleur visible afin que le SDK puisse présenter correctement son interface utilisateur. |
yunoCreatePayment(with token: String) | Cette méthode est chargée de créer un paiement avec le token fourni. Elle prend en paramètre une chaîne de caractères appelée tokenqui représente le token paiement. |
yunoCreatePayment(with token: String, information: [String: Any]) | Cette méthode est chargée de créer un paiement avec le token fourni. Elle prend en paramètre une chaîne de caractères appelée tokenreprésentant le token paiement. En outre, il renvoie toutes les informations relatives à la réponse du token dans un dictionnaire. |
yunoPaymentResult(_ result: Yuno.Result) | Cette méthode est appelée lorsque le processus de paiement est terminé et fournit le résultat du paiement en tant que paramètre de type Yuno.Result. |
Note importanteVous pouvez appeler
yunoCreatePaymentavec ou sans le paramètreinformationselon vos besoins. Cependant, n'utilisez qu'une seule version dans votre code, car appeler les deux n'est pas nécessaire et peut causer des problèmes.
Exigences de Concurrence Swift 6Si vous utilisez Swift 6, vous devrez implémenter le protocole
YunoPaymentDelegateavec des considérations spécifiques sur la concurrence. Swift 6 introduit des exigences de sécurité des fils d'exécution plus strictes qui affectent la manière dont vous implémentez les délégués. Consultez la section Implémentation deYunoPaymentDelegateavec la Concurrence Swift 6 pour les options d'implémentation détaillées et les meilleures pratiques.
Étape 4 : Initier le Processus de Paiement
Pour initier effectivement un paiement après avoir affiché les méthodes de paiement, vous devez appeler la méthode startPaymentLitecomme le montre l'extrait de code ci-dessous :
startPaymentLite(
with: YunoPaymentDelegate,
paymentSelected: PaymentMethodSelected,
showPaymentStatus: Bool
)Pour la version Lite, vous devez envoyer un paramètre supplémentaire, qui peut être le token et/ou la méthode de paiement que le client utilisera pour effectuer le paiement.
protocol PaymentMethodSelected {
var vaultedToken: String? { get }
var paymentMethodType: String { get }
}
startPaymentLite(with: self, paymentSelected: paymentSelected)Étape 5 : Obtenir le token usage unique (OTT)
Vous pouvez obtenir le token à usage unique pour créer le paiement back-to-back à la fin de ce processus. Vous obtiendrez le token à usage unique dans la fonction yunoCreatePayment() que vous obtenez lorsque vous implémentez le YunoPaymentDelegate. Un exemple de récupération du token à usage unique est présenté ci-dessous :
func yunoCreatePayment(with token: String) { ... }Étape 6 : Créer le paiement
Une fois que vous avez effectué les étapes décrites précédemment, vous pouvez créer un paiement. La création d'un paiement back-to-back doit être effectuée à l'aide du l'endpoint Créer un paiement. Le commerçant doit appeler son backend pour créer le paiement dans Yuno, en utilisant le token à usage unique et la session de paiement.
Continuer la méthodeYuno vous demande d'intégrer la méthode
continuePaymentdu SDK après la création du paiement, car certaines méthodes de paiement asynchrones nécessitent une action supplémentaire de la part du client pour le compléter. L'API vous informera de ce scénario via le champsdk_action_requiredde la réponse, qui sera retourné comme true. La fonctionyuno.continuePayment()affichera les écrans supplémentaires aux clients, où ils pourront effectuer les actions nécessaires pour compléter le paiement sans que vous ayez besoin de gérer chaque scénario.
Yuno.continuePayment()Étape 7 : Gérer le statut du paiement (facultatif)
Liens Profonds et Mercado Pago Checkout ProCette étape n'est requise que si vous utilisez une méthode de paiement qui repose sur des liens profonds ou Mercado Pago Checkout Pro. Si vos méthodes de paiement n'utilisent pas de liens profonds, vous pouvez ignorer cette étape.
Certaines méthodes de paiement font sortir les utilisateurs de votre application pour finaliser la transaction. Une fois le paiement terminé, l'utilisateur est redirigé vers votre application à l'aide d'un lien profond. Le SDK utilise ce lien profond pour vérifier ce qui s'est passé (paiement réussi, échec ou annulation) et peut afficher un écran de statut à l'utilisateur.
Pour gérer cela, vous devez mettre à jour votre AppDelegate pour transmettre l'URL entrante au SDK Yuno. Cela permet au SDK de lire le résultat et éventuellement d'afficher le statut du paiement. Le code suivant montre comment l'ajouter à votre application :
func application(_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
guard url.scheme == "yunoexample" else { return false }
return Yuno.receiveDeeplink(url)
}Ce code est à l'écoute des liens profonds qui ouvrent votre application. Lorsqu'une URL est reçue, il vérifie si le schéma correspond à celui que vous avez utilisé le callback_url lors de la configuration de la session de paiement. Si cela correspond, l'URL est transmise au SDK Yuno via Yuno.receiveDeeplink(...). Le SDK lit alors le résultat du paiement et affiche le statut approprié à l'utilisateur.
Assurez-vous que le url.scheme dans ce code correspond au callback_url que vous avez fourni lors de la création de la checkout_session.
Cliquer pour payerPour obtenir de l'aide sur Click to Pay, suivez le guide d'intégration dédié au SDK Click to Pay dans la section Portefeuilles.
Rappel
Le SDK renvoie différents états de transaction une fois le paiement effectué. Le tableau suivant décrit chaque état :
| État de la transaction | Description |
|---|---|
success | Indique que la transaction ou le processus de paiement a été complété avec succès. |
fail | Cet état indique que la transaction ou le processus de paiement a échoué. Cela signifie qu'il y a eu une erreur ou un problème au cours de la procédure de paiement, l'empêchant de s'achever avec succès. |
processing | Indique que la transaction ou le processus de paiement est en cours de traitement. Il est généralement utilisé lorsque le traitement du paiement est retardé, par exemple dans l'attente de l'approbation d'un service tiers ou d'une institution financière. |
reject | Cet état indique que la transaction a été rejetée. Le rejet peut avoir diverses raisons, telles qu'une insuffisance de fonds, une activité frauduleuse ou une demande qui enfreint des règles ou des politiques spécifiques. |
internalError | Cela signifie qu'une erreur inattendue s'est produite dans le système ou l'infrastructure qui gère le processus de paiement. Cet état suggère qu'il y a eu un problème du côté du serveur ou du backend plutôt qu'un problème avec l'entrée ou la demande de l'utilisateur. |
userCancell | Cet état indique que l'utilisateur a volontairement annulé ou interrompu la transaction ou le processus de paiement. Cet état est généralement utilisé lorsque l'utilisateur a la possibilité d'annuler ou d'abandonner la procédure de paiement. |
Validation du statut de paiement
Cette section explique comment le SDK gère le statut des paiements lorsque les utilisateurs annulent ou quittent les flux de paiement, et comment le statut du SDK est lié au statut des paiements backend dans ces scénarios.
Synchroniser les modes de paiement (Apple Pay)
Pour les méthodes de paiement synchronisées telles qu'Apple Pay, lorsqu'un utilisateur annule ou ferme l'interface utilisateur du portefeuille avant de recevoir la réponse du prestataire de services de paiement (PSP) :
- Statut du SDK: Retours
userCancell(CANCELLED) - Statut du paiement backend: Restes
PENDINGjusqu'à l'expiration du délai PSP ou l'annulation par le commerçant - Important: Le SDK ne renverra pas
rejectouprocessingdans ce scénario
Cela garantit que le paiement backend reste en attente et peut être correctement traité par le système du commerçant.
Modes de paiement asynchrones (PIX et méthodes basées sur les QR codes)
Pour les méthodes de paiement asynchrones telles que PIX, lorsqu'un utilisateur ferme la fenêtre du code QR (clique sur X) avant d'avoir terminé le paiement :
- Statut du SDK: Retours
PENDING, éventuellement avec un sous-statut tel queCLOSED_BY_USER - Statut du paiement backend: Restes
PENDINGet le code QR reste valide jusqu'à son expiration. - Réutilisation de la session de paiement: la réouverture de la même session de paiement permet d'afficher le même code QR valide.
- Pas d'annulation automatique: le paiement PIX n'est pas automatiquement annulé lorsque l'utilisateur ferme la fenêtre QR.
Ce comportement permet aux utilisateurs de revenir au flux de paiement et de terminer la transaction à l'aide du même code QR avant son expiration.
Paiements asynchrones expirés
Si un code QR PIX expire naturellement :
- Statut du backend: Mis à jour vers
EXPIRED - Statut du SDK: Les rappels SDK et endpoints d'interrogation endpoints
EXPIREDde manière cohérente
Cela garantit que les commerçants reçoivent des informations précises sur le statut lorsqu'un moyen de paiement a expiré.
Implémenter le délégué pour recevoir les états de transaction :
enum Result {
case reject, success, fail, processing, internalError, userCancell
}
func yunoPaymentResult(_ result: Yuno.Result) { ... }
func yunoEnrollmentResult(_ result: Yuno.Result) { ... }Fonctionnalités Complémentaires
Le SDK iOS de Yuno offre des fonctionnalités supplémentaires pour améliorer l'expérience client. Utilisez les personnalisations du SDK pour adapter l'apparence de votre marque ou configurer le loader.
- Loader: Contrôlez l'utilisation du Loader par le biais des options de configuration du SDK.
- Sauvegarde de carte pour les futurs paiements: De plus, vous pouvez afficher une case à cocher pour l'enregistrement des cartes en utilisant
cardSaveEnable: true. Vous trouverez ci-dessous des exemples de cases à cocher pour les deux rendus de formulaires de cartes.
- Vous pouvez également choisir l'une des options de rendu pour le formulaire de la carte. Ci-dessous, vous trouverez des captures d'écran présentant la différence entre les options de rendu du formulaire de carte
cardFormTypeONE_STEPetSTEP_BY_STEP.
- Personnalisation du SDK: Modifiez l'apparence du SDK pour qu'il corresponde à votre marque.
Intégration du Mode Rendu
Le mode rendu dans le SDK Yuno offre une flexibilité UI accrue, permettant aux développeurs d'intégrer des flux de paiement avec un contrôle complet sur l'interface utilisateur tout en conservant la pleine fonctionnalité du SDK. Ce mode fournit des vues SwiftUI qui peuvent être intégrées de manière transparente dans votre UI existante.
Fonction principale : startPaymentRenderFlow
startPaymentRenderFlowLe champ startPaymentRender est une fonctionnalité du SDK Yuno qui permet aux marchands d'intégrer le processus de paiement d'une manière plus détaillée et personnalisable. Cette fonction accorde un contrôle total sur quand et comment les formulaires de paiement sont affichés, ce qui facilite l'intégration avec l'interface utilisateur de l'application existante du commerçant.
Objectif
Cette fonction est conçue pour offrir un plus grand contrôle sur le flux de paiement, permettant aux commerçants de :
- Intégrer des formulaires de paiement de manière personnalisée dans leur propre interface utilisateur.
- Contrôler précisément l'affichage des formulaires de données de paiement.
- Obtenir un contrôle détaillé sur le processus de confirmation de paiement.
- Offrir une expérience utilisateur plus fluide et plus cohérente au sein de l'application du commerçant.
Syntaxe
La section syntaxe fournit la signature de la méthode pour la fonction startPaymentRender Cette fonction est essentielle à l'intégration du processus de paiement dans votre application, car elle offre une approche détaillée et personnalisable de la gestion des formulaires et des flux de paiement.
@MainActor static func startPaymentRenderFlow(
paymentMethodSelected: PaymentMethodSelected,
with delegate: YunoPaymentDelegate)
async -> some YunoPaymentRenderFlowProtocolParamètres
Le champ startPaymentRender nécessite des paramètres spécifiques pour fonctionner efficacement. Ces paramètres sont essentiels pour définir la méthode de paiement et gérer les réponses au processus de paiement.
| Paramètres | Type | Description |
|---|---|---|
paymentMethodSelected | PaymentMethodSelected | La méthode de paiement sélectionnée par l'utilisateur. Doit inclure le vaultedToken (s'il existe) et le paymentMethodType |
delegate | YunoPaymentDelegate | Le délégué qui traitera les réponses du processus de paiement, y compris la création du token et le résultat final. |
Valeur de Retour
Retourne une instance qui est conforme au protocole YunoPaymentRenderFlowProtocol, lequel fournit des méthodes pour gérer le flux de rendu de paiement.
Protocole YunoPaymentRenderFlowProtocol
L'instance retournée par startPaymentRender est conforme à ce protocole qui comprend les méthodes suivantes :
formView(paymentMethodSelected:with :)
func formView(
paymentMethodSelected: PaymentMethodSelected,
with delegate: YunoPaymentDelegate)
async -> AnyView?- Objet: Obtention de la vue du formulaire pour la saisie des données de paiement
- Comportement:
- Si la méthode de paiement nécessite l'affichage d'un formulaire, il renvoie un
AnyViewavec la forme correspondante - Si la méthode de paiement n'a pas besoin d'afficher de formulaire (par exemple, les méthodes déjà configurées), le message suivant est renvoyé
nil
- Si la méthode de paiement nécessite l'affichage d'un formulaire, il renvoie un
- Quand l'utiliser: Appeler immédiatement après avoir créé l'instance de flux de paiement
submitForm()
func submitForm()- Objectif: Soumettre les données du formulaire à la validation
- Comportement: Exécute toutes les validations nécessaires et, en cas de succès, génère un nouveau token à usage unique.
- Quand l'utiliser: Lorsque l'utilisateur exécute l'action "payer" dans l'application du commerçant.
continuerPaiement()
func continuePayment() async -> AnyView?- Objectif: poursuivre le processus de paiement après la génération du token à usage unique.
- Comportement:
i. S'il est nécessaire d'afficher une vue supplémentaire (par exemple, l'authentification 3DS), renvoie un formulaire
AnyViewii. Si aucune vue supplémentaire n'est requise, les retoursnil - Quand l'utiliser: Après avoir reçu le token à usage unique par l'intermédiaire du délégué et créé le paiement.
Flux d'Implémentation
Cette section décrit la séquence des étapes nécessaires à l'Implémentation du processus de rendu des paiements à l'aide du SDK de Yuno.
Étape 1 : Configuration initiale
Pour commencer à utiliser startPaymentRenderPour cela, assurez-vous que le SDK est correctement initialisé et que vous disposez d'un numéro d'identification valide. checkoutSession. Suivez les étapes ci-dessous pour configurer votre environnement :
attendre Yuno.initialize(apiKey: « votre_clé_api »)Étape 2 : Créer une Instance de Flux de Paiement
Créer une instance de flux de paiement pour gérer et rendre le processus de paiement à l'aide de la méthode sélectionnée.
let paymentFlow = await Yuno.startPaymentRenderFlow(
paymentMethodSelected: selectedPaymentMethod,
with: self
)Étape 3 : Obtenir et afficher le formulaire
Récupérer et présenter le formulaire de paiement pour collecter efficacement les informations de paiement de l'utilisateur.
let formView = await paymentFlow.formView(
paymentMethodSelected: selectedPaymentMethod,
with: self
)
if let formView = formView {
VStack {
Text("Payment Information")
formView
Button("Pay") {
paymentFlow.submitForm()
}
}
} else {
paymentFlow.submitForm()
}Étape 4 : Gérer le Token à Usage Unique
Implémentez la méthode de délégation pour recevoir le token:
extension MyViewController: YunoPaymentDelegate {
var checkoutSession: String {
return "your_checkout_session"
}
var countryCode: String {
return "CO"
}
var viewController: UIViewController? {
return self
}
func yunoCreatePayment(with token: String, information: [String: Any]) {
createPaymentInBackend(token: token) { [weak self] success in
if success {
Task {
let additionalView = await self?.paymentFlow?.continuePayment()
if let additionalView = additionalView {
self?.showAdditionalView(additionalView)
}
}
}
}
}
func yunoPaymentResult(_ result: Yuno.Result) {
switch result {
case .succeeded:
showSuccessMessage()
case .reject:
showRejectionMessage()
case .fail:
showErrorMessage()
case .processing:
showProcessingMessage()
case .userCancell:
handleCancellation()
case .internalError:
showInternalErrorMessage()
}
}
}Exemple complet
import SwiftUI
import YunoSDK
struct PaymentRenderView: View {
@State private var paymentFlow: YunoPaymentRenderFlowProtocol?
@State private var formView: AnyView?
@State private var additionalView: AnyView?
let selectedPaymentMethod: PaymentMethodSelected
let delegate: YunoPaymentDelegate
var body: some View {
VStack(spacing: 20) {
Text("Complete Purchase")
.font(.title2)
.fontWeight(.bold)
OrderSummaryView()
if let formView = formView {
VStack(alignment: .leading) {
Text("Payment Information")
.font(.headline)
formView
}
}
if let additionalView = additionalView {
additionalView
}
Spacer()
Button(action: {
paymentFlow?.submitForm()
}) {
Text("Confirm Payment")
.font(.headline)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue)
.cornerRadius(10)
}
}
.padding()
.onAppear {
setupPaymentFlow()
}
}
private func setupPaymentFlow() {
paymentFlow = await Yuno.startPaymentRenderFlow(
paymentMethodSelected: selectedPaymentMethod,
with: delegate
)
Task {
formView = await paymentFlow?.formView(
paymentMethodSelected: selectedPaymentMethod,
with: delegate
)
}
}
}
class PaymentDelegate: YunoPaymentDelegate {
let checkoutSession: String
let countryCode: String
weak var viewController: UIViewController?
init(checkoutSession: String, countryCode: String, viewController: UIViewController?) {
self.checkoutSession = checkoutSession
self.countryCode = countryCode
self.viewController = viewController
}
func yunoCreatePayment(with token: String, information: [String: Any]) {
PaymentService.createPayment(token: token) { [weak self] result in
switch result {
case .success:
Task {
await self?.continuePaymentProcess()
}
case .failure(let error):
print("Error creating payment: \(error)")
}
}
}
func yunoPaymentResult(_ result: Yuno.Result) {
DispatchQueue.main.async {
switch result {
case .succeeded:
NotificationCenter.default.post(name: .paymentSucceeded, object: nil)
case .reject:
NotificationCenter.default.post(name: .paymentRejected, object: nil)
}
}
}
private func continuePaymentProcess() async {
}
}Cas d'Usage Courants
Cette section présente des scénarios typiques dans lesquels le SDK de Yuno peut être utilisé pour gérer différentes méthodes de paiement, offrant ainsi flexibilité et facilité d'intégration.
1. Paiement par carte de crédit
Dans ce cas d'utilisation, nous montrons comment traiter les paiements à l'aide de nouvelles informations de carte de crédit, en demandant à l'utilisateur de remplir un formulaire pour saisir les détails de la carte nécessaires.
let cardPayment = CardPaymentMethod(paymentMethodType: "CARD")
let flow = Yuno.startPaymentRender(paymentMethodSelected: cardPayment, with: delegate)
let form = await flow.formView(paymentMethodSelected: cardPayment, with: delegate)2. Paiement avec méthode enregistrée
Ce scénario illustre l'utilisation d'une méthode de paiement enregistrée, permettant aux utilisateurs de payer sans avoir à saisir à nouveau les détails en utilisant un token protégé.
let savedCard = SavedCardPayment(
paymentMethodType: "CARD",
vaultedToken: "saved_token_123")
let flow = Yuno.startPaymentRender(paymentMethodSelected: savedCard, with: delegate)
let form = await flow.formView(paymentMethodSelected: savedCard, with: delegate)3. Paiement avec authentification 3DS
3D Secure (3DS) ajoute une étape de vérification supplémentaire pour une sécurité accrue. Le SDK Yuno intègre ce processus dans votre flux de paiement de manière transparente.
func yunoCreatePayment(with token: String, information: [String: Any]) {
createPayment(token: token) { [weak self] success in
if success {
Task {
let authView = await self?.paymentFlow?.continuePayment()
if let authView = authView {
self?.show3DSView(authView)
}
}
}
}
}Considérations Importantes
Cette section met en évidence les points clés de l'intégration efficace du SDK Yuno, afin de garantir un processus de paiement transparent et sécurisé.
Prérequis
- Assurez-vous que le SDK est initialisé avant d'utiliser
startPaymentRender - Le délégué doit implémenter toutes les méthodes requises de
YunoPaymentDelegate - Le champ
checkoutSessiondoit être valide et active
Gestion de l'État
- Vérifiez toujours si
formView()retoursnilavant d'afficher la vue - Gérez correctement le cas où
continuePayment()retoursnil - Implémentez des états de chargement lors des opérations asynchrones
Sécurité
- Ne jamais stocker de tokens usage unique - les utiliser immédiatement
- Validez toujours les résultats du paiement dans votre backend
- Implémentez des délais d'attente appropriés pour les opérations du réseau
Performance
- Les appels à
formView()etcontinuePayment()sont asynchrones - Envisagez d'afficher des indicateurs de chargement lors de ces opérations
- Réutiliser l'instance de flux de paiement lorsque cela est possible
Dépannage
Cette section propose des solutions rapides aux problèmes courants rencontrés lors de l'intégration du SDK de Yuno, afin de garantir un processus de paiement sans heurts.
Problèmes courants
-
formView()renvoie toujoursnil- Vérifiez que la méthode de paiement sélectionnée nécessite un formulaire
- S'assurer que le SDK est correctement initialisé
-
Le délégué ne reçoit pas
yunoCreatePayment- Vérifiez que
submitForm()est appelé correctement - Confirmez que le formulaire contient des données valides
- Vérifiez que
-
continuePayment()ne renvoie pas la vue comme prévu- Certains méthodes de paiement ne nécessitent pas d'affichage supplémentaire
- Vérifiez la configuration de la méthode de paiement dans votre tableau de bord Yuno.
Journaux de débogage
Yuno.config.environment = .stagingMigration à partir d'autres méthodes
Si vous migrez de startPayment() ou startPaymentLite():
Yuno.startPayment()
let flow = Yuno.startPaymentRender(paymentMethodSelected: method, with: delegate)
let form = await flow.formView(paymentMethodSelected: method, with: delegate)Le principal avantage de la nouvelle méthode est le contrôle détaillé qu'elle offre à la fois sur l'interface utilisateur et sur le processus de paiement.
Application de démoEn plus des exemples de code fournis, vous pouvez accéder au dépôt Yuno pour une implémentation complète des SDK iOS de Yuno.
Implémentation de YunoPaymentDelegate avec la Concurrence Swift 6
YunoPaymentDelegate avec la Concurrence Swift 6Swift 6 introduit des exigences de concurrence plus strictes qui affectent la manière dont vous implémentez le protocole YunoPaymentDelegate . Cette section explique les défis et fournit des solutions pour différents scénarios d'implémentation.
Comprendre la Concurrence dans Swift 6La concurrence est la capacité de votre application à gérer plusieurs tâches simultanément. Avec Swift 6, les règles de concurrence sont devenues plus rigoureuses afin d'améliorer la stabilité de l'application et de prévenir les plantages. Cela signifie que votre code doit être structuré plus soigneusement pour garantir la sécurité des fils d'exécution et une gestion appropriée des tâches.
Le Problème
Avec Swift 6, les protocoles qui héritent de Sendable exigent que toutes leurs implémentations soient sécurisées pour les fils d'exécution. Cela génère des avertissements lorsque l'on implémente le délégué dans des classes marquées avec @MainActor.
La sécurité des fils d'exécution signifie que votre code peut être appelé en toute sécurité à partir de plusieurs fils d'exécution sans provoquer de plantage ou de comportement inattendu. @MainActor assure l'exécution du code sur le fil d'exécution principal (fil d'exécution de l'interface utilisateur).
Notre Décision de Conception
Nous ne marquons pas les protocoles comme @MainActor car :
- Cela obligerait toutes les implémentations à être
MainActor-compatible - Cela réduirait la flexibilité des commerçants qui n'utilisent pas
MainActor - Chaque implémentation a des besoins de concurrence différents
Responsabilité du commerçant
Il incombe au commerçant de gérer la concurrence en fonction de son implémentation. Vous trouverez ci-dessous trois approches différentes que vous pouvez utiliser en fonction de vos besoins spécifiques.
Option 1 : Propriétés immuables
Cette approche utilise des propriétés immuables qui sont automatiquement sécurisées pour les fils d'exécution, les rendant idéales pour des configurations simples. Elle est la mieux adaptée aux applications simples avec des valeurs de configuration fixes qui ne changent pas pendant l'exécution.
@MainActor
class MyViewController: UIViewController, YunoPaymentDelegate {
private let _countryCode = "CO"
private let _language = "EN"
nonisolated var countryCode: String { _countryCode }
nonisolated var language: String? { _language }
nonisolated var checkoutSession: String { _checkoutSession }
nonisolated func yunoPaymentResult(_ result: Yuno.Result) {
Task { @MainActor in
}
}
}Option 2 : Propriétés mutables avec MainActor.assumeIsolated
MainActor.assumeIsolatedCette approche, idéale pour les applications où les valeurs de configuration pourraient changer pendant l'exécution (comme les préférences utilisateur), permet des propriétés mutables tout en maintenant la sécurité des fils d'exécution grâce à l'utilisation de MainActor.assumeIsolated.
@MainActor
class MyViewController: UIViewController, YunoPaymentDelegate {
@Published var configLanguage: String = "EN"
@Published var configCountryCode: String = "CO"
nonisolated var language: String? {
MainActor.assumeIsolated { configLanguage }
}
nonisolated var countryCode: String {
MainActor.assumeIsolated { configCountryCode }
}
}Option 3 : Pour les non-MainActor cours
MainActor coursCette approche convient aux classes de service qui ne nécessitent pas MainActor isolement, ce qui le rend idéal pour les services d'arrière-plan ou les classes utilitaires qui n'interagissent pas avec l'interface utilisateur.
class MyService: YunoPaymentDelegate {
let countryCode: String
let language: String?
let checkoutSession: String
let viewController: UIViewController?
init(countryCode: String, language: String?, checkoutSession: String, viewController: UIViewController?) {
self.countryCode = countryCode
self.language = language
self.checkoutSession = checkoutSession
self.viewController = viewController
}
func yunoPaymentResult(_ result: Yuno.Result) {
}
}⚠️ Considérations Importantes
Lors de l'implémentation de la concurrence dans votre délégué, gardez ces points clés à l'esprit :
MainActor.assumeIsolated: À utiliser uniquement lorsque vous garantissez qu'il est appelé depuisMainActorIl s'agit d'un mécanisme de sécurité qui indique à Swift « fais-moi confiance, je sais que cela s'exécute sur le thread principal ».nonisolated: Cela signifie qu'il est accessible depuis n'importe quel thread, il doit donc être thread-safe. Utilisez cette option lorsque vos propriétés ou méthodes ne dépendent pas de l'état de l'interface utilisateur.viewController: Reste en@MainActorcar il doit toujours être accédé depuis le fil d'exécution principal. Les composants de l'interface utilisateur doivent toujours s'exécuter sur le fil principal pour éviter les plantages.
Mise à jour il y a 27 jours