Funciones avanzadas SDK para iOS
Configuración avanzada e integraciones personalizadas para iOS.
Opciones de montaje alternativas
El flujo básico utiliza Yuno.startPayment() que gestiona automáticamente todo el pago . Para tener más control, utiliza estas alternativas:
Selección de pago personalizado (startPaymentLite)
startPaymentLite)Selecciona qué pago mostrar. Tu delegado debe implementar YunoPaymentFullDelegate con las propiedades requeridas:
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
)
}
}Flujo simplificado (startPaymentSeamlessLite)
startPaymentSeamlessLite)Similar a Lite, pero con pago automática pago :
Yuno.startPaymentSeamlessLite(
paymentMethodType: "CARD",
vaultedToken: nil,
delegate: self
)Inscripción (Guardar tarjetas)
Ahorra durante pago
Tu delegado proporciona la información de la sesión a través de las propiedades:
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)
}
}
}Inscripción por separado
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 almacenados
Utiliza las tarjetas guardadas proporcionando el token almacenado en la bóveda 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
)
}
}Interfaz de usuario personalizada (integración sin interfaz gráfica)
Crea pago totalmente personalizados con control total de la interfaz de usuario cuando necesites un control completo sobre cada elemento de la interfaz, experiencias de pago altamente personalizadas o dispongas de recursos de desarrollo para una interfaz de usuario personalizada.
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)")
}
}
}Con Token almacenado
let resultado = try await apiClient.generateToken(datos: TokenCollectedData(
checkoutSession: "session_id",
método de pago: CollectedData(
tipo: "CARD",
vaultedToken: "saved_token_id",
tarjeta: CardData(código de seguridad: "123")
)
))Integración del modo de renderizado
Muestra pago dentro de tu vista personalizada.
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) {}
}Estilo y apariencia
Personaliza la apariencia del SDK con Yuno.Appearance:
import YunoSDK
func configureAppearance() {
var appearance = Yuno.Appearance()
// Colores
appearance.primaryColor = UIColor.systemBlue
appearance.backgroundColor = UIColor.systemBackground
appearance.textColor = UIColor.label
appearance.errorColor = UIColor.systemRed
// Tipografía
appearance.fontFamily = "SF Pro Display"
appearance.fontSize = 16
// Radio de esquina
appearance.cornerRadius = 12
// Aplicar
Yuno.setAppearance(appearance)
}Concurrencia en Swift 6
Maneja las advertencias de concurrencia con las anotaciones adecuadas:
@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)
}
}Delegado no aislado:
extension PaymentViewController {
nonisolated func yunoPaymentResult(_ result: PaymentResult) {
MainActor.assumeIsolated {
// UI updates here
self.showResult(result)
}
}
}Integración con ClearSale
Habilita la prevención de fraudes:
Instala el SDK de 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
}Los datos de ClearSale se recopilan automáticamente y se envían junto con los pagos.
Configuración personalizada
Tipos de flujo de tarjetas
Configura el flujo de entrada de tarjetas durante la inicialización de Yuno:
// In AppDelegate or App struct
Yuno.initialize(
apiKey: "your-public-key",
cardFlow: .oneStep // or .stepByStep
)Ocultar nombre del titular de la tarjeta
Configurar la visibilidad del nombre del titular de la tarjeta:
// Set globally
Yuno.hideCardholderName = trueMostrar/ocultar la pantalla de estado
Pantalla de control pago en continuePayment():
func yunoCreatePayment(with token: String, information: [String: Any]) {
Task {
await createPayment(token: token)
Yuno.continuePayment(showPaymentStatus: false) // Handle result yourself
}
}Gestión de errores
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)")
}
}Webhooks
Verificar pago en el backend:
// Backend receives webhook
POST /webhooks/yuno
{
"type": "payment.succeeded",
"data": {
"payment_id": "pay_123",
"status": "SUCCEEDED",
"amount": 2500
}
}Pruebas
Modo de prueba
// Use test key
Yuno.initialize(apiKey: "pk_test_your_key")Registro de depuración
// Enable logs in development
#if DEBUG
Yuno.setLogLevel(.verbose)
#endifActuación
Precarga el SDK
// Preload in background
Task(priority: .background) {
_ = Yuno.self
}Carga diferida
// Load only when needed
lazy var yuno: Yuno = {
Yuno.initialize(apiKey: "pk_test_key")
return Yuno.shared
}()Actualizado hace 1 día