Full SDK (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.
Cette page fournit toutes les étapes pour ajouter, configurer et utiliser Full SDK (iOS) dans votre projet.
Prérequis
Pour implémenter le SDK iOS de Yuno, vous devez satisfaire aux exigences 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
Pour ajouter le SDK Yuno à votre projet iOS, vous devez installer le SDK Yuno. Si vous n'avez pas de Podfile, suivez le guide CocoaPods pour en créer un. Après avoir créé le Podfile, intégrez le SDK Yuno avec Cocoapods en ajoutant la ligne ci-dessous à votre Podfile.
pod 'YunoSDK', '~> 1.1.22'Ensuite, vous devez exécuter l'installation :
installation du pod
Swift Package Manager
Pour ajouter le SDK Yuno à votre projet iOS, vous devez installer le Swift Package ManagerUne fois le package Swift configuré, ajoutez YunoSDK en tant que dépendance, comme présenté dans le bloc de code suivant :
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
Pour commencer à exécuter le paiement Yuno iOS Full, obtenez d'abord votre ID d'application Yuno et votre Clé API Publique. Ensuite, importez et initialisez Yuno comme indiqué ci-dessous :
import YunoSDK
Yuno.initialize(
apiKey: "PUBLIC_API_KEY",
config: YunoConfig(),
callback: { (value: Bool) in }
)
IdentifiantsPour plus d'informations, Consultez la page des identifiants : https://docs.y.uno/reference/authentication
Utilisation de UISceneDelegateSi votre application utilise un UISceneDelegate, assurez-vous de placer votre code d'initialisation Yuno dans votre SceneDelegate.
Le paiement Complet vous permet de configurer l'apparence et le processus. C'est une étape optionnelle que vous configurez via la classe YunoConfig. Si vous souhaitez définir les configurations, le bloc de code suivant montre les éléments qui peuvent être configurés :
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éder à votre clé APIRécupérez votre clé API depuis la section Développeurs du tableau de bord Yuno.
Étape 3 : Démarrer le processus de paiement
La classe ViewController est définie comme une sous-classe de UIViewController et adopte également 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 importante sur yunoCreatePaymentVous 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 : Ajouter la Vue du SDK au Paiement
Votre vue doit adopter le protocole YunoPaymentFullDelegate . Cela permet à votre application de répondre aux actions liées au paiement, comme lorsque l'utilisateur sélectionne une méthode de paiement.
Voici comment définir le délégué :
protocol YunoPaymentFullDelegate: YunoPaymentDelegate {
func yunoDidSelect(paymentMethod: YunoSDK.PaymentMethodSelected)
func yunoDidUnenrollSuccessfully(_ success: Bool)
func yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat)
}Paramètres
| Fonction | Description |
|---|---|
yunoDidSelect(paymentMethod: YunoSDK.PaymentMethodSelected) | Appelé lorsque l'utilisateur sélectionne une méthode de paiement. - paymentMethod: La méthode choisie par l'utilisateur. |
yunoDidUnenrollSuccessfully(_ success: Bool) | Appelée lorsqu'une action de désenregistrement se termine. - success: true si l'opération a réussi, sinon false . |
yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat) | Appelée lorsque getPaymentMethodViewAsync() est invoquée et chaque fois que la hauteur de la vue change. |
Pour afficher les méthodes de paiement, appelez la méthode suivante et passez votre modèle de vue ou contrôleur comme délégué.
await Yuno.getPaymentMethodViewAsync(delegate :)Cette méthode renverra automatiquement le type de vue correct en fonction du framework UI que vous utilisez :
- Si vous utilisez UIKitil renvoie un
UIView. - Si vous utilisez SwiftUIil renvoie un
some View.
Il est ainsi facile d'intégrer le SDK dans n'importe quel projet iOS, quel que soit le cadre d'interface utilisateur utilisé.
Étape 5 : Lancer le processus de paiement
Pour démarrer un paiement après avoir affiché les méthodes de paiement, appelez la méthode startPayment : Indicateurs booléens
Yuno.startPayment(showPaymentStatus:Bool)Étape 6 : 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 implémentez lors de l'adoption du YunoPaymentDelegate. Un exemple de récupération du token à usage unique est présenté ci-dessous :
func yunoCreatePayment(with token: String) { ... }Étape 7 : Créer le paiement
Une fois que vous avez terminé les étapes décrites ci-dessus, vous pouvez créer un paiement. La création d'un paiement de bout en bout doit être effectuée à l'aide du 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.
Méthode ContinuePaymentPour garantir une expérience de paiement fluide, il est crucial d'intégrer la méthode
continuePaymentaprès avoir créé un paiement. Cette étape est particulièrement importante pour les méthodes de paiement asynchrones qui nécessitent des actions client supplémentaires. Voici ce qu'il faut savoir :
- Gestion du Paiement Asynchrone: L'API signalera la nécessité d'une action supplémentaire avec le champ
sdk_action_requireddéfini sur true.- Fonctionnalité: La fonction
yuno.continuePayment()est conçue pour gérer et afficher tous les écrans supplémentaires nécessaires au client pour finaliser le paiement.- Simplification du processus: En utilisant cette méthode, vous pouvez rationaliser le processus de paiement, car elle gère automatiquement divers scénarios pour vous.
Yuno.continuePayment()Étape 8 : 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.
Rappel
Une fois le paiement effectué, le SDK peut renvoyer différents états de la transaction : success, fail, processing, reject, internalErroret userCancell. Les descriptions de chaque état de transaction sont présentées dans le tableau ci-dessous.
| État de la transaction | Description |
|---|---|
succeeded | 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 | Cet état Indique que la transaction est en cours de traitement. Il est généralement utilisé lorsqu'il y a un retard dans le traitement du paiement, 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 des demandes qui enfreignent 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 un problème du côté du serveur ou du backend plutôt qu'un problème lié à 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é.
Afin d'obtenir l'état de la transaction, vous devez implémenter le délégué présenté dans le code suivant :
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 fournit des services et des configurations supplémentaires que vous pouvez utiliser pour améliorer l'expérience de vos clients. Utilisez les personnalisations du SDK pour modifier l'apparence du SDK afin qu'il corresponde à votre marque ou pour 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. Vous trouverez ci-dessous 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.
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:
- S'il est nécessaire d'afficher une vue supplémentaire (par exemple, l'authentification 3DS), il renvoie un formulaire
AnyView - Si aucune vue supplémentaire n'est requise, il renvoie
nil
- S'il est nécessaire d'afficher une vue supplémentaire (par exemple, l'authentification 3DS), il renvoie un formulaire
- 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(showPaymentStatus: true)
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 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