> ## 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.

# Seamless mode

> Migrate Android Seamless integrations (Activity.startPaymentSeamlessLite) to the unified Transaction API.

Seamless was the simplest legacy entry point on Android: after wiring up the launcher with `startCheckout(…)`, a single `startPaymentSeamlessLite(paymentSelected, …)` call handed everything off: the SDK rendered the form, tokenized, created the payment, ran 3DS, and reported back through a `callbackPaymentState` lambda.

In the unified API the same flow is the **default behavior** of `Transaction.start(activity, paymentSelected)`. No controller overrides beyond `onStatus`. The structural change is the result-delivery model: was a lambda passed to the start call, now is a callback through `onStatus` on a `TransactionController`.

## Before you start

* Replace the `com.yuno.sdk.*` and `com.yuno.presentation.*` imports with their `com.yuno.payments.sdk.api.*` counterparts (the side-by-side lists them). 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 Seamless you had | In the unified API | Session `workflow` |
| - | - | - | - |
| Your backend | No equivalent: Seamless never let you create it | Override `createPayment` | Default (`SDK_CHECKOUT`) |
| The SDK | Always | 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>
  ```kotlin Before. Seamless mode theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
  import com.yuno.sdk.Yuno
  import com.yuno.sdk.payments.startCheckout
  import com.yuno.sdk.payments.startPaymentSeamlessLite
  import com.yuno.presentation.core.components.PaymentSelected

  class CheckoutActivity : ComponentActivity() {

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)

          // 1. Initialize once at app startup
          Yuno.initialize(applicationContext, apiKey = "your-public-api-key")

          // 2. Wire up the checkout launcher
          startCheckout(
              checkoutSession = "session-from-backend",
              countryCode = "CO",
          )
      }

      // 3. Trigger the payment with a single call; result arrives in the lambda
      fun pay(paymentSelected: PaymentSelected) {
          startPaymentSeamlessLite(
              paymentSelected = paymentSelected,
              showPaymentStatus = true,
              callbackPaymentState = { state, subState ->
                  when (state) {
                      "SUCCEEDED"         -> println("Success")
                      "REJECT"            -> println("Rejected")
                      "FAIL"              -> println("Failed")
                      "PROCESSING"        -> println("Processing")
                      "INTERNAL_ERROR"    -> println("Internal error")
                      "CANCELED_BY_USER"  -> println("User cancelled")
                  }
              },
          )
      }
  }
  ```

  ```kotlin After. Unified Transaction theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
  import com.yuno.payments.sdk.api.SdkPayments
  import com.yuno.payments.sdk.api.Transaction
  import com.yuno.payments.sdk.api.TransactionConfig
  import com.yuno.payments.sdk.api.TransactionController
  import com.yuno.payments.sdk.api.models.PaymentMethodSelected
  import com.yuno.payments.sdk.api.models.TransactionStatus

  class CheckoutActivity : ComponentActivity(), TransactionController {

      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)

          // 1. Initialize once at app startup
          SdkPayments.initialize(applicationContext, apiKey = "your-public-api-key")
      }

      // 2. Implement a minimal controller
      override fun onStatus(status: TransactionStatus) {
          when (status.status) {
              "SUCCEEDED"      -> println("Success")
              "DECLINED"       -> println("Declined")
              "REJECTED"       -> println("Rejected")
              "ERROR"          -> println("Error")
              "PENDING"        -> println("Pending")
              "INTERNAL_ERROR" -> println("Internal error")
              "USER_CANCEL"    -> println("User cancelled")
          }
      }

      // 3. Trigger the payment
      fun pay(paymentSelected: PaymentMethodSelected) {
          val config = TransactionConfig(
              checkoutSession = "session-from-backend",
              countryCode = "CO",
              language = "en",
              controller = this,
              showStatusScreen = true,
          )

          Transaction(config = config)
              .start(activity = this, paymentSelected = paymentSelected)
      }
  }
  ```
</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. **New**: no legacy counterpart. The last column is the only thing you have to do beyond the rename.

### Initialization and config

| Seamless | Unified | Change | What to do |
| - | - | - | - |
| `import com.yuno.sdk.*` | `import com.yuno.payments.sdk.api.*` | Renamed | |
| `Yuno.initialize(context, apiKey)` | `SdkPayments.initialize(context, apiKey)` | Renamed | |
| `checkoutSession`, `countryCode` arguments of `startCheckout` | The same fields on `TransactionConfig` | Moved | Same values; the config also takes the `controller` (see Controller). |
| `showPaymentStatus` argument of `startPaymentSeamlessLite` | `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

| Seamless | Unified | Change | What to do |
| - | - | - | - |
| *(no controller: a lambda passed to the start call)* | `TransactionController` | New | Even the simplest case needs a controller instance: implement `TransactionController` with just `onStatus` and pass it as `TransactionConfig.controller`. The SDK does not retain it: keep it alive for the whole transaction. |
| `callbackPaymentState: (state, subState) -> Unit` | `onStatus(status: TransactionStatus)` | Moved | The result arrives through the controller instead of a lambda passed to the start call. Still the single outcome callback, once per transaction, also when the SDK shows its result screen. The raw `(state, subState)` pair becomes a `TransactionStatus` object: `status` and `substatus` come from the backend, as the backend returns them. The legacy `REJECT`, `FAIL` and `PROCESSING` strings are no longer emitted: handle `DECLINED`, `REJECTED`, `ERROR` and `PENDING` instead. `CANCELED_BY_USER` is now `USER_CANCEL`. The SDK itself only emits `INTERNAL_ERROR` and `USER_CANCEL`. See [`Status`](/docs/yuno-sdk/reference/objects-you-receive#status). |

### Entry points

| Seamless | Unified | Change | What to do |
| - | - | - | - |
| `startCheckout(…)` + `startPaymentSeamlessLite(paymentSelected, showPaymentStatus, callbackPaymentState)` | `Transaction(config).start(activity, paymentSelected)` | Renamed | Build the config, then `start`: single entry point, and the outcome arrives in `onStatus`. You still pick the method and pass it. The `Activity` extension functions become one call on a regular `Transaction` instance, which doesn't need an `Activity` to construct. |
| `PaymentSelected` | `PaymentMethodSelected` | Renamed | Same role: the value you pass to `start`. |

## Related

* [Get Started](/docs/yuno-sdk/get-started). The unified-API walkthrough; the new "Seamless equivalent" is now the default path.
* [`onStatus`](/docs/yuno-sdk/controllers/on-status). Controller that delivers the final status.
* [`TransactionConfig`](/docs/yuno-sdk/reference/objects-you-pass#transaction-config). Complete field reference.
* [Migration / Lite](/docs/yuno-sdk/migration/android/payment/lite). Almost identical migration; Seamless and Lite collapse into the same default path in the unified API.


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