> ## Documentation Index
> Fetch the complete documentation index at: https://docs.y.uno/llms.txt
> Use this file to discover all available pages before exploring further.

# Full mode

> Migrate iOS Full integrations (Yuno.getPaymentMethodViewAsync + Yuno.startPayment) to the unified Transaction API.

Full mode rendered the SDK's payment method list inside your layout, fired callbacks when the user picked a method, then handed off to the SDK to render the form and process the payment. In the unified API the same flow uses a single `Transaction` plus `getPaymentMethodsViews(...)` for the embedded list, with the controllers split in two: `SdkPayments.TransactionController` for the transaction lifecycle and `SdkPayments.PaymentListController` for list-specific events.

## Before you start

* Replace `import YunoSDK` with `import SdkPayments`. Your public API key and the checkout sessions your backend creates do not change ([Before you begin](/docs/yuno-sdk/get-started#before-you-begin)).
* Decide who creates the payment. The checkout session's `workflow` must match that decision:

| Who creates the payment | In Full you had | In the unified API | Session `workflow` |
| - | - | - | - |
| Your backend | `yunoCreatePayment` implemented | Override `createPayment` | Default (`SDK_CHECKOUT`) |
| The SDK | No equivalent: only Seamless let the SDK create the payment | No override | `SDK_SEAMLESS` |

<Warning>
  A default-workflow session with no `createPayment` override ends in `INTERNAL_ERROR`: the backend rejects the SDK's payment creation. See [`createPayment`](/docs/yuno-sdk/controllers/create-payment).
</Warning>

## Side-by-side

<CodeGroup>
  ```swift Before. Full mode theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
  import SwiftUI
  import YunoSDK

  // 1. Initialize once at app startup
  Yuno.initialize(
      apiKey: "your-public-api-key",
      config: YunoConfig(appearance: customAppearance, saveCardEnabled: true)
  )

  // 2. Implement the Full delegate (combines payment + list events)
  final class CheckoutModel: YunoPaymentFullDelegate, ObservableObject {
      var checkoutSession: String = "session-from-backend"
      var countryCode: String = "CO"
      var language: String? = "en"
      var viewController: UIViewController?

      @Published var selectedPaymentMethod: PaymentMethodSelected?

      // Payment events
      func yunoPaymentResult(_ result: Yuno.Result) {
          switch result.status {
          case .succeeded:      print("Success")
          case .reject:         print("Rejected")
          case .fail:           print("Failed")
          case .processing:     print("Processing")
          case .internalError:  print("Internal error")
          case .userCancelled:  print("User cancelled")
          @unknown default:     break
          }
      }

      // Payment-list events
      func yunoDidSelect(paymentMethod: PaymentMethodSelected) {
          selectedPaymentMethod = paymentMethod
      }
      func yunoDidUnenrollSuccessfully(_ success: Bool) { /* refresh UI */ }
      func yunoUpdatePaymentMethodsViewHeight(_ height: CGFloat) { /* relayout */ }
  }

  // 3. Embed the SDK's list and trigger payment
  struct CheckoutView: View {
      @StateObject var model = CheckoutModel()
      @State var list: AnyView?

      var body: some View {
          VStack {
              list
              Button("Pay") {
                  Yuno.startPayment(showPaymentStatus: true)
              }
              .disabled(model.selectedPaymentMethod == nil)
          }
          .task {
              list = AnyView(await Yuno.getPaymentMethodViewAsync(delegate: model))
          }
      }
  }
  ```

  ```swift After. Unified Transaction theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
  import SwiftUI
  import SdkPayments

  // 1. Initialize once at app startup
  SdkPayments.initialize(apiKey: "your-public-api-key")

  // 2. Implement BOTH controllers on the same model (or split them)
  final class CheckoutModel:
      SdkPayments.TransactionController,
      SdkPayments.PaymentListController,
      ObservableObject {

      @Published var selectedPaymentMethod: SdkPayments.PaymentMethodSelected?

      // Transaction events
      func onStatus(status: SdkPayments.TransactionStatus) {
          switch status.status {
          case "INTERNAL_ERROR":  print("Internal error")
          case "USER_CANCEL":     print("User cancelled")
          // Handle other backend statuses (e.g. SUCCEEDED, DECLINED, PENDING) as needed.
          default:                break
          }
      }

      // Payment-list events
      func onPaymentSelected(paymentSelected: SdkPayments.PaymentMethodSelected) {
          selectedPaymentMethod = paymentSelected
      }
      func onUnenroll(success: Bool) { /* refresh UI */ }
      func onHeightChange(newHeight: CGFloat) { /* relayout */ }
  }

  // 3. Build a Transaction, embed the list, trigger payment
  struct CheckoutView: View {
      @StateObject var model = CheckoutModel()
      @State var transaction: SdkPayments.Transaction?
      @State var list: AnyView?

      var body: some View {
          VStack {
              list
              Button("Pay") {
                  if let selected = model.selectedPaymentMethod {
                      transaction?.start(paymentSelected: selected)
                  }
              }
              .disabled(model.selectedPaymentMethod == nil)
          }
          .task {
              let config = SdkPayments.TransactionConfig(
                  checkoutSession: "session-from-backend",
                  countryCode: "CO",
                  language: "en",
                  appearance: customAppearance,
                  controller: model,
                  showStatusScreen: true,
                  saveCardEnabled: true
              )
              let tx = SdkPayments.Transaction(config: config)
              transaction = tx
              let views = tx.getPaymentMethodsViews(
                  types: [.PAYMENT_METHOD_LIST],
                  controller: model
              )
              list = views[.PAYMENT_METHOD_LIST]
          }
      }
  }
  ```
</CodeGroup>

## What changes

Grouped in the order you edit the code. **Renamed**: same role, new name. **Moved**: same value, new owner. **Removed**: nothing to call. The last column is the only thing you have to do beyond the rename.

### Initialization and config

| Full | Unified | Change | What to do |
| - | - | - | - |
| `import YunoSDK` | `import SdkPayments` | Renamed | |
| `Yuno.initialize(apiKey:config:)` | `SdkPayments.initialize(apiKey:)` | Renamed | `YunoConfig` is gone: its fields move to `SdkPayments.TransactionConfig` (next rows). The `callback:` parameter is gone too; use the `async` overload if you need to wait. |
| `YunoConfig.appearance` | `SdkPayments.TransactionConfig.appearance` | Moved | Pass it per transaction instead of once at startup. |
| `Yuno.Appearance` | `SdkPayments.Appearance` | Renamed | Same initializer; drop the `Yuno.` prefix. |
| `YunoConfig.saveCardEnabled` | `SdkPayments.TransactionConfig.saveCardEnabled` | Moved | Defaults to `false`. With `true`, the card form shows the save-card checkbox (payments only), unchecked. |
| `YunoConfig.keepLoader` | *(removed)* | Removed | The SDK keeps its loader. Override `showLoading` only if you want your own (see Controller). |
| `YunoPaymentFullDelegate.checkoutSession`, `.countryCode`, `.language`, `.viewController` | The same fields on `SdkPayments.TransactionConfig` | Moved | Delegate properties become config fields. `viewController` stays iOS-only and optional in SwiftUI. |
| `showPaymentStatus:` argument of `startPayment` | `SdkPayments.TransactionConfig.showStatusScreen` | Moved | See the note below. |

<Note>
  **The SDK result screen is off by default now.** Set `showStatusScreen: true` to keep it.
</Note>

### Controller

| Full | Unified | Change | What to do |
| - | - | - | - |
| `YunoPaymentFullDelegate` | `SdkPayments.TransactionController` + `SdkPayments.PaymentListController` | Renamed | One delegate becomes two controllers: Full mixed transaction events (`yunoPaymentResult`) and list events (`yunoDidSelect` and the rest), the unified API splits them. You can still conform the same class to both, as in the example above. Pass it as `TransactionConfig.controller` and as the `controller` of `getPaymentMethodsViews`. As before, the SDK does not retain it: keep it alive for the whole transaction. |
| `yunoPaymentResult(_:)` | `onStatus(status:)` | Renamed | Still the single outcome callback, once per transaction, also when the SDK shows its result screen. `status` and `substatus` come from the backend; the SDK itself only emits `INTERNAL_ERROR` and `USER_CANCEL`. See [`Status`](/docs/yuno-sdk/reference/objects-you-receive#status). |
| `Yuno.Result.message` | `SdkPayments.TransactionStatus.message` | Renamed | Same role. `source` is now an enum (`.sdk` / `.backend`) and `code` is non-optional. |
| `yunoCreatePayment(with:)` / `(with:information:)` | `createPayment(token:)` | Renamed | Optional. One handler replaces both variants; `token` is the full One-Time Token as a dictionary. Create the payment and return: returning is what used to be `continuePayment()`. If the handler throws, the flow stops and `onStatus` is not called, so show the error yourself. See [`createPayment`](/docs/yuno-sdk/controllers/create-payment). |
| `YunoLoaderDelegate.onLoading(isLoading:)` | `showLoading(isLoading:)` | Renamed | Optional. Full never invoked it. If you override it now, the SDK hides its own loader and reports the state to you. See [`showLoading`](/docs/yuno-sdk/controllers/show-loading). |
| `onInstallmentSelected(_:)` with `YunoInstallmentSelected` | `onInstallmentSelected(_:)` with `SdkPayments.InstallmentSelected` | Renamed | Optional. Same trigger and fields; only the payload type changes. It fires when the shopper selects or changes an installment in the SDK's card form, including the SDK's default auto-selection, and with `nil` when the selection no longer applies. See [`onInstallmentSelected`](/docs/yuno-sdk/controllers/on-installment-selected). |
| `YunoShippingDelegate.onShippingAddressChanged(_:shippingInfo:)` | `onShippingAddressChanged(_:shippingInfo:)` via `SdkPayments.ShippingAddressHandling` | Moved | Optional. Conform the controller to the protocol; the types drop the `Yuno` prefix and the completion-based variant is gone. Same async signature and role: real-time shipping updates on the Apple Pay sheet. The protocol inherits from `TransactionController`, so the SDK picks it up from the `controller` you pass in the config. See [`onShippingAddressChanged`](/docs/yuno-sdk/controllers/on-shipping-address-changed). |
| `yunoDidSelect(paymentMethod:)` | `onPaymentSelected(paymentSelected:)` | Renamed | Required. Store the `SdkPayments.PaymentMethodSelected` it gives you: `start` needs it (see Entry points). |
| `yunoDidUnenrollSuccessfully(_:)` | `onUnenroll(success:)` | Renamed | Optional. Same `Bool` payload. |
| `yunoUpdatePaymentMethodsViewHeight(_:)` | `onHeightChange(newHeight:)` | Renamed | Optional. |

### Entry points

| Full | Unified | Change | What to do |
| - | - | - | - |
| `Yuno.getPaymentMethodViewAsync(delegate:)` | `transaction.getPaymentMethodsViews(types:controller:)` | Renamed | It returned a single `some View`; the new call returns `[SdkPayments.PaymentMethodType: AnyView]`. Pass `[.PAYMENT_METHOD_LIST]` for the equivalent of Full and read `views[.PAYMENT_METHOD_LIST]`; the subscript returns `nil` for types you did not request. You can also request `.APPLE_PAY()` in the same call to get the wallet button. |
| `Yuno.getPaymentMethodViewAsync(delegate:)` returning `UIView` | `transaction.getPaymentMethodsViewsUIKit(types:controller:)` | Renamed | Same dictionary shape as the SwiftUI call, with `UIView` values. |
| `Yuno.startPayment(showPaymentStatus:)` | `transaction.start(paymentSelected:)` | Renamed | The SDK no longer remembers the selection: pass the `SdkPayments.PaymentMethodSelected` you stored from `onPaymentSelected`. `showPaymentStatus` moved to the config (see Initialization and config). |
| `Yuno.continuePayment()` | *(removed)* | Removed | Delete the call: returning from `createPayment` resumes the flow (the SDK polls the status, runs 3DS if needed and calls `onStatus`). Set [`autoContinuePayment`](/docs/yuno-sdk/reference/objects-you-pass#autocontinuepayment) to `false` only if you need the SDK to stop right after the payment is created. |
| `Yuno.receiveDeeplink(_:)` | `SdkPayments.handleDeeplink(_:)` | Renamed | Same role: forward the URL your app receives after an external redirect. See [Handle deeplinks](/docs/yuno-sdk/features/handle-deeplinks). |
| `Yuno.hideLoader()` | *(removed)* | Removed | Delete the call: the SDK dismisses its own loader. With a `showLoading` override you receive `isLoading: false` instead. |

## Related

* [Get Started](/docs/yuno-sdk/get-started). Full unified-API walkthrough.
* [Payment Methods List](/docs/yuno-sdk/features/payment-methods-list). The new `getPaymentMethodsViews` API.
* [`TransactionConfig`](/docs/yuno-sdk/reference/objects-you-pass#transaction-config). Complete field reference.
* [Migration / Lite](/docs/yuno-sdk/migration/ios/payment/lite). The simpler case (single pre-selected method).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.