Fonctionnalités avancées SDK iOS
Configuration avancée et intégrations personnalisées pour iOS.
Options de montage alternatives
Le flux de base utilise Yuno.startPayment() qui gère automatiquement l'intégralité du flux de paiement. Pour plus de contrôle, utilisez ces alternatives :
Sélection d'un mode de paiement personnalisé (startPaymentLite)
startPaymentLite)Sélectionnez le mode de paiement à afficher. Votre délégué doit mettre en œuvre YunoPaymentFullDelegate avec les propriétés requises :
class PaymentViewController: UIViewController, YunoPaymentFullDelegate {
var checkoutSession: String { return _checkoutSession }
var countryCode: String { "US" }
var language: String? { "en" }
var viewController: UIViewController? { self }
private var _checkoutSession: String = ""
func setupPayment() async {
// 1. Create session
let session = await createCheckoutSession()
_checkoutSession = session.checkoutSession
// 2. Fetch available methods
let methods = await fetchPaymentMethods(sessionId: checkoutSession)
// 3. Display in your UI, then start payment with selected method
Yuno.startPaymentLite(
paymentMethodType: selectedMethod, // "CARD", "PIX", etc.
vaultedToken: nil, // or saved token
delegate: self
)
}
}Flux simplifié (startPaymentSeamlessLite)
startPaymentSeamlessLite)Similaire à Lite, mais avec création automatique des paiements :
Yuno.startPaymentSeamlessLite(
paymentMethodType: "CARD",
vaultedToken: nil,
delegate: self
)Inscription (enregistrer les cartes)
Enregistrer pendant le paiement
Votre délégué fournit les informations de session via les propriétés :
class PaymentViewController: UIViewController, YunoPaymentFullDelegate {
var checkoutSession: String { _checkoutSession }
var countryCode: String { "US" }
var language: String? { "en" }
var viewController: UIViewController? { self }
private var _checkoutSession: String = ""
func setupPayment() async {
let session = await createCheckoutSession()
_checkoutSession = session.checkoutSession
// Start payment - SDK will show save card checkbox automatically
Yuno.startPayment()
}
// In delegate:
func yunoCreatePayment(with token: String, information: [String: Any]) {
Task {
await createPayment(
token: token,
vaultOnSuccess: true // Save after successful payment
)
Yuno.continuePayment(showPaymentStatus: true)
}
}
}Inscription séparée
class EnrollmentViewController: UIViewController, YunoEnrollmentDelegate {
var customerSession: String { _customerSession }
var countryCode: String { "US" }
var language: String? { "en" }
var viewController: UIViewController? { self }
private var _customerSession: String = ""
func setupEnrollment() async {
// Create customer session on backend
let session = await createCustomerSession(customerId: "cus_123")
_customerSession = session.id
// Start enrollment - SDK reads session from delegate
Yuno.enrollPayment(delegate: self)
}
func yunoEnrollmentStatus(status: Yuno.EnrollmentStatus, vaultedToken: String?) {
if status == .successful, let token = vaultedToken {
print("Card saved:", token)
}
}
func yunoDidSelect(enrollmentMethod: EnrollmentMethodSelected) {
print("Selected enrollment method:", enrollmentMethod)
}
}Token voûtés
Utilisez les cartes enregistrées en fournissant le token stocké dans le coffre-fort token startPaymentLite:
class PaymentViewController: UIViewController, YunoPaymentFullDelegate {
var checkoutSession: String { _checkoutSession }
var countryCode: String { "US" }
var language: String? { "en" }
var viewController: UIViewController? { self }
private var _checkoutSession: String = ""
func payWithSavedCard(vaultedToken: String) {
Yuno.startPaymentLite(
paymentMethodType: "CARD",
vaultedToken: vaultedToken,
delegate: self
)
}
}Interface utilisateur personnalisée (intégration sans interface graphique)
Créez des formulaires de paiement entièrement personnalisés avec un contrôle total de l'interface utilisateur lorsque vous avez besoin d'un contrôle complet sur chaque élément de l'interface utilisateur, d'expériences de paiement hautement personnalisées ou que vous disposez de ressources de développement pour une interface utilisateur personnalisée.
import YunoSDK
class CustomPaymentVC: UIViewController {
func processWithCustomUI() async {
// 1. Initialize headless client
let apiClient = Yuno.apiClientPayment(
countryCode: "US",
checkoutSession: "session_id"
)
// 2. Collect card data in your custom UI
let cardData = CardData(
number: "4111111111111111",
expirationMonth: 12,
expirationYear: 25,
securityCode: "123",
holderName: "John Doe",
type: .credit
)
// 3. Generate token
do {
let result = try await apiClient.generateToken(data: TokenCollectedData(
checkoutSession: "session_id",
paymentMethod: CollectedData(
type: "CARD",
card: cardData
)
))
// 4. Create payment with token
await createPayment(token: result.token)
// 5. Handle continuation if needed
if apiClient.shouldContinue {
try await apiClient.continuePayment()
}
} catch {
print("Error: \(error)")
}
}
}Avec Token voûté
let result = try await apiClient.generateToken(data: TokenCollectedData(
checkoutSession: "session_id",
paymentMethod: CollectedData(
type: "CARD",
vaultedToken: "saved_token_id",
card: CardData(securityCode: "123")
)
))Intégration du mode de rendu
Affichez le formulaire de paiement dans votre vue personnalisée.
class PaymentViewController: UIViewController, YunoPaymentRenderFlowProtocol {
func startRenderMode() async {
let session = try await createCheckoutSession()
let config = YunoConfig(
checkoutSession: session.id,
countryCode: "US"
)
Yuno.startPaymentRenderFlow(with: config, delegate: self)
}
// SDK provides view to embed
func formView() -> UIView? {
let containerView = UIView(frame: CGRect(x: 0, y: 0, width: 350, height: 500))
containerView.backgroundColor = .systemBackground
return containerView
}
// Handle form submission
func submitForm() async {
// Customer submitted payment form
}
// Handle result
func yunoPaymentResult(_ result: PaymentResult) {
if result.status == .succeeded {
navigateToSuccess()
}
}
}SwiftUI :
struct RenderModeView: View, YunoPaymentRenderFlowProtocol {
@State private var paymentView: UIView?
var body: some View {
if let view = paymentView {
PaymentViewWrapper(view: view)
.frame(height: 500)
}
}
func startPayment() async {
let config = YunoConfig(checkoutSession: "session_id", countryCode: "US")
await Yuno.startPaymentRenderFlow(with: config, delegate: self)
}
func formView() -> UIView? {
let view = UIView()
DispatchQueue.main.async {
paymentView = view
}
return view
}
}
struct PaymentViewWrapper: UIViewRepresentable {
let view: UIView
func makeUIView(context: Context) -> UIView { view }
func updateUIView(_ uiView: UIView, context: Context) {}
}Style et apparence
Personnalisez l'apparence du SDK avec Yuno.Appearance:
import YunoSDK
func configureAppearance() {
var appearance = Yuno.Appearance()
// Couleurs
appearance.primaryColor = UIColor.systemBlue
appearance.backgroundColor = UIColor.systemBackground
appearance.textColor = UIColor.label
appearance.errorColor = UIColor.systemRed
// Typographie
apparence.fontFamily = "SF Pro Display"
apparence.fontSize = 16
// Rayon des coins
apparence.cornerRadius = 12
// Appliquer
Yuno.setAppearance(apparence)
}Concurrence Swift 6
Traitez les avertissements de concurrence avec des annotations appropriées :
@MainActor
class PaymentViewController: UIViewController, YunoPaymentFullDelegate {
var checkoutSession: String { _checkoutSession }
var countryCode: String { "US" }
var language: String? { "en" }
var viewController: UIViewController? { self }
private var _checkoutSession: String = ""
// Safe to call from any thread
nonisolated func startPayment() {
Task { @MainActor in
Yuno.startPayment()
}
}
// UI updates on main thread
@MainActor
func yunoPaymentResult(_ result: PaymentResult) {
updateUI(result)
}
}Délégué non isolé :
extension PaymentViewController {
nonisolated func yunoPaymentResult(_ result: PaymentResult) {
MainActor.assumeIsolated {
// UI updates here
self.showResult(result)
}
}
}Intégration ClearSale
Activer la prévention contre la fraude :
Installer le SDK ClearSale :
pod « ClearSaleSDK »Initialize:
import ClearSale
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Initialize ClearSale
ClearSale.setup(apiKey: "your-clearsale-key")
// Initialize Yuno
Yuno.initialize(apiKey: "your-public-key")
return true
}Les données ClearSale sont automatiquement collectées et envoyées avec les paiements.
Configuration personnalisée
Types de flux de cartes
Configurer le flux d'entrée de la carte lors de l'initialisation de Yuno :
// In AppDelegate or App struct
Yuno.initialize(
apiKey: "your-public-key",
cardFlow: .oneStep // or .stepByStep
)Masquer le nom du titulaire de la carte
Configurer la visibilité du nom du titulaire de la carte :
// Set globally
Yuno.hideCardholderName = trueAfficher/Masquer l'écran d'état
Contrôler l'état des paiements dans continuePayment():
func yunoCreatePayment(with token: String, information: [String: Any]) {
Task {
await createPayment(token: token)
Yuno.continuePayment(showPaymentStatus: false) // Handle result yourself
}
}Gestion des erreurs
func yunoPaymentResult(_ result: PaymentResult) {
switch result.status {
case .succeeded:
handleSuccess(result)
case .failed:
handleFailure(result.error)
case .pending:
handlePending(result)
case .rejected:
handleRejection(result)
}
}
func handleFailure(_ error: YunoError?) {
guard let error = error else { return }
switch error.code {
case "SESSION_EXPIRED":
// Recreate session
Task { await createNewSession() }
case "INVALID_CARD":
showAlert("Please check your card details")
case "INSUFFICIENT_FUNDS":
showAlert("Insufficient funds")
case "NETWORK_ERROR":
showAlert("Connection error. Please try again.")
default:
showAlert("Payment failed: \(error.message)")
}
}Point d’ancrage Web
Vérifier le statut du paiement dans le backend :
// Backend receives webhook
POST /webhooks/yuno
{
"type": "payment.succeeded",
"data": {
"payment_id": "pay_123",
"status": "SUCCEEDED",
"amount": 2500
}
}Test
Mode test
// Use test key
Yuno.initialize(apiKey: "pk_test_your_key")Journalisation de débogage
// Enable logs in development
#if DEBUG
Yuno.setLogLevel(.verbose)
#endifPerformance
Précharger le SDK
// Preload in background
Task(priority: .background) {
_ = Yuno.self
}Chargement différé
// Load only when needed
lazy var yuno: Yuno = {
Yuno.initialize(apiKey: "pk_test_key")
return Yuno.shared
}()Mise à jour il y a 1 jour