Android SDK

Install

build.gradle (Project level):

repositories {
    maven { url = uri("https://yunopayments.jfrog.io/artifactory/snapshots-libs-release") }
}

build.gradle (App level):

dependencies {
    implementation("com.yuno.payments:android-sdk:{last_version}")
}
📘

Requirements

Android 5.0 (API 21)+, Kotlin 1.4.0+, Java 8, AndroidX, android-gradle-plugin 4.0.0+, Proguard 6.2.2+

Initialize

In Application class:

import com.yuno.sdk.Yuno
import com.yuno.sdk.YunoConfig
import android.app.Application

class CustomApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        Yuno.initialize(
            this,
            "your-public-api-key",
            YunoConfig()
        )
    }
}

AndroidManifest.xml:

<application
    android:name=".CustomApplication"
    ...>
</application>

YunoConfig Options

data class YunoConfig(
    val cardFlow: CardFormType = CardFormType.ONE_STEP,
    val saveCardEnabled: Boolean = false,
    val keepLoader: Boolean = false,
    val cardFormDeployed: Boolean = false,
    val language: YunoLanguage? = null,
    val isDynamicViewEnabled: Boolean = false
)
ParameterTypeDefaultDescription
cardFlowCardFormTypeONE_STEPCard form type: ONE_STEP or STEP_BY_STEP
saveCardEnabledBooleanfalseShow save card checkbox in card flows
keepLoaderBooleanfalseKeep Yuno loading screen until payment is created
cardFormDeployedBooleanfalseShow card form deployed in payment methods list (Full SDK only)
languageYunoLanguage?nullSDK language (null uses device language)
isDynamicViewEnabledBooleanfalseEnable dynamic view

Available Languages:

enum class YunoLanguage {
    SPANISH,
    ENGLISH,
    PORTUGUESE,
    INDONESIAN,
    MALAYSIAN
}

Basic Payment Flow

Full SDK Version

import androidx.appcompat.app.AppCompatActivity
import com.yuno.sdk.payments.startCheckout
import com.yuno.sdk.payments.startPayment
import com.yuno.sdk.payments.continuePayment
import com.yuno.sdk.payments.updateCheckoutSession

class PaymentActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_payment)
        
        // Step 1: Initialize checkout in onCreate
        startCheckout(
            callbackPaymentState = ::onPaymentStateChange
        )
        
        setupPaymentMethodsView()
    }
    
    private fun setupPaymentMethodsView() {
        // Step 2: Update checkout session with your session ID and country
        updateCheckoutSession(
            checkoutSession = "your_checkout_session_id",
            countryCode = "CO"
        )
        
        // Step 3: Display payment methods using Compose view
        val composeView = findViewById<ComposeView>(R.id.paymentMethodsContainer)
        composeView.setContent {
            PaymentMethodListViewComponent(
                activity = this@PaymentActivity,
                onPaymentSelected = { isSelected ->
                    findViewById<Button>(R.id.payButton).isEnabled = isSelected
                }
            )
        }
    }
    
    private fun processPayment() {
        // Step 4: Start payment when user clicks pay button
        startPayment(
            callbackOTT = ::onTokenReceived
        )
    }
    
    private fun onTokenReceived(token: String?) {
        token?.let {
            // Step 5: Send token to your backend to create payment
            createPaymentOnBackend(it)
        }
    }
    
    private fun createPaymentOnBackend(token: String) {
        // Call your backend API to create payment with the token
        // If response has sdk_action_required = true, call continuePayment()
    }
    
    private fun handleSdkActionRequired() {
        // Step 6: Continue payment if sdk_action_required is true
        continuePayment(
            callbackPaymentState = ::onPaymentStateChange
        )
    }
    
    private fun onPaymentStateChange(state: String?) {
        when (state) {
            "SUCCEEDED" -> {
                // Payment successful
                navigateToSuccess()
            }
            "FAIL" -> {
                // Payment failed
                showError("Payment failed")
            }
            "PROCESSING" -> {
                // Payment is being processed
                showPendingMessage()
            }
            "REJECT" -> {
                // Payment was rejected
                showError("Payment rejected")
            }
            "INTERNAL_ERROR" -> {
                // Internal error occurred
                showError("An error occurred")
            }
            "CANCELED" -> {
                // User canceled
                Toast.makeText(this, "Payment canceled", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

Layout XML for Payment Methods:

<com.yuno.payments.features.payment.ui.views.PaymentMethodListView
    android:id="@+id/list_payment_methods"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Or use ComposeView for Jetpack Compose integration:

<androidx.compose.ui.platform.ComposeView
    android:id="@+id/paymentMethodsContainer"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Lite SDK Version

For custom payment method selection, use the Lite version:

import com.yuno.sdk.payments.startCheckout
import com.yuno.sdk.payments.startPaymentLite
import com.yuno.sdk.payments.continuePayment
import com.yuno.sdk.payments.updateCheckoutSession
import com.yuno.presentation.core.components.PaymentSelected

class CheckoutLiteActivity : AppCompatActivity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_checkout_lite)
        
        // Initialize checkout
        startCheckout(
            checkoutSession = "your_checkout_session_id",
            countryCode = "CO",
            callbackPaymentState = ::onPaymentStateChange
        )
    }
    
    private fun processPayment(paymentMethodType: String, vaultedToken: String?) {
        // Start payment with selected payment method
        startPaymentLite(
            paymentSelected = PaymentSelected(
                paymentMethodType = paymentMethodType,
                vaultedToken = vaultedToken
            ),
            callBackTokenWithInformation = { ottModel ->
                // Optional: Receive additional token information
                Log.i("OTT Info", ottModel.toString())
            },
            callbackOTT = ::onTokenReceived
        )
    }
    
    private fun onTokenReceived(token: String?) {
        token?.let {
            // Send token to your backend
            createPaymentOnBackend(it)
        }
    }
    
    private fun onPaymentStateChange(state: String?) {
        // Handle payment state changes
    }
}

Payment States

The SDK returns these payment states via callbackPaymentState:

const val PAYMENT_STATE_SUCCEEDED = "SUCCEEDED"
const val PAYMENT_STATE_FAIL = "FAIL"
const val PAYMENT_STATE_PROCESSING = "PROCESSING"
const val PAYMENT_STATE_REJECT = "REJECT"
const val PAYMENT_STATE_INTERNAL_ERROR = "INTERNAL_ERROR"
const val PAYMENT_STATE_CANCELED = "CANCELED"

3DS Authentication

3DS is handled automatically by the SDK. Call continuePayment() after creating payment if sdk_action_required is true in the response:

private fun onTokenReceived(token: String?) {
    token?.let {
        lifecycleScope.launch {
            val response = createPaymentOnBackend(it)
            
            if (response.sdkActionRequired) {
                continuePayment(
                    callbackPaymentState = ::onPaymentStateChange
                )
            }
        }
    }
}

Configuration Options

Essential Parameters

ParameterTypeDescription
checkoutSessionStringSession ID from your backend
countryCodeStringISO country code (e.g., "CO", "US")
callbackPaymentState(String?) -> UnitPayment state callback
callbackOTT(String?) -> UnitOne-time token callback

Optional Parameters

ParameterTypeDefaultDescription
showPaymentStatusBooleantrueShow Yuno's payment status screens
merchantSessionIdString?nullAnti-fraud session ID

Proguard Rules

proguard-rules.pro:

# Yuno SDK
-keep class com.yuno.sdk.** { *; }
-keep interface com.yuno.sdk.** { *; }
-dontwarn com.yuno.sdk.**

# OkHttp & Retrofit
-dontwarn okhttp3.**
-dontwarn retrofit2.**

Next Steps

Ready to explore more advanced features? Check out the Advanced Features guide for:

  • Lite SDK Flow - Custom payment method selection with startPaymentLite()
  • Enrollment (Save Cards) - Save payment methods for future use
  • Vaulted Token Payments - One-click payments with saved cards
  • Keep Loader Flow - Unified payment flow with startCompletePaymentFlow()
  • Custom Card Form - Build custom card forms with Yuno Secure Fields
  • Styling - Customize SDK appearance

See also: