iOS SDK

安装

选项 1:CocoaPods

添加到你的 Podfile:

pod 'YunoSDK'
吊舱安装

选项 2:Swift 软件包管理器

在 Xcode 中:文件 → 添加包依赖项

https://github.com/yuno-payments/yuno-sdk-ios
📘

要求:iOS 14.0+,Swift 5.7+

Initialize

AppDelegate.swift 或 App 结构体:

import YunoSDK

// In AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions...) -> Bool {
    Yuno.initialize(apiKey: "your-public-api-key")
    return true
}

// Or in SwiftUI App struct
init() {
    Yuno.initialize(apiKey: "your-public-api-key")
}

基本支付流程

SwiftUI 示例

import SwiftUI
import YunoSDK

struct PaymentView: View {
    @State private var showPayment = false
    @StateObject private var viewModel = PaymentViewModel()
    
    var body: some View {
        VStack {
            Text("Total: $25.00")
                .font(.title)
            
            Button("Pay Now") {
                Task {
                    await viewModel.startPayment()
                }
            }
        }
        .task {
            await viewModel.initialize()
        }
    }
}

@MainActor
class PaymentViewModel: ObservableObject, YunoPaymentFullDelegate {
    private var _checkoutSession: String = ""
    private var _countryCode: String = "US"
    private var paymentMethodsView: UIView?
    
    // YunoPaymentFullDelegate required properties
    var checkoutSession: String { _checkoutSession }
    var countryCode: String { _countryCode }
    var language: String? { "en" }
    var viewController: UIViewController? { nil }
    
    func initialize() async {
        // Create checkout session on backend
        let session = await createCheckoutSession()
        _checkoutSession = session.checkoutSession
        
        // Get payment methods view from SDK
        paymentMethodsView = await Yuno.getPaymentMethodViewAsync(delegate: self)
        
        // Add view to your UI hierarchy (in SwiftUI, use UIViewRepresentable)
    }
    
    func startPayment() async {
        // Start payment - SDK reads session from delegate properties
        Yuno.startPayment()
    }
    
    // YunoPaymentFullDelegate methods
    func yunoCreatePayment(with token: String, information: [String: Any]) {
        Task {
            await createPayment(token: token)
            Yuno.continuePayment(showPaymentStatus: true)
        }
    }
    
    func yunoPaymentResult(_ result: Yuno.Result) {
        switch result {
        case .success:
            print("Payment succeeded")
        case .failure(let error):
            print("Payment failed:", error)
        }
    }
    
    func yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat) {
        // Called when payment methods view height changes
        print("Payment methods view height:", height)
    }
    
    func yunoDidSelect(paymentMethod: PaymentMethodSelected) {
        // Called when user selects a payment method
        print("Selected payment method:", paymentMethod)
    }
}

func createCheckoutSession() async -> CheckoutSession {
    // Call your backend
    let response = try? await URLSession.shared.data(from: URL(string: "https://api.example.com/checkout")!)
    return try! JSONDecoder().decode(CheckoutSession.self, from: response!.0)
}

UIKit示例

import UIKit
import YunoSDK

class PaymentViewController: UIViewController, YunoPaymentFullDelegate {
    private var _checkoutSession: String = ""
    private var paymentMethodsView: UIView?
    
    // YunoPaymentFullDelegate required properties
    var checkoutSession: String { _checkoutSession }
    var countryCode: String { "US" }
    var language: String? { "en" }
    var viewController: UIViewController? { self }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        Task {
            // 1. Create session on backend
            let session = await createCheckoutSession()
            _checkoutSession = session.checkoutSession
            
            // 2. Get payment methods view from SDK
            paymentMethodsView = await Yuno.getPaymentMethodViewAsync(delegate: self)
            
            // 3. Add payment methods view to hierarchy
            if let methodsView = paymentMethodsView {
                methodsView.translatesAutoresizingMaskIntoConstraints = false
                view.addSubview(methodsView)
                NSLayoutConstraint.activate([
                    methodsView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                    methodsView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                    methodsView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
                ])
            }
            
            // 4. Add pay button
            let payButton = UIButton(type: .system)
            payButton.setTitle("Pay Now", for: .normal)
            payButton.addTarget(self, action: #selector(payButtonTapped), for: .touchUpInside)
            payButton.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(payButton)
            NSLayoutConstraint.activate([
                payButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20),
                payButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
            ])
        }
    }
    
    @objc func payButtonTapped() {
        // Start payment - SDK reads session from delegate properties
        Yuno.startPayment()
    }
    
    // YunoPaymentFullDelegate methods
    func yunoCreatePayment(with token: String, information: [String: Any]) {
        Task {
            await createPayment(token: token, checkoutSession: _checkoutSession)
            Yuno.continuePayment(showPaymentStatus: true)
        }
    }
    
    func yunoPaymentResult(_ result: Yuno.Result) {
        switch result {
        case .success:
            navigationController?.pushViewController(SuccessViewController(), animated: true)
        case .failure(let error):
            showAlert(message: "Payment failed: \(error.localizedDescription)")
        }
    }
    
    func yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat) {
        // Called when payment methods view height changes
        // Update constraints if needed
        print("Payment methods view height:", height)
    }
    
    func yunoDidSelect(paymentMethod: PaymentMethodSelected) {
        // Called when user selects a payment method
        print("Selected payment method:", paymentMethod)
    }
}

处理支付结果

func yunoPaymentResult(_ result: Yuno.Result) {
    switch result {
    case .success(let data):
        switch data.status {
        case "SUCCEEDED":
            navigateToSuccess()
        case "PENDING":
            showPendingMessage()
        default:
            break
        }
        
    case .failure(let error):
        switch error.code {
        case .cardDeclined:
            showError("Card was declined")
        case .insufficientFunds:
            showError("Insufficient funds")
        case .networkError:
            showError("Network error, please try again")
        default:
            showError("Payment failed: \(error.localizedDescription)")
        }
    }
}

3DS认证

3DS验证将自动处理。对于异步支付方式:

func yunoCreatePayment(with token: String, information: [String: Any]) {
    Task {
        await createPayment(token: token)
        
        // Handle redirects if needed
        let result = await Yuno.continuePayment(showPaymentStatus: false)
        
        if let redirectURL = result?.redirectURL {
            // Open redirect URL
            UIApplication.shared.open(redirectURL)
        }
    }
}

配置选项

基本参数

参数类型说明
checkoutSession字符串后端会话ID
countryCode字符串ISO国家代码(例如'US')
language字符串?语言代码(例如 'en')
viewControllerUIViewController?用于呈现支付用户界面(UIKit)

卡片配置

let config =YunoConfig(
 checkoutSession: session.id,
 countryCode: "US",
    cardSaveEnable: true, // 显示保存复选框
    cardFormType: .default, // 或 .extended
    allowedPaymentTypes: [.credit, .debit]
)

外观

Yuno.Appearance.主色 = .系统蓝
Yuno.Appearance.背景色 = .系统背景色
Yuno.Appearance.字体 = .系统字体(字号: 16)
Yuno.Appearance.圆角半径 = 8.0

下一步行动

准备探索更多高级功能了吗?查看《高级功能指南》了解:

  • 替代安装方案 - startPaymentLite()startPaymentSeamlessLite() 用于自定义支付方式选择
  • 注册(保存卡片)——保存支付方式以备将来使用
  • 拱顶Token ——一键支付,保存卡片
  • 自定义用户界面(无头集成)——构建完全定制的支付表单
  • 渲染模式集成- 在自定义视图中显示支付表单
  • 样式与外观- 自定义 SDK 外观
  • Swift 6 并发- 使用正确注解处理并发警告
  • ClearSale集成- 欺诈预防

另见: