Recursos avançados do SDK para iOS
Configuração avançada e integrações personalizadas para iOS.
Opções alternativas de montagem
O fluxo básico utiliza Yuno.startPayment() que lida com todo o fluxo de pagamento automaticamente. Para obter mais controle, use estas alternativas:
Seleção de método de pagamento personalizado (startPaymentLite)
startPaymentLite)Selecione qual método de pagamento exibir. Seu delegado deve implementar YunoPaymentFullDelegate com as propriedades necessárias:
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
)
}
}Fluxo simplificado (startPaymentSeamlessLite)
startPaymentSeamlessLite)Semelhante ao Lite, mas com criação automática de pagamentos:
Yuno.startPaymentSeamlessLite(
paymentMethodType: "CARTÃO",
vaultedToken: nil,
delegado: self
)Inscrição (Salvar cartões)
Salvar durante o pagamento
Seu delegado fornece as informações da sessão por meio de propriedades:
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)
}
}
}Inscrição separada
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 armazenados
Use os cartões salvos fornecendo o token armazenado no cofre 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
)
}
}IU personalizada (integração sem interface gráfica)
Crie formulários de pagamento totalmente personalizados com controle total da interface do usuário quando precisar de controle total sobre todos os elementos da interface, experiências de checkout altamente personalizadas ou tiver recursos de desenvolvimento para uma interface 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)")
}
}
}Com Token Vaulted Token
let resultado = tente aguarde apiClient.generateToken(dados: TokenCollectedData(
checkoutSession: "session_id",
paymentMethod: CollectedData(
tipo: "CARD",
vaultedToken: "saved_token_id",
cartão: CardData(código de segurança: "123")
)
))Integração do modo de renderização
Exiba o formulário de pagamento em sua visualização 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 e aparência
Personalize a aparência do SDK com Yuno.Appearance:
import YunoSDK
func configureAppearance() {
var appearance = Yuno.Appearance()
// Cores
appearance.primaryColor = UIColor.systemBlue
appearance.backgroundColor = UIColor.systemBackground
appearance.textColor = UIColor.label
appearance.errorColor = UIColor.systemRed
// Tipografia
aparência.fontFamily = "SF Pro Display"
aparência.fontSize = 16
// Raio do canto
aparência.cornerRadius = 12
// Aplicar
Yuno.setAppearance(aparência)
}Concorrência no Swift 6
Lide com avisos de simultaneidade com anotações adequadas:
@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 não isolado:
extension PaymentViewController {
nonisolated func yunoPaymentResult(_ result: PaymentResult) {
MainActor.assumeIsolated {
// UI updates here
self.showResult(result)
}
}
}Integração ClearSale
Habilite a prevenção contra fraudes:
Instale o 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
}Os dados da ClearSale são coletados automaticamente e enviados junto com os pagamentos.
Configuração personalizada
Tipos de fluxo de cartões
Configure o fluxo de entrada do cartão durante a inicialização do Yuno:
// In AppDelegate or App struct
Yuno.initialize(
apiKey: "your-public-key",
cardFlow: .oneStep // or .stepByStep
)Ocultar nome do titular do cartão
Configurar a visibilidade do nome do titular do cartão:
// Set globally
Yuno.hideCardholderName = trueMostrar/ocultar tela de status
Controle a tela de status de pagamento em continuePayment():
func yunoCreatePayment(with token: String, information: [String: Any]) {
Task {
await createPayment(token: token)
Yuno.continuePayment(showPaymentStatus: false) // Handle result yourself
}
}Tratamento de erros
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
Verifique o status do pagamento no backend:
// Backend receives webhook
POST /webhooks/yuno
{
"type": "payment.succeeded",
"data": {
"payment_id": "pay_123",
"status": "SUCCEEDED",
"amount": 2500
}
}Testes
Modo de teste
// Use test key
Yuno.initialize(apiKey: "pk_test_your_key")Registro de depuração
// Enable logs in development
#if DEBUG
Yuno.setLogLevel(.verbose)
#endifDesempenho
Pré-carregar SDK
// Preload in background
Task(priority: .background) {
_ = Yuno.self
}Carregamento lento
// Load only when needed
lazy var yuno: Yuno = {
Yuno.initialize(apiKey: "pk_test_key")
return Yuno.shared
}()Atualizado há 1 dia