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

# Get Started

> Accept your first payment in sandbox, where no real money moves.

Four steps: install the SDK, show your shopper their payment methods, take
the payment, and know it went through. Yuno handles the forms, the routing,
and 3DS in between.

<Steps>
  <Step title="Install">
    Add the SDK to your platform and initialize it with your public API key.
  </Step>

  <Step title="Show payment methods">
    Your backend creates a checkout session; the SDK shows the methods.
  </Step>

  <Step title="Take the payment">
    Start the transaction. Yuno renders the form and runs 3DS.
  </Step>

  <Step title="Know it went through">
    The SDK tells you the outcome; your server confirms it.
  </Step>
</Steps>

## Before you begin

You need:

* A Yuno account and your **public API key**, available in the [Yuno Dashboard](https://dashboard.y.uno/) under **Developers** > **Credentials**.
* A backend that can call Yuno's API to create checkout sessions and, optionally, payments.

## Install

Add the SDK for your platform, then initialize it once, at app or page
startup. The constructor only takes your public API key. All
payment-specific configuration comes later.

<Tabs>
  <Tab title="Web">
    Load the SDK from the CDN. It exposes a global `SdkPayments` and dispatches a `sdk-payments-ready` event on `window` once it's ready to use.

    ```html theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    <script src="https://sdk-web.y.uno/v2.0.0/main.js"></script>
    ```

    Each release has its own full-version path. To move to a newer release, change the version in the `src`.

    Then initialize the SDK. The bundle sets `window.SdkPayments` synchronously and fires `sdk-payments-ready` on `window` **once**, right as it loads. If your code runs after the script has already loaded, that event has passed — so check for the global first and fall back to the event only while the script is still loading:

    ```javascript theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    async function startYuno() {
        const sdkPayments = await SdkPayments.initialize('your-public-api-key');
        // Build a transaction from here (see "Take the payment").
    }

    if (window.SdkPayments) {
        startYuno();
    } else {
        window.addEventListener('sdk-payments-ready', startYuno);
    }
    ```

    This works whichever way you load the script — synchronous, `async`, or `defer`. `SdkPayments.initialize` returns a Promise; `await` it before using the SDK.
  </Tab>

  <Tab title="iOS">
    **Swift Package Manager**

    ```swift theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    dependencies: [
        .package(url: "https://github.com/yuno-payments/yuno-sdk-ios", from: "3.0.0")
    ]
    ```

    **CocoaPods**

    ```ruby theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    pod 'SdkPayments', '~> 3.0'
    ```

    Then initialize in your `AppDelegate` or `App` struct, depending on your app's entry point:

    ```swift theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    import SdkPayments

    SdkPayments.initialize(apiKey: "your-public-api-key")
    ```

    <Note>
      An `async` version of `initialize(apiKey:)` is also available for async contexts.
    </Note>
  </Tab>

  <Tab title="Android">
    **build.gradle**

    ```groovy theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    repositories {
        maven { url "https://yunopayments.jfrog.io/artifactory/snapshots-libs-release" }
    }

    dependencies {
        implementation 'com.yuno.payments:android-sdk:3.0.0'
    }
    ```

    Then initialize from your `Application` class so the SDK is ready before any activity uses it:

    ```kotlin theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    import com.yuno.payments.sdk.api.SdkPayments

    class MyApplication : Application() {
        override fun onCreate() {
            super.onCreate()
            SdkPayments.initialize(this, apiKey = "your-public-api-key")
        }
    }
    ```
  </Tab>
</Tabs>

<Note>
  The SDK targets the environment from your API key's prefix: `sandbox_` keys use sandbox, `prod_` keys use production.
</Note>

## Show payment methods

Ask Yuno which methods this shopper can use, and put them on screen. Your
backend first creates a **checkout session** (the payment's identity) and
hands it to your app.

### Create the checkout session (backend)

A checkout session is Yuno's record of this one payment: your server asks
Yuno for it and hands the ID to your app.

* **Endpoint**: `POST /v1/checkout/sessions`
* **Auth**: `public-api-key` and `private-secret-key` headers (from the [Dashboard](https://dashboard.y.uno/) under **Developers** > **Credentials**)
* **Required**: `account_id`, `merchant_order_id`, `payment_description`, `country`
* **Optional**: `customer_id` (gives the session access to that customer's enrolled methods), `amount`, `workflow`
* **Returns**: `checkout_session` (the value you pass as `checkoutSession`)
* **Reference**: [`POST /v1/checkout/sessions`](https://docs.y.uno/reference/checkout-sessions/create-checkout-session), with full request/response and auth details

```http theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
POST https://api-sandbox.y.uno/v1/checkout/sessions
public-api-key: <your-public-api-key>
private-secret-key: <your-private-secret-key>

{
  "account_id": "your-account-id",
  "merchant_order_id": "order-123",
  "payment_description": "Order 123",
  "country": "US",
  "customer_id": "customer-123",
  "amount": { "currency": "USD", "value": 2500 },
  "workflow": "SDK_SEAMLESS"
}
```

<Warning>
  Create the session with `workflow: "SDK_SEAMLESS"`, a field on the session-create body above, **not** on `TransactionConfig`. It is what lets the SDK create the payment for you. Without it, the transaction ends in `INTERNAL_ERROR`. See the [`workflow` field](https://docs.y.uno/reference/checkout-sessions/create-checkout-session#body-workflow).
</Warning>

### Put the methods on screen

The shopper's choice reaches the SDK as a [`PaymentMethodSelected`](/docs/yuno-sdk/reference/objects-you-pass#payment-method-selected): only `paymentMethodType` (`type` on Web) is required; `vaultedToken` and `transactionData` (`data` on Web) are optional. Two ways to get it:

* **Use the SDK's pre-built methods list.** Call `getPaymentMethodsViews` to render a list of methods. When the user picks one, your `onPaymentSelected` controller receives a `PaymentMethodSelected` you can pass to `start()`. See [Payment Methods List](/docs/yuno-sdk/features/payment-methods-list).
* **Build your own list.** Fetch the available payment methods from Yuno's API and construct `PaymentMethodSelected` yourself based on the user's choice. See [`GET /v1/checkout/sessions/{checkout_session}/payment-methods`](https://docs.y.uno/reference/checkout-sessions/retrieve-payment-methods-for-checkout#retrieve-payment-methods-for-checkout).

## Take the payment

When the shopper confirms, start the payment. Yuno renders the method's
form, runs 3DS if the bank asks for it, and creates the payment. A complete
transaction has three pieces:

1. A **checkout session** created by your backend.
2. A `TransactionConfig` with the session, country, language, and controllers.
3. A `Transaction` that you start with a `PaymentMethodSelected`.

Controllers are how your code receives the SDK's events. At minimum `onStatus`, which delivers the final result of the transaction. Provide them through a `TransactionController` object passed in the config.

<Tabs>
  <Tab title="Web">
    `TransactionConfig` on web is a plain object. Pass it directly to `sdkPayments.transaction(...)`.

    ```typescript theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    // Create the checkout session on your backend, then pass it here.
    const transaction = sdkPayments.transaction({
        checkoutSession: 'session-from-backend',
        countryCode: 'US',
        language: 'en', // optional, falls back to browser language
        // elementSelector: the DOM element the form renders into (form payments only).
        elementSelector: '#payment-form',
        onStatus: (result) => {
            console.log('Final status:', result.status)
        },
    })

    // Tell the SDK which method to use ("CARD", "PIX", ...).
    // See "Put the methods on screen" above.
    const paymentMethod = { type: 'CARD' }

    await transaction.start({ paymentMethod })
    ```

    On Web, `start()` without `data` mounts the method's form into `elementSelector` and resolves once the form is on the page. The form has its own Pay button. The shopper taps it, and the result arrives later in `onStatus`. To use your own button, pass `showPayButton: false` in the config and call `transaction.submit()` from it. To pay with details you collected yourself, pass `data` on `paymentMethod`, and the SDK runs the payment with no form.
  </Tab>

  <Tab title="iOS">
    On iOS, controllers are provided through a `TransactionController` object passed in the config. The example below uses a standalone class so it works the same in SwiftUI and UIKit. Hold a `Checkout` instance wherever fits your app (a `@State` in a `View`, a property in a `UIViewController`, or any other owner) and call `start(...)` from your payment button.

    ```swift theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    import SdkPayments

    final class Checkout: SdkPayments.TransactionController {

        func start() {
            // Tell the SDK which method to use ("CARD", "PIX", ...).
            // See "Put the methods on screen" above.
            let paymentSelected = SdkPayments.PaymentMethodSelected(paymentMethodType: "CARD")

            // Create the checkout session on your backend, then pass it here.
            let config = SdkPayments.TransactionConfig(
                checkoutSession: "session-from-backend",
                countryCode: "US",
                language: "en",          // optional, falls back to device language
                controller: self
            )

            SdkPayments.Transaction(config: config)
                .start(paymentSelected: paymentSelected)
        }

        func onStatus(status: SdkPayments.TransactionStatus) {
            print("Final status: \(status.status)")
        }
    }
    ```
  </Tab>

  <Tab title="Android">
    On Android, controllers are provided through a `TransactionController` object passed in the config.

    ```kotlin theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
    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 onStatus(status: TransactionStatus) {
            println("Final status: ${status.status}")
        }

        private fun startCheckout() {
            // Tell the SDK which method to use ("CARD", "PIX", ...).
            // See "Put the methods on screen" above.
            val paymentSelected = PaymentMethodSelected(paymentMethodType = "CARD")

            // Create the checkout session on your backend, then pass it here.
            val config = TransactionConfig(
                checkoutSession = "session-from-backend",
                countryCode = "US",
                language = "en",          // optional, falls back to device language

                controller = this
            )

            Transaction(config)
                .start(activity = this, paymentSelected = paymentSelected)
        }
    }
    ```
  </Tab>
</Tabs>

### `TransactionConfig` fields used here

| Field | Required | Purpose |
| - | - | - |
| `checkoutSession` | Yes | Session ID returned by your backend. |
| `countryCode` | Yes | ISO-3166 alpha-2 country code (e.g. `US`, `CO`). |
| `language` | No | ISO-639 code (e.g. `en`, `es`). Falls back to the device or browser language. |
| `controller` | Yes (mobile only) | Object implementing `TransactionController`. Not present on Web, where events are wired inline on the config. |
| `elementSelector` | Yes (Web, form payments) | CSS selector or `HTMLElement` the form renders into. Optional for enrollment, where the SDK appends its own container. Ignored when you pass `data`. |

For the full list of fields, see [`TransactionConfig`](/docs/yuno-sdk/reference/objects-you-pass#transaction-config).

## Know it went through

The SDK presents the form, tokenizes the input, creates the payment, handles 3DS if required, and emits the final status to `onStatus`. Use it to show the shopper the receipt. On Web the SDK shows its own result screen by default. To draw the receipt yourself, pass `showStatusScreen: false` in the transaction config.

<Note>
  `onStatus` drives your UI. For fulfillment (shipping goods, granting access), confirm the outcome server-side via webhooks or the payments API; see [Confirm on your server](/docs/yuno-sdk/controllers/on-status#confirm-on-your-server).
</Note>

### Creating the payment yourself (optional)

By default, the SDK creates the payment for you. You don't need this endpoint.

If you override `createPayment` to take control of payment creation, your backend calls this endpoint with the One-Time Token delivered by the SDK.

* **Endpoint**: `POST /v1/payments`
* **Required**: One-Time Token, checkout session, `account_id`, `merchant_order_id`, `description`, `country`, and `amount` (`value` + `currency`)
* **Reference**: [`POST /v1/payments`](https://docs.y.uno/reference/payments/create-payment)

```http theme={"theme":{"light":"github-dark","dark":"github-dark-dimmed"}}
POST https://api-sandbox.y.uno/v1/payments
public-api-key: <your-public-api-key>
private-secret-key: <your-private-secret-key>

{
  "account_id": "your-account-id",
  "merchant_order_id": "order-123",
  "description": "Order 123",
  "country": "US",
  "amount": { "currency": "USD", "value": 2500 },
  "payment_method": { "token": "one-time-token-from-sdk" },
  "checkout": { "session": "checkout-session-id" }
}
```

See [`createPayment`](/docs/yuno-sdk/controllers/create-payment) for the override flow.

## Test cards

<Warning>
  Test cards are **provider-specific**. The cards below only work when your sandbox routes card payments to the [Yuno Test Payment Gateway](/docs/direct-integration-use-cases/yuno-testing-gateway). If your routing points to another provider (Adyen, Stripe, etc.), these cards are declined, often without an error message. In that case, use that provider's own test cards instead.
</Warning>

Use these in sandbox to exercise different scenarios. Enter the full tuple exactly as listed:

| Card number | Expiry | CVV | Cardholder | Result |
| - | - | - | - | - |
| 4507 9900 0000 0002 | 11/28 | 123 | John Doe | SUCCEEDED |
| 4507 9900 0000 0028 | 11/28 | 123 | John Doe | DECLINED\_BY\_BANK |
| 4507 9900 0000 0010 | 11/28 | 123 | John Doe | INSUFFICIENT\_FUNDS |

For the full list of cards and scenarios (Mastercard, Amex, more decline codes), see [Card detail](/docs/direct-integration-use-cases/yuno-testing-gateway#test-card-payments-with-yuno-testing-gateway). For 3DS flows, use the [3DS test cards](/docs/direct-integration-use-cases/yuno-testing-gateway#test-card-payments-with-yuno-testing-gateway).

## Next steps

* [Configuration](/docs/yuno-sdk/reference/objects-you-pass#transaction-config). Full reference for `TransactionConfig`. See also [`PaymentMethodSelected`](/docs/yuno-sdk/reference/objects-you-pass#payment-method-selected) and [`TransactionData`](/docs/yuno-sdk/reference/objects-you-pass#transaction-data).
* [Controllers](/docs/yuno-sdk/controllers/overview). Override `showLoading`, or `createPayment` to customize rendering, loading, or payment creation.
* [Guides](/docs/yuno-sdk/features/payment-methods-list). Payment Methods List, Enrollment, Styling, and more.


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