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

# Objects you pass

> The objects your app builds and hands to the SDK: TransactionConfig, PaymentMethodSelected and TransactionData.

The objects your app builds and hands to the SDK: the per-transaction configuration, the payment method the shopper picked, and the data you collected yourself when you skip the SDK's forms.

<Tabs>
  <Tab title="TransactionConfig" id="transaction-config">
    `TransactionConfig` is the configuration object passed to the `Transaction` constructor. It defines the session, locale, controllers, and behavior flags for a single transaction.

    <Note>
      On web, `TransactionConfig` is a plain object passed directly to `sdkPayments.transaction(config)`.
    </Note>

    ## Fields

    <Tabs>
      <Tab title="Web">
        | Field | Type | Required | Default |
        | - | - | - | - |
        | [`checkoutSession`](#checkoutsession) | String | One of two | |
        | [`customerSession`](#customersession) | String | One of two | |
        | [`countryCode`](#countrycode) | String | Yes | |
        | [`language`](#language) | String? | No | Browser language |
        | [`onStatus`](/docs/yuno-sdk/controllers/on-status) | (status) => void | No | |
        | [`showLoading`](/docs/yuno-sdk/controllers/show-loading) | (isLoading) => void | No | |
        | [`createPayment`](/docs/yuno-sdk/controllers/create-payment) | (token) => void \| Promise | No | |
        | [`onChange`](#onchange-web-only) | (state) => void | No | |
        | [`showStatusScreen`](#showstatusscreen) | Bool | No | `true` |
        | [`autoContinuePayment`](#autocontinuepayment) | Bool | No | `true` |
        | [`elementSelector`](#elementselector-web-only) | String \| HTMLElement | Yes for form payments | |
        | [`showPayButton`](#showpaybutton-web-only) | Bool | No | `true` |
        | [`card`](#card-web-only) | Object | No | |
        | [`texts`](#texts-web-only) | Object | No | |
        | [`externalButtons`](#externalbuttons-web-only) | Object | No | |

        On Web there is no `controller` field: wire events (`onStatus`, `showLoading`, `createPayment`) directly as fields on the config. See [`controller`](#controller-ios-android). Without `onStatus` the SDK logs a console warning and never delivers the result. `createPayment` must be a function when present. The constructor throws otherwise.

        Payment-only fields on Web. An enrollment config does not take them, and neither does it take `createPayment`, `showPayButton` or `autoContinuePayment`.

        | Field | Type | Description |
        | - | - | - |
        | `deviceFingerprints` | Array | Fraud provider sessions, `{ provider_id, session_id }` each, that the SDK attaches to the one-time token. |
        | `showOnlyThesePaymentMethods` | String\[] | Payment method types the payment methods list shows. The list hides every other type. |
        | `paymentListConfig` | Object | Scroll options of the payment methods list: `scrollContainerSelector`, `visibleTriggerOffsetPx` and `bottomOffsetPx`. `paymentMethodList.mount()` accepts the same options. |
        | `savePaymentMethodEnabled` | Bool | Shows the save checkbox on non-card methods that support saving, when the session has a customer. |
        | `inputDesignType` | String | Label style of the SDK inputs: `'float-label'` (default), `'float-label-static'` or `'label-placeholder'`. |
        | `c2p` | Object | Click to Pay options: `recognitionToken`, `onRecognitionTokenCreated` and `onRecognitionTokenDeleted`. |
      </Tab>

      <Tab title="iOS">
        | Field | Type | Required | Default |
        | - | - | - | - |
        | [`checkoutSession`](#checkoutsession) | String | One of two | |
        | [`customerSession`](#customersession) | String | One of two | |
        | [`countryCode`](#countrycode) | String | Yes | |
        | [`language`](#language) | String? | No | Device language |
        | [`controller`](#controller-ios-android) | TransactionController | Yes | |
        | [`showStatusScreen`](#showstatusscreen) | Bool | No | `false` |
        | [`autoContinuePayment`](#autocontinuepayment) | Bool | No | `true` |
        | [`saveCardEnabled`](#savecardenabled-ios) | Bool | No | `false` |
        | [`appearance`](#appearance-ios-android) | Appearance? | No | `null` |
        | [`viewController`](#viewcontroller-ios-only) | UIViewController? | No | `null` |

        `autoContinuePayment` and `saveCardEnabled` are payment-only: the enrollment initializer, `init(customerSession:...)`, does not take them.

        Shipping callbacks are not a config field on iOS: conform the `controller` object to `ShippingAddressHandling`. See [`onShippingAddressChanged`](/docs/yuno-sdk/controllers/on-shipping-address-changed).
      </Tab>

      <Tab title="Android">
        Android exposes `TransactionConfig` through **two constructors** — the same object, reached two ways. The constructor you call decides the flow, and the payment-only fields simply don't exist on the enrollment one. Passing both sessions, or neither, is a compile error: there is no constructor for that combination.

        **Payment** — `TransactionConfig(checkoutSession = …)`

        | Field | Type | Required | Default |
        | - | - | - | - |
        | [`checkoutSession`](#checkoutsession) | String | Yes | |
        | [`countryCode`](#countrycode) | String | Yes | |
        | [`controller`](#controller-ios-android) | TransactionController | Yes | |
        | [`language`](#language) | String? | No | Device language |
        | [`appearance`](#appearance-ios-android) | Appearance? | No | `null` |
        | [`autoContinuePayment`](#autocontinuepayment) | Bool | No | `true` |
        | [`showStatusScreen`](#showstatusscreen) | Bool | No | `false` |
        | [`onShippingAddressChanged`](/docs/yuno-sdk/controllers/on-shipping-address-changed) | (suspend (String, ShippingInfo) → ShippingUpdate?)? | No | `null` |

        **Enrollment** — `TransactionConfig(customerSession = …)`

        | Field | Type | Required | Default |
        | - | - | - | - |
        | [`customerSession`](#customersession) | String | Yes | |
        | [`countryCode`](#countrycode) | String | Yes | |
        | [`controller`](#controller-ios-android) | TransactionController | Yes | |
        | [`language`](#language) | String? | No | Device language |
        | [`appearance`](#appearance-ios-android) | Appearance? | No | `null` |
        | [`showStatusScreen`](#showstatusscreen) | Bool | No | `false` |

        `autoContinuePayment` and `onShippingAddressChanged` are payment-only — the enrollment constructor doesn't take them.
      </Tab>
    </Tabs>

    You must pass either `checkoutSession` or `customerSession`, but not both. See [Validation](#validation).

    ***

    ## `checkoutSession`

    Session ID for a payment flow. Pass the value returned by your backend after calling [`POST /v1/checkout/sessions`](https://docs.y.uno/reference/checkout-sessions/create-checkout-session).

    Mutually exclusive with `customerSession`.

    See [Sessions](/docs/basic-concepts/sessions) for more.

    ## `customerSession`

    Session ID for an enrollment flow. Pass the value returned by your backend after calling [`POST /v1/customers/sessions`](https://docs.y.uno/reference/customer-sessions-enrollment/create-customer-session).

    Mutually exclusive with `checkoutSession`.

    See [Sessions](/docs/basic-concepts/sessions) for more.

    ## `countryCode`

    ISO country code for the payment (for example, `US`, `CO`).

    On iOS and Android the SDK does not validate the value. On Web a payment `start()` that mounts a form or runs headless checks the value against the SDK's country list. A value outside that list makes `start()` reject with `countryCode=<value> is not valid`. An enrollment `start()` checks only that the value is a non-empty string. See [Country coverage](/docs/sdks/resources/country-coverage) for the list of supported countries.

    ## `language`

    ISO-639 language code. Falls back to the device or browser language if omitted.

    See [Supported languages](/docs/sdks/resources/languages-supported).

    ## `controller` (iOS, Android)

    Object that implements the `TransactionController` interface. Used to receive transaction events (`onStatus`, `showLoading`, `createPayment`).

    On iOS and Android, `controller` is **required**: `onStatus` is the only mechanism for receiving the transaction outcome, so a config without a controller would deliver every result nowhere. On iOS the SDK holds the reference weakly, so keep the instance alive for the duration of the transaction.

    On Web, controllers are wired directly as fields on the config (`onStatus`, `showLoading`, `createPayment`). On iOS and Android, you pass a single controller object through the `controller` field.

    See [Controllers](/docs/yuno-sdk/controllers/overview).

    ## `showStatusScreen`

    Flag that controls whether the SDK presents its built-in result screen after the transaction finishes.

    * `false` (default on iOS and Android). The SDK does not show a result screen. You receive the final status through `onStatus` and render your own UI.
    * `true` (default on Web). The SDK presents its result screen. On iOS the screen is not shown for `USER_CANCEL`.

    `onStatus` is always invoked, regardless of this flag.

    ## `autoContinuePayment`

    Controls whether the SDK automatically continues the payment flow after creating it. When `true` (default), the SDK handles 3DS and status polling internally. Set to `false` if you want to control the post-creation flow manually.

    On Web the flag applies only when you pass `createPayment`. Without a handler the SDK creates and continues the payment itself. PayPal ignores `false` and always continues, because its popup completes inside the SDK's continue step.

    On iOS the flag applies whether or not you override `createPayment`. With `false` and the default handler, the SDK creates the payment, closes its own views and stops.

    With `false`, the SDK stops once the payment is created: it does not poll status, does not run 3DS, and `onStatus` is not invoked for the transaction.

    ## `saveCardEnabled` (iOS)

    Flag that controls whether the card form offers the save-card checkbox on payments. Defaults to `false`.

    * `false` (default). The card form has no save-card checkbox.
    * `true`. The card form shows the checkbox, unchecked. If the user ticks it, the card is stored on a successful payment.

    Payment flows only. The enrollment initializer does not take it.

    On Web the flag lives inside the `card` object. See [`card`](#card-web-only).

    ## `elementSelector` (Web only)

    CSS selector, or the `HTMLElement` itself, for the node the SDK renders a form into. Required when `start({ paymentMethod })` mounts a payment form. Without it `start()` rejects with `elementSelector=undefined is not valid`. Optional for the enrollment form, which otherwise renders into a container the SDK appends to `<body>`. Headless flows and secure fields ignore it. Wallet and list views take their own `elementSelector` on `.mount()`.

    ## `showPayButton` (Web only)

    Whether the form the SDK mounts shows the SDK's own Pay button. Set it to `false` to use your own button: mount the form with `transaction.start({ paymentMethod })` and call [`transaction.submit()`](/docs/yuno-sdk/controllers/show-view#web-submit-from-your-own-button) when the user confirms.

    Payment flows only. Enrollment forms always show the SDK button.

    ## `onChange` (Web only)

    Callback the SDK calls with `{ form: { isValid } }` each time the validity of the mounted form changes. `isValid` is `true` when every required field, secure fields included, is valid.

    ## `card` (Web only)

    Options for the card form: `styles`, `type`, `saveCardEnabled`, `vaultOnSuccess`, `texts`, `documentEnable`, `isCreditCardProcessingOnly` and `fonts`, plus the callbacks `onChange`, `onGetInstallments` and `onInstallmentSelected`. See [Styling](/docs/yuno-sdk/features/styling) and [`onInstallmentSelected`](/docs/yuno-sdk/controllers/on-installment-selected).

    ## `texts` (Web only)

    Button label overrides: `customerForm.submitButton` and `paymentOtp.sendOtpButton`.

    ## `externalButtons` (Web only)

    Button options per wallet (`googlePay`, `applePay`, `samsungPay`, `paypal`, `paypalBraintree`, `revolutPay`) and the [`onShippingAddressChanged`](/docs/yuno-sdk/controllers/on-shipping-address-changed) callback. Each wallet view's `.mount()` accepts the same button options.

    ## `appearance` (iOS, Android)

    Visual customization object for the SDK's built-in views: font family and colors. Not available on Web.

    See [Styling](/docs/yuno-sdk/features/styling) for the full set of options.

    ## `viewController` (iOS only)

    Optional reference to the `UIViewController` that the SDK should use to present its UI.

    Optional when your app is fully built with SwiftUI. Required if you want the SDK to present from a specific UIKit view controller.

    When you pass `nil`, the SDK presents from the root view controller of the key window. If there is no window yet, for example when `start` runs before the scene is active, the transaction ends with `INTERNAL_ERROR`, `message.code` `NO_PRESENTATION_ANCHOR` and `message.context` `Transaction.start`. Pass `viewController`, or start after the window exists.

    This field exists only on iOS.

    ***

    ## Validation

    The config rejects both `checkoutSession` and `customerSession` being set, or neither. How each platform enforces it differs:

    | Platform | Enforcement |
    | - | - |
    | iOS | Compile-time. `TransactionConfig` has two non-throwing initializers (`init(checkoutSession:...)` and `init(customerSession:...)`), so a config with both or neither sessions cannot be constructed. No `try` is needed. |
    | Android | Compile-time. `TransactionConfig` has two constructors (`TransactionConfig(checkoutSession = …)` and `TransactionConfig(customerSession = …)`), so a config with both or neither session cannot be constructed. |
    | Web | Runtime. Throws a Yuno SDK error |

    On Web, the constructor also throws if `countryCode` is missing or if `createPayment` is set to anything other than a function. If `onStatus` is missing the constructor does not throw. It logs a console warning and the transaction result is never delivered.

    Beyond those checks, the SDK does not validate the *values* of `countryCode`, `language`, or other fields. Invalid values may surface later as backend errors or unexpected behavior. On Web, `start()` checks `countryCode` and `elementSelector` later. See [`countryCode`](#countrycode) and [`elementSelector`](#elementselector-web-only).
  </Tab>

  <Tab title="PaymentMethodSelected" id="payment-method-selected">
    `PaymentMethodSelected` is the object you pass to `Transaction.start()` to tell the SDK which payment method the user picked. You can build it from the result of [Payment Methods List](/docs/yuno-sdk/features/payment-methods-list) or from the payment methods service returned by Yuno's API.

    ## Fields

    <Tabs>
      <Tab title="Web">
        | Field | Type | Required |
        | - | - | - |
        | [`type`](#paymentmethodtype) | String | Yes |
        | [`vaultedToken`](#vaultedtoken) | String? | No |
        | [`data`](#transactiondata) | TransactionData | No (`start()` only) |

        The object the payment methods list hands to `onPaymentSelected` carries `type`, `vaultedToken`, an optional display `name` and `selectionSource` (`'auto'` when the SDK preselected the method, `'user'` when the shopper picked it). It never carries `data`. You can pass it to `start()` as it is.
      </Tab>

      <Tab title="iOS">
        | Field | Type | Required |
        | - | - | - |
        | [`paymentMethodType`](#paymentmethodtype) | String | Yes |
        | [`vaultedToken`](#vaultedtoken) | String? | No |
        | [`transactionData`](#transactiondata) | TransactionData | No |

        The object the payment methods list hands to `onPaymentSelected` also carries `selectionSource` (`.auto` when the SDK preselected the method, `.user` when the shopper picked it). It is read-only: an object you build yourself has it as `nil`.

        `Transaction.start` ignores a second call while a transaction is in flight, so a double tap does not start two transactions.
      </Tab>

      <Tab title="Android">
        | Field | Type | Required |
        | - | - | - |
        | [`paymentMethodType`](#paymentmethodtype) | String | Yes |
        | [`vaultedToken`](#vaultedtoken) | String? | No |
        | [`transactionData`](#transactiondata) | TransactionData | No |
      </Tab>
    </Tabs>

    Only `paymentMethodType` / `type` is required. On iOS and Android the SDK does not validate this object.

    On Web `start()` validates it. For a payment, `type` must be a non-empty string. For a headless enrollment that passes `data`, `type` is required too. With secure fields mounted, `data.card` must not contain `number`, `securityCode`, `expirationMonth` or `expirationYear`. In manual mode, a form `start()` rejects express wallet types such as `GOOGLE_PAY` and `APPLE_PAY`, because their buttons mount through `getPaymentMethodsViews()`. Beyond that the SDK does not check the values.

    ***

    ## `paymentMethodType`

    String identifying the type of payment method (for example, `CARD`, `GOOGLE_PAY`, `APPLE_PAY`).

    The list of valid values is not fixed. Yuno may add new payment method types over time. Use the value returned by Yuno's API or by the [Payment Methods List](/docs/yuno-sdk/features/payment-methods-list) controller.

    ## `vaultedToken`

    Token of a previously saved payment method, returned by Yuno when the customer enrolled the method or when a previous payment was made with `vault_on_success: true`.

    Use this when the customer is paying with a saved method instead of entering data again.

    ## `transactionData`

    Pre-collected payment data. When provided, the SDK skips its built-in forms and tokenizes directly.

    On Web two cases keep the form. With secure fields mounted, `data` only supplements the card the iframes collect (`card.holderName`, `card.type`, `installment`, `customer` and `vaultOnSuccess`). When the payment methods list has an inline form mounted for the selected method, `start()` with `data` throws. Call `start({ paymentMethod })` without `data` to submit that form.

    See [TransactionData](/docs/yuno-sdk/reference/objects-you-pass#transaction-data) for the shape of this object.
  </Tab>

  <Tab title="TransactionData" id="transaction-data">
    `TransactionData` is the object you pass inside [`PaymentMethodSelected`](/docs/yuno-sdk/reference/objects-you-pass#payment-method-selected) when you've already collected the payment data on your side. When provided, the SDK skips its built-in forms and tokenizes directly with the values you supply.

    `TransactionData` is the union of several nested objects, each covering a different aspect of the payment (card data, installments, 3DS setup, customer data, etc.). You only fill the parts that apply to your scenario. Every nested object is optional unless required by the specific payment method or feature you're using.

    ## Shape

    The full shape of `TransactionData` is the following. This JSON is illustrative, on each platform you build an object (JavaScript on Web, Swift on iOS, Kotlin on Android) that produces this structure. All field names are camelCase in the SDK. Every field is optional, fill only what applies to your scenario.

    ```json theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    {
      "card": {
        "number": "4111111111111111",
        "expirationMonth": 12,
        "expirationYear": 28,
        "securityCode": "123",
        "holderName": "John Doe",
        "brand": "VISA",
        "type": "CREDIT"
      },
      "vaultOnSuccess": true,
      "installment": {
        "id": "installment_xxx",
        "value": 3
      },
      "threeDSecure": {
        "setupId": "setup_xxx"
      },
      "customer": {
        "firstName": "John",
        "lastName": "Doe",
        "email": "john.doe@example.com",
        "document": {
          "documentNumber": "1090209924",
          "documentType": "CC"
        },
        "phone": {
          "countryCode": "57",
          "number": "3001234567"
        },
        "merchantCustomerId": "customer_xxx",
        "billingAddress": {
          "addressLine1": "Calle 34 # 56 - 78",
          "addressLine2": "Apartamento 502, Torre I",
          "city": "Bogotá",
          "country": "CO",
          "state": "Cundinamarca",
          "zipCode": "111111",
          "neighborhood": "Chapinero"
        },
        "shippingAddress": {
          "addressLine1": "Calle 34 # 56 - 78",
          "addressLine2": "Apartamento 502, Torre I",
          "city": "Bogotá",
          "country": "CO",
          "state": "Cundinamarca",
          "zipCode": "111111"
        }
      },
      "bankTransfer": {
        "bankAccount": "1234567890",
        "routingNumber": "021000021",
        "beneficiaryName": "John Doe"
      },
      "issuerId": "issuer_xxx",
      "otp": "123456",
      "ticket": {
        "benefitType": "FOOD"
      },
      "wallet": {
        "cardData": {
          "type": "CREDIT"
        }
      }
    }
    ```

    `type` and `vaultedToken` are not part of `TransactionData`; they live on [`PaymentMethodSelected`](/docs/yuno-sdk/reference/objects-you-pass#payment-method-selected).

    On Web and iOS, `bankTransfer` also takes `accountType` and `accountHolderType`. On Web, `TransactionData` also accepts a top-level `additionalData` object. Each key of `additionalData` names the object its extra fields belong to, for example `card`. The SDK folds each entry into that object before sending, so there is no `additional_data` key on the wire. `card.type` is `CREDIT` or `DEBIT`, and `card.brand` is optional.

    On iOS the shape differs in four places. There is no `otp`. `bankTransfer` names the account fields `accountNumber` and `routingId`. `wallet` carries the fields of a wallet checkout you ran yourself, not `cardData`. And `customer` sends only part of what it accepts. See [iOS types](#ios-types).

    With secure fields mounted, the SDK reads only `card.holderName`, `card.type`, `vaultOnSuccess`, `installment` and `customer` from `data`. The other objects apply to headless `start()` only.

    <Warning>
      `card.expirationYear` is the **two-digit** year: `28` means 2028. The SDK passes `TransactionData` through verbatim: it does not normalize a four-digit year, so `2028` reaches the backend as-is and is not a valid value.
    </Warning>

    ## Top-level objects

    | Field | Description |
    | - | - |
    | `issuerId` | Identifier of the issuer for the payment method, when applicable. |
    | `vaultOnSuccess` | When `true`, saves the payment method for the customer if the payment succeeds. |
    | `card` | Card data (number, expiration, security code, holder, brand, type). `expirationYear` is two-digit (`28` for 2028). |
    | `installment` | Installment plan and value. |
    | `threeDSecure` | 3DS setup identifier when 3DS is configured separately. |
    | `bankTransfer` | Bank transfer details (beneficiary, account, routing). |
    | `wallet` | Wallet data. On Web, wallet-specific card data (e.g., card type). On iOS, the result of a wallet checkout you ran outside the SDK. |
    | `ticket` | Ticket-based payment data (e.g., benefit type for food/meal vouchers). |
    | `otp` | One-time password, when the payment method requires it. Not available on iOS. |
    | `customer` | Customer information (name, email, document, phone, billing and shipping addresses). |

    ## iOS types

    On iOS you build `SdkPayments.TransactionData` from these structs. Every argument of `TransactionData` has a default, so pass only the parts you have. Arguments are listed in declaration order.

    | Field | Type | Initializer |
    | - | - | - |
    | `issuerId` | `String?` | |
    | `vaultOnSuccess` | `Bool`, default `false` | |
    | `card` | `CardTransactionData` | `(number:securityCode:expirationMonth:expirationYear:holderName:brand:type:)`. `number`, `securityCode` and `holderName` are `String`; `expirationMonth` and `expirationYear` are `Int`; `brand` is `String?`; `type` is `CardTransactionData.CardType?`, `.credit` or `.debit`. |
    | `installment` | `InstallmentTransactionData` | `(id: String, value: Int)` |
    | `threeDSecure` | `ThreeDSecureTransactionData` | `(setupId: String)` |
    | `bankTransfer` | `BankTransferTransactionData` | `(beneficiaryName:accountNumber:routingId:accountType:accountHolderType:)`, all `String?`. |
    | `wallet` | `WalletTransactionData` | `(accountIntegrationCode:integrationType:checkoutResponse:thirdPartyToken:flowID:merchantTransactionID:)`, all `String?`. |
    | `ticket` | `TicketTransactionData` | `(benefitType: String?)` |
    | `customer` | `Customer` | Every argument is optional. `gender` is a `Customer.Gender` (`.male`, `.female`, `.noBinary`). `document` is a `Customer.Document(documentNumber:documentType:)`, `phone` a `Customer.Phone(countryCode:number:)`, and `billingAddress` and `shippingAddress` a `Customer.Address(addressLine1:addressLine2:city:country:state:zipCode:neighborhood:)`, where every argument but `neighborhood` is a required `String`. |

    The token carries these `customer` fields: `firstName`, `lastName`, `email`, `gender`, `document`, `phone`, `billingAddress` and `shippingAddress`. The initializer also accepts `id`, `merchantCustomerId`, `dateOfBirth`, `nationality`, `country` and `neighborhood`, but the SDK does not send them.
  </Tab>
</Tabs>

## Related

* [Objects you receive](/docs/yuno-sdk/reference/objects-you-receive). What the SDK hands back: `Status` and `OneTimeToken`.
* [Controllers overview](/docs/yuno-sdk/controllers/overview). The callbacks you pass inside `TransactionConfig`.
* [Get Started](/docs/yuno-sdk/get-started). The unified-API walkthrough.


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