高级功能 iOS SDK
iOS的高级配置和自定义集成。
替代安装方案
基本流程使用 Yuno.startPayment() 该方案可自动处理完整的支付流程。若需更多控制权,请使用以下替代方案:
自定义支付方式选择(startPaymentLite)
startPaymentLite)选择要显示的支付方式。您的委托人必须实现 YunoPaymentFullDelegate 具有所需属性:
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
)
}
}简化流程 (startPaymentSeamlessLite)
startPaymentSeamlessLite)与精简版类似,但具备自动创建付款功能:
Yuno.startPaymentSeamlessLite(
paymentMethodType: "CARD",
vaultedToken: nil,
delegate: self
)注册(保存卡片)
付款时节省
您的委托人通过属性提供会话信息:
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)
}
}
}单独注册
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
通过提供保险库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
)
}
}自定义用户界面(无头集成)
当您需要完全掌控每个用户界面元素、打造高度定制的结账体验,或拥有开发定制界面的资源时,可构建具备完整用户界面控制权的完全定制化支付表单。
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)")
}
}
}使用拱顶Token
let result = try await apiClient.generateToken(data: TokenCollectedData(
checkoutSession: "session_id",
paymentMethod: CollectedData(
type: "CARD",
vaultedToken: "saved_token_id",
card: CardData(securityCode: "123")
)
))渲染模式集成
在您的自定义视图中显示付款表单。
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) {}
}造型与外观
自定义 SDK 外观 Yuno.Appearance:
import YunoSDK
func configureAppearance() {
var appearance =Yuno.Appearance()
// 颜色
appearance.primaryColor = UIColor.systemBlue
appearance.backgroundColor = UIColor.systemBackground
appearance.textColor = UIColor.label
appearance.errorColor = UIColor.systemRed
// 字体样式
appearance.fontFamily = "SF Pro Display"
appearance.fontSize = 16
// 圆角半径
appearance.cornerRadius = 12
// 应用样式
Yuno.setAppearance(appearance)
}Swift 6 并发
使用正确的注解处理并发警告:
@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)
}
}非隔离委托人:
extension PaymentViewController {
nonisolated func yunoPaymentResult(_ result: PaymentResult) {
MainActor.assumeIsolated {
// UI updates here
self.showResult(result)
}
}
}ClearSale 集成
启用欺诈预防:
安装 ClearSale SDK:
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
}ClearSale数据会随支付交易自动收集并发送。
自定义配置
卡片流类型
在Yuno初始化期间配置卡片输入流程:
// In AppDelegate or App struct
Yuno.initialize(
apiKey: "your-public-key",
cardFlow: .oneStep // or .stepByStep
)隐藏持卡人姓名
配置持卡人姓名可见性:
// Set globally
Yuno.hideCardholderName = true显示/隐藏状态屏幕
控制付款状态屏幕 continuePayment():
func yunoCreatePayment(with token: String, information: [String: Any]) {
Task {
await createPayment(token: token)
Yuno.continuePayment(showPaymentStatus: false) // Handle result yourself
}
}错误处理
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)")
}
}网络钩子
在后端验证支付状态:
// Backend receives webhook
POST /webhooks/yuno
{
"type": "payment.succeeded",
"data": {
"payment_id": "pay_123",
"status": "SUCCEEDED",
"amount": 2500
}
}测试
测试模式
// Use test key
Yuno.initialize(apiKey: "pk_test_your_key")调试日志记录
// Enable logs in development
#if DEBUG
Yuno.setLogLevel(.verbose)
#endif性能
预加载 SDK
// Preload in background
Task(priority: .background) {
_ = Yuno.self
}延迟加载
// Load only when needed
lazy var yuno: Yuno = {
Yuno.initialize(apiKey: "pk_test_key")
return Yuno.shared
}()1 天前已更新