API

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 Flow
      Swift
      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.swift pour 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.tapToPayNotConfigured devient YavinLoginError.tapToPayDisabled
  • Multi-société

1.5.1 - 22/08/2025

  • Ajout de champs à YavinPaymentRequest
    • reference: String?
    • idempotentUuid: String?
  • Ajout de champs à YavinPaymentResult
    • scheme: 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

DistributionSwift Package Manager
AuthentificationFlux de connexion autonome (identifiants du marchand) ou clé API Yavin
Convention de nommageAPI Swift, montants en entiers exprimés en centimes
Version actuellev1.7.3
Remise des résultatsSynchrone : 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 :

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.

Illustration de la documentation

Application de démonstration

Vous trouverez une application de démonstration sur ce dépôt :

https://gitlab.com/yavin-public/demo-ios

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 :

Swift
import YavinSDK

Accéder à l'instance partagée

Accédez aux fonctionnalités via l'instance YavinManager.shared :

Swift
let yavinSdk = YavinManager.shared

SwiftUI : 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.

Swift
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 :

  1. Affichage d'un écran « publicitaire »
  2. Connexion du marchand avec ses identifiants Yavin
  3. Acceptation des conditions de Yavin relatives à Tap to Pay

Voici le rendu :

Illustration de la documentation
Illustration de la documentation
Illustration de la documentation

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é.

Swift
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.

Swift
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.

Swift
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é

Swift
// 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.

Swift
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

Swift
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.

Swift
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 :

Swift
YavinManager.shared.enableTipsScreen(enable: true)

Vérifier l'éligibilité par programmation

Swift
if YavinManager.shared.isDeviceEligible() {
    // Device supports Tap to Pay
} else {
    // Device doesn't meet requirements
}

Dans votre application, vous pouvez accéder à YavinManager.shared.YavinEligibilityView() pour consulter l'éligibilité de l'appareil de manière autonome.

Exemple :

Illustration de la documentation
Swift
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

Illustration de la documentation
Swift
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.

Swift
YavinManager.shared.prepareProximityReader()

Structure des données

YavinLoginRequest

Swift
public struct YavinLoginRequest {
    public let yavinApiKey: String?
}

YavinLoginResult

Swift
public struct YavinLoginResult {
    public let success: Bool
    public let apiKey: String? // filled when returnApiKey is true
}

YavinLoginError

Swift
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

Swift
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

Swift
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

Swift
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)
}