SDK Apple iOS Tap to Pay
v1.7.3
Notes de version
1.7.3 - 10/08/2026
- Depuis Xcode 27, la version minimale prise en charge doit être iOS 15 : YavinSDK requiert désormais une version de déploiement minimale = iOS 15
1.7.1 - 30/07/2026
1.7.0 - 13/05/2026
1.6.7 - 21/01/2026
- SDK Sandbox : correction d'un plantage lors de la connexion
1.6.6 - 21/11/2025 🧘♂️
YavinManager.shared.isLoggedIn()n'était pas mis à jour dans le callback de succès de la connexion. Ce problème est corrigé
1.6.5 - 21/11/2025
- Permet à l'intégrateur de demander la clé d'API Yavin après une connexion réussie via le Standalone Login FlowSwift
YavinManager.shared.showTapToPayActivationFlow( viewController: currentViewController, onDismiss: {}, returnApiKey: true, <----- NEW onCompletion: { result in switch result { case .success(let loginResult): if loginResult.success { // SDK is logged in, payments can be processed } case .failure(let error): // handle error } } )
1.6.4 - 18/11/2025
- Correction d'une transaction envoyée avec le statut "pending" au lieu de "ko" lorsque la carte n'est pas lue
1.6.3 - 13/10/2025
- Correction de
Package.swiftpour la compatibilité avec iOS 13
1.6.2 - 08/10/2025
- Correction de l'URL d'enregistrement
1.6.1 - 08/10/2025
- Corrections de l'interface
1.6.0 - 02/10/2025
- « Compatibilité » iOS 13 : votre application peut récupérer YavinSDK, mais rien ne sera accessible sans vérification de la version d'iOS.
- Pour améliorer le parcours de connexion depuis une caisse, nous avons introduit un « Standalone Login Flow ». Ce nouveau parcours offre à la caisse un flux complet, de l'enregistrement du compte TTPOI et l'acceptation des conditions Yavin jusqu'à l'authentification Yavin. Consultez la documentation pour plus de détails.
YavinLoginError.tapToPayNotConfigureddevientYavinLoginError.tapToPayDisabled- Multi-société
1.5.1 - 22/08/2025
- Ajout de champs à
YavinPaymentRequestreference: String?idempotentUuid: String?
- Ajout de champs à
YavinPaymentResultscheme: String?paymentApplication: String?reference: String?idempotentUuid: String?issuer: String?cardToken: String?clientTicket: String?companyTicket: String?
1.5.0 - 21/08/2025
- Amélioration de l'historique : ajout de filtres par date, heure, numéro de série, référence et schéma
1.4.2 - 08/07/2025
- Correction du mode sombre
1.4.1 - 27/06/2025
- Correction d'un plantage à l'affichage du tutoriel TTPOI sur certains appareils
1.4.0 - 26/06/2025
- Refonte de l'interface
1.3.0 - 05/06/2025
- Renvoi d'une nouvelle erreur lors de la connexion ou de l'actualisation de la connexion (
YavinLoginError.tapToPayNotConfigured) lorsque le marchand n'a pas demandé l'activation TTPOI auprès de Yavin.
1.2.0 - 28/05/2025
- Prise en compte de la couleur de la marque de la société définie dans Corus pour personnaliser l'application
1.1.3 - 22/05/2025
- Correction du mode sombre
- Correction d'un plantage lié au lecteur de proximité Apple
1.1.1 - 20/05/2025
- Correction du tutoriel qui ne s'affichait pas sur certains appareils sous iOS 18+. Le tutoriel natif est affiché dans ce cas
1.1.0 - 20/05/2025
- Ajout de la fonctionnalité d'historique avec filtre par date simple
- Ajout d'un écran de pourboires selon les paramètres de la société dans Corus (classique, favori, emoji)
- Activation de la fonctionnalité de pourboires selon les paramètres de la société dans Corus
1.0.0 → 1.0.9
- Connexion via la clé d'API Yavin
- Lancement et traitement d'un paiement (débit, annulation)
- Partage du ticket par e-mail et par QR code
- Tutoriel Tap2Pay
- Écran d'éligibilité
- Localisation prise en charge : français, anglais
Cette documentation présente une vue d'ensemble et le détail des composants principaux du YavinSDK, en se concentrant sur la classe YavinManager et ses types associés. Le SDK gère l'authentification, le traitement des paiements et l'éligibilité de l'appareil pour la fonctionnalité Tap to Pay.
En bref
| Distribution | Swift Package Manager |
| Authentification | Flux de connexion autonome (identifiants du marchand) ou clé API Yavin |
| Convention de nommage | API Swift, montants en entiers exprimés en centimes |
| Version actuelle | v1.7.3 |
| Remise des résultats | Synchrone : completion handlers sur chaque appel du SDK |
Présentation
Le SDK propose des solutions pour :
- Authentification de l'utilisateur : gestion de la connexion avec la clé API Yavin ou avec un e-mail et un mot de passe.
- Traitement des paiements : lancement et finalisation des requêtes de paiement.
- Éligibilité de l'appareil : vérification que l'appareil remplit les prérequis nécessaires (par ex. version d'iOS, caractéristiques matérielles, code de verrouillage).
- Interface utilisateur : affichage des vues d'authentification et de paiement en présentation modale plein écran.
- Gestion des erreurs : traitement et propagation des erreurs liées à l'authentification, au paiement et à l'éligibilité de l'appareil.
Prérequis
- Matériel : iPhone XS ou plus récent (pour Tap to Pay)
- Système de l'appareil : iOS 17+ (pour Tap to Pay)
- Sécurité : un code de verrouillage doit être défini sur l'appareil
Installation
Ajouter la dépendance
Ajoutez la dépendance Swift package à votre projet Xcode :
Project -> Package Dependencies -> Click + icon
Dans la barre de recherche, ajoutez la dépendance correspondant à votre usage :
- PROD : https://gitlab.com/yavin-public/ios-sdk-spm.git
- SANDBOX : https://gitlab.com/yavin-public/ios-sdk-spm-sandbox.git
Dans l'environnement SANDBOX, vous avez besoin d'un compte iCloud Sandbox.
Demandez l'ajout de la capability Tap to Pay on iPhone à votre compte Apple.

Application de démonstration
Vous trouverez une application de démonstration sur ce dépôt :
Diagramme de flux
Tap to Pay on iPhone : diagramme de flux de bout en bout (Figma)
Utilisation de YavinManager
La classe YavinManager est le point central d'interaction avec le SDK. Elle suit le patron singleton et regroupe les fonctionnalités d'authentification et de paiement de Yavin.
Importer le SDK
Pour commencer, ajoutez d'abord l'import YavinSDK :
import YavinSDKAccéder à l'instance partagée
Accédez aux fonctionnalités via l'instance YavinManager.shared :
let yavinSdk = YavinManager.sharedSwiftUI : obtenir le UIViewController
Si vous utilisez SwiftUI, certaines méthodes de l'API nécessitent un UIViewController pour fonctionner. Le SDK fournit une classe utilitaire ViewControllerAccessor pour accéder au UIViewController depuis votre vue SwiftUI.
struct MySwiftUIView: View {
@State private var currentViewController: UIViewController?
var body: some View {
VStack {
// Use `currentViewController` to launch Yavin features
}
.background(
ViewControllerAccessor { vc in
self.currentViewController = vc
}
)
}
}Authentification
Il existe deux façons de connecter le SDK :
- Flux de connexion autonome
- Avec la clé d'API Yavin
Flux de connexion autonome
Comme la caisse ne dispose pas forcément de la clé d'API Yavin pour se connecter, nous proposons un flux autonome.
Le flux autonome permet à une caisse d'offrir aux marchands une expérience fluide pour activer Tap to Pay on iPhone.
Il se déroule en 3 étapes :
- Affichage d'un écran « publicitaire »
- Connexion du marchand avec ses identifiants Yavin
- Acceptation des conditions de Yavin relatives à Tap to Pay
Voici le rendu :



Une fois les conditions acceptées par le marchand, le SDK se connecte et, en cas de succès, les paiements peuvent être traités.
La caisse peut détecter l'authentification du SDK avec YavinManager.shared.isLoggedIn() (voir plus bas)
Recommandations :
La caisse doit afficher un bouton « Activer Tap to Pay on iPhone » si le SDK n'est pas connecté. Au clic sur ce bouton, la caisse doit appeler YavinManager.shared.showTapToPayActivationFlow(). L'écran « publicitaire » présenté ci-dessus s'affichera alors.
Lorsque la connexion réussit, la caisse peut masquer le bouton, car à ce stade le SDK Yavin est connecté avec le marchand et peut traiter des paiements.
Si la caisse peut basculer entre plusieurs points de vente, il lui incombe de déconnecter puis reconnecter le SDK Yavin avant de traiter des paiements pour le nouveau point de vente sélectionné.
YavinManager.shared.showTapToPayActivationFlow(
viewController: currentViewController,
onDismiss: {},
returnApiKey: false,
onCompletion: { result in
switch result {
case .success(let loginResult):
if loginResult.success {
// SDK is logged in, payments can be processed
}
case .failure(let error):
// handle error
}
}
)Connexion avec la clé d'API Yavin
Les partenaires peuvent utiliser cette méthode s'ils gèrent déjà la clé d'API Yavin ; sinon, nous recommandons d'utiliser le flux autonome.
let request = YavinLoginRequest(
yavinApiKey: "your_yavin_api_key"
)
YavinManager.shared.login(
viewController: self,
request: request
) { result in
switch result {
case .success(let loginResult):
if loginResult.success {
// Handle successful login
}
case .failure(let error):
// Handle error
}
}Actualiser la connexion
Cette méthode permet d'actualiser le jeton utilisé en interne par le SDK pour activer le traitement des paiements.
Vous devez être connecté pour utiliser cette méthode.
YavinManager.shared.refreshLogin(viewController: self) { result in
switch result {
case .success(let loginResult):
if loginResult.success {
// Handle successful login
}
case .failure(let error):
// Handle error
}
}Vérifier si l'utilisateur est connecté
// Boolean check
let isLoggedIn = YavinManager.shared.isLoggedIn()
// Publisher for reactive updates
var cancellables = Set<AnyCancellable>()
YavinManager.shared.isLoggedIn()
.sink { isLoggedIn in
// Update UI
}
.store(in: &cancellables)Déconnexion
Cette méthode efface toutes les données et définit YavinManager.shared.isLoggedIn sur false. Vous devrez vous reconnecter pour encaisser des paiements.
YavinManager.shared.logout()Paiement
Une fois le SDK connecté, les paiements se lancent en un seul appel. Les montants sont toujours des entiers exprimés en centimes.
Lancer un paiement via l'API
let paymentRequest = YavinPaymentRequest(
amount: 1000, // In cents: 10€
transactionType: .debit,
reference: "my reference"
)
YavinManager.shared.launchPaymentRequest(
viewController: self,
request: paymentRequest
) { result in
switch result {
case .success(let paymentResult):
// Handle processed payment
print("payment with id \(paymentResult.transactionId) processed")
case .failure(let error):
// Handle payment error
}
}Annuler un paiement via l'API
Définit transactionType sur reversal. Pendant le traitement du paiement, un code PIN est requis pour confirmer l'annulation.
Le code PIN est disponible sur la page de votre société dans le backoffice Yavin, sous Détails de la société > Code PIN.
let paymentRequest = YavinPaymentRequest(
amount: 1000, // In cents: 10€
transactionType: .reversal
)
YavinManager.shared.launchPaymentRequest(
viewController: self,
request: paymentRequest
) { result in
switch result {
case .success(let paymentResult):
// Handle processed payment
print("payment with id \(paymentResult.transactionId) processed")
case .failure(let error):
// Handle payment error
}
}Fonctionnalités supplémentaires
Activation des pourboires
Pour proposer un pourboire à votre client, utilisez la fonction suivante :
YavinManager.shared.enableTipsScreen(enable: true)Vérifier l'éligibilité par programmation
if YavinManager.shared.isDeviceEligible() {
// Device supports Tap to Pay
} else {
// Device doesn't meet requirements
}
Accéder à EligibilityView
Dans votre application, vous pouvez accéder à YavinManager.shared.YavinEligibilityView() pour consulter l'éligibilité de l'appareil de manière autonome.
Exemple :

NavigationLink(destination: YavinManager.shared.YavinEligibilityView()) {
VStack(alignment: .leading) {
Text("Eligibility")
.foregroundStyle(.black)
Text("SoftPos requirements")
.font(.footnote)
.foregroundStyle(.gray)
}
}Présentation du tutoriel Tap to Pay

Task {
await YavinManager.shared.showTapToPayTutorial(viewController: self)
}Préparer ProximityReader
Pour offrir une expérience fluide à vos utilisateurs, vous devez préparer le lecteur de proximité de l'appareil avant un paiement (sinon, le démarrage effectif du paiement peut prendre quelques secondes).
Appelez prepareProximityReader() en amont du paiement :
Le SDK appelle cette fonction en interne lors :
- de la connexion
- du renouvellement de la connexion
- avant le démarrage du paiement
Recommandation : préparez le lecteur de proximité pendant la saisie du montant ou des produits à payer.
YavinManager.shared.prepareProximityReader()Structure des données
YavinLoginRequest
public struct YavinLoginRequest {
public let yavinApiKey: String?
}YavinLoginResult
public struct YavinLoginResult {
public let success: Bool
public let apiKey: String? // filled when returnApiKey is true
}YavinLoginError
public enum YavinLoginError: Error, Sendable, Hashable {
case deviceNotEligible(message: String? = nil)
case invalidCredentials(message: String? = nil)
case loginYavinFailed(message: String? = nil)
case loginGatewayFailed(message: String? = nil)
case refreshLoginForbidden(message: String? = nil)
case tapToPayDisabled(message: String? = nil)
case invalidPaymentContract(message: String? = nil)
case tapToPayTermsNotGranted(message: String? = nil)
}YavinPaymentRequest
public struct YavinPaymentRequest {
public let amount: Int
public let transactionType: YavinTransactionType
public let currency: String
public let reference: String?
public let idempotentUuid: String?
public init(
amount: Int,
transactionType: YavinTransactionType,
currency: String? = "EUR",
reference: String? = nil,
idempotentUuid: String? = nil
) {
self.amount = amount
self.transactionType = transactionType
self.currency = currency ?? "EUR"
self.reference = reference
self.idempotentUuid = idempotentUuid
}
}YavinPaymentResult
public struct YavinPaymentResult: Hashable {
public let success: Bool
public let transactionId: String?
public let amount: Int
public let giftAmount: Int
public let totalAmount: Int
public let transactionType: YavinTransactionType
public let currency: String
public let requiresSignature: Bool
public let deviceTimestamp: Int?
public let ticketUrl: String?
public let issuer: String?
public let scheme: String?
public let reference: String?
public let idempotentUuid: String?
public let cardToken: String?
public let paymentApplication: String?
public let clientTicket: String?
public let companyTicket: String?
}YavinPaymentError
public enum YavinPaymentError: Error, Sendable {
case deviceNotEligible(message: String? = nil)
case notLoggedIn(message: String? = nil)
case cancelByUser(message: String? = nil)
case illegalTransactionState(message: String? = nil)
case paymentFailed(message: String? = nil)
}