Recursos avançados do Android SDK
Configuração avançada e integrações personalizadas para Android.
Opções alternativas de montagem
O fluxo básico utiliza a exibição automática do método de pagamento. Para maior controle, utilize estas alternativas:
Seleção de método de pagamento personalizado (startPaymentLite)
startPaymentLite)Controle qual método de pagamento exibir:
// 1. Fetch available methods
val methods = fetchPaymentMethods(sessionId)
// 2. Display in your UI
// 3. Start payment with selected method
startPaymentLite(
paymentMethodType = selectedMethod, // "CARD", "PIX", etc.
vaultedToken = null,
showPaymentStatus = true,
callbackOTT = { token ->
token?.let { createPayment(it, checkoutSession) }
}
)Fluxo simplificado (startPaymentSeamlessLite)
startPaymentSeamlessLite)Semelhante ao Lite, mas com criação automática de pagamentos:
startPaymentSeamlessLite(
paymentMethodType "CARD",
vaultedToken null,
showPaymentStatus true
)Inscrição (Salvar cartões)
Salvar durante o pagamento
// When creating payment on backend, include vault_on_success flag
suspend fun createPayment(token: String, checkoutSession: String) {
apiClient.post("/payment/create", mapOf(
"one_time_token" to token,
"checkout_session" to checkoutSession,
"vault_on_success" to true // Save after successful payment
))
}
// Configure SDK to show save checkbox
startCheckout(
callbackPaymentState = { state -> handlePaymentState(state) }
)
// Update with session - SDK will show "Save card" checkbox automatically
updateCheckoutSession(
checkoutSession = session.checkoutSession,
countryCode = "US"
)Inscrição separada
// Create customer session on backend
val customerSession = createCustomerSession("cus_123")
// Start enrollment
initEnrollment(
customerSession = customerSession.id,
countryCode = "US"
)
// Start enrollment flow
startEnrollment(
showEnrollmentStatus = true,
callback = { vaultedToken ->
vaultedToken?.let {
println("Card saved: $it")
}
}
)Token armazenados
startPaymentLite(
paymentMethodType "CARD",
vaultedToken "vtok_saved_card_123",
showPaymentStatus true,
callbackOTT { token >
token?.let { createPayment(it, checkoutSession) }
}
)IU personalizada (integração sem interface gráfica)
Crie formulários de pagamento totalmente personalizados com controle total da interface do usuário quando precisar de controle total sobre todos os elementos da interface, experiências de checkout altamente personalizadas ou tiver recursos de desenvolvimento para uma interface personalizada.
import com.yuno.sdk.Yuno
import com.yuno.sdk.api.ApiClientPayment
lifecycleScope.launch {
// 1. Initialize
val apiClient = Yuno.apiClientPayment(
countryCode "US",
checkoutSession "session_id"
)
// 2. Colete os dados do cartão em sua interface de usuário personalizada
val token apiClient.generateToken(
checkoutSession "session_id",
paymentMethod = PaymentMethod(
type = "CARD",
card = CardData(
number = "4111111111111111",
expirationMonth = 12,
expirationYear = 25,
securityCode = "123",
holderName = "John Doe",
type = "CREDIT"
)
)
)
// 3. Crie o pagamento com token
createPayment(token.oneTimeToken)
// 4. Lidar com a continuação, se necessário
apiClient.continuePayment(
activity = this@PaymentActivity,
onPaymentResult = { result ->
handlePaymentResult(result)
}
)
}Com Token Vaulted Token
val token apiClient.generateToken(
checkoutSession "session_id",
paymentMethod = PaymentMethod(
type = "CARD",
vaultedToken "saved_token_id",
card = CardData(securityCode = "123")
)
)Integração do modo de renderização
Exiba o formulário de pagamento em sua visualização personalizada.
class PaymentActivity : ComponentActivity(), YunoPaymentRenderListener {
private lateinit var paymentController: YunoPaymentFragmentController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
var paymentView by remember { mutableStateOf<View?>(null) }
Column {
Button(onClick = { startRenderMode() }) {
Text("Pay Now")
}
paymentView?.let {
AndroidView(factory = { it })
}
}
}
}
private fun startRenderMode() {
lifecycleScope.launch {
val session = createCheckoutSession()
paymentController = Yuno.startPaymentRender(
activity = this@PaymentActivity,
checkoutSession = session.id,
countryCode = "US",
listener = this@PaymentActivity
)
}
}
override fun onFormView(view: View) {
// Add view to your layout
findViewById<FrameLayout>(R.id.payment_container).addView(view)
}
override fun onSubmitForm() {
// Customer submitted form
}
override fun onPaymentResult(result: PaymentResult) {
if (result.status == PaymentStatus.SUCCEEDED) {
navigateToSuccess()
}
}
}Estilo
Personalize a aparência do SDK com temas.
cores.xml:
<color name="yuno_primary">#007bff</color>
<color name="yuno_background">#ffffff</color>
<color name="yuno_text">#333333</color>
<color name="yuno_error">#dc3545</color>temas.xml:
<style name="YunoSDKTheme" parent="Theme.MaterialComponents">
<item name="colorPrimary">@color/yuno_primary</item>
<item name="colorOnPrimary">@android:color/white</item>
<item name="android:textColor">@color/yuno_text</item>
</style>Aplicar tema:
Yuno.definirTema(R.estilo.TemaYunoSDK)Digitalização de cartões (OCR)
Ative a leitura de cartões com a câmera.
Adicionar dependência:
dependencies {
implementation("com.yuno.sdk:card-scan:2.8.1")
}Habilite na configuração:
Yuno.initialize(
isto,
chavePúblicaAPI = "sua-chave",
config = YunoConfig(
digitalizaçãoDeCartãoAtivada = verdadeiro
)
)O botão para digitalização do cartão aparece automaticamente no formulário do cartão.
Integração ClearSale
Habilite a prevenção contra fraudes.
Adicionar SDK ClearSale:
dependencies {
implementation("br.com.clearsale:cs-android-sdk:4.0.0")
}Initialize:
import br.com.clearsale.androidsdk.ClearSale
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize ClearSale
ClearSale.init(this, "your-clearsale-app-key")
// Initialize Yuno
Yuno.initialize(this, "your-public-key", YunoConfig())
}
}fingerprint ClearSale fingerprint coletada e enviada automaticamente.
Tratamento de erros
Lidar com erros na chamada de retorno do estado do pagamento e no processamento do pagamento:
// Set up error handling in payment state callback
startCheckout(
callbackPaymentState = { state ->
when (state) {
"SUCCEEDED" -> handleSuccess()
"FAIL" -> {
// Handle payment failure
showError("Payment failed")
}
"REJECT" -> {
// Handle payment rejection
showRejectedMessage()
}
"PROCESSING" -> showPendingMessage()
else -> {}
}
}
)
// Update session with error handling
try {
val session = createCheckoutSession()
updateCheckoutSession(
checkoutSession = session.checkoutSession,
countryCode = "US"
)
} catch (e: Exception) {
Log.e("Payment", "Session error: ${e.message}")
showError("Failed to initialize payment")
}
// Handle errors during payment creation
startPayment(
showStatusYuno = true,
callbackOTT = { token ->
lifecycleScope.launch {
try {
createPayment(token, checkoutSession)
} catch (e: Exception) {
Log.e("Payment", "Payment creation error: ${e.message}")
showError("Payment failed: ${e.message}")
}
}
}
)Testes e depuração
Ativar registro
Yuno.setLogLevel(LogLevel.VERBOSE)Modo de teste
Yuno.initialize(
isto,
chavePúblicaDaAPI = "pk_test_sua_chave",
config = YunoConfig(modoDeTeste = verdadeiro)
)Desempenho
Inicialização preguiçosa
val yuno por lazy {
Yuno.initialize(this, "pk_test_key", YunoConfig())
Yuno.getInstance()
}Pré-carregar SDK
lifecycleScope.launch(Dispatchers.IO) {
Yuno.preload(this@MainActivity)
}Retorno do navegador externo (links diretos)
Lide com usuários que retornam ao seu aplicativo após fluxos de pagamento externos, como desafios de autenticação 3DS, redirecionamentos de transferência bancária, pagamentos PIX e métodos de pagamento alternativos com redirecionamentos externos.
1. Defina callback_url na sessão de checkout
Incluir callback_url ao criar a sessão de checkout no seu backend:
{
"callback_url": "myapp://return"
}
ImportanteSem
callback_url, os usuários podem ficar presos no navegador externo, sem ter como retornar ao seu aplicativo.
2. Configurar o tratamento de links diretos
Adicionar um intent-filter à sua atividade em AndroidManifest.xml:
<activity android:name=".YourMainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="return" />
</intent-filter>
</activity>O esquema (myapp) e host (return) deve corresponder ao seu callback_url.
3. Lidar com a intenção de devolução
Lidar com o link direto quando o usuário retornar:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Check if app was opened via deep link
intent.data?.let { uri ->
val url = uri.toString()
if (url.contains("myapp://return")) {
handlePaymentReturn(uri)
}
}
}
private fun handlePaymentReturn(uri: Uri) {
val sessionId = uri.getQueryParameter("checkoutSession")
sessionId?.let {
continuePayment(
showPaymentStatus = true,
checkoutSession = it,
countryCode = "US"
) { result ->
result?.let { status ->
Toast.makeText(this, "Payment status: $status", Toast.LENGTH_SHORT).show()
}
}
}
}4. Exemplo de integração completa
class PaymentActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialize checkout
startCheckout(
callbackPaymentState = { state ->
handlePaymentState(state)
}
)
// Handle deep link return
if (intent?.data != null) {
handleDeepLinkReturn(intent)
} else {
// Normal payment flow
initializePaymentUI()
}
}
private fun handleDeepLinkReturn(intent: Intent) {
intent.data?.let { uri ->
if (uri.toString().contains("myapp://return")) {
val sessionId = extractCheckoutSession(uri)
sessionId?.let {
continuePayment(
showPaymentStatus = true,
checkoutSession = it,
countryCode = "US"
) { result ->
when (result) {
"SUCCEEDED" -> navigateToSuccess()
"FAILED" -> showError("Payment failed")
else -> showPendingMessage()
}
}
}
}
}
}
private fun extractCheckoutSession(uri: Uri): String? {
return uri.getQueryParameter("checkoutSession")
}
}Melhores práticas
- Inclua sempre
callback_urlem fluxos de pagamento que podem redirecionar - Teste o tratamento de links diretos em vários dispositivos e versões do Android
- Lidar com dados de links diretos ausentes ou malformados de maneira elegante
- Atualize o status do pagamento na sua interface do usuário após retornar do navegador externo.
Atualizado há 1 dia