Přeskočit na hlavní obsah

MVP ukázka

Tato stránka ukazuje minimální funkční implementaci Mobilního SDK — kompletní příklad, který integruje karetní platby, Google Pay, 3D Secure autentizaci, overlay indikátoru načítání a zobrazení výsledku platby v jediné Activity.

Cílem je poskytnout přehledný výchozí bod při integraci SDK do vlastní aplikace. Detailní popis jednotlivých komponent a konfiguračních možností naleznete v navazujících sekcích dokumentace.

Co MVP obsahuje

  • Inicializaci session (ComgateSecureSession) včetně konfigurace 3D Secure
  • Formulář se Secure Fields pro karetní platbu (číslo karty, datum expirace, CVV, jméno držitele)
  • Tlačítko pro karetní platbu (SecurePayButton)
  • Tlačítko pro Google Pay (SecureGooglePayButton)
  • Overlay indikátoru načítání (SecureLoadingOverlay)
  • Zobrazení výsledku platby (SecurePaymentStatusView)

Zdrojový kód

package cz.comgate.mvpdemo

import android.os.Bundle
import android.util.Log
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color as ComposeColor
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import cz.comgate.sdk.ComgateSecureSession
import cz.comgate.sdk.PaymentParams
import cz.comgate.sdk.PaymentResult
import cz.comgate.sdk.compose.*
import cz.comgate.sdk.threeds.ThreeDSConfig
import cz.comgate.sdk.threeds.ThreeDSToolbarStyle
import cz.comgate.sdk.threeds.ThreeDSUiCustomization
import cz.comgate.sdk.ui.SecureLoadingOverlay

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
// Vytvoříme session a při ukončení obrazovky ji korektně uvolníme.
val session = remember {
try { createSession() }
catch (e: Exception) { Log.e("ComgateMvp", "createSession crashed", e); null }
}
if (session != null) {
DisposableEffect(session) { onDispose { session.dispose() } }
PaymentScreen(session)
} else {
Text("Initialization failed", color = ComposeColor.Red, modifier = Modifier.padding(20.dp))
}
}
}
}

private fun createSession() = ComgateSecureSession(
checkoutId = "<CHECKOUT_ID>",
context = applicationContext,
devMode = false,
googleMerchantId = "<GOOGLE_MERCHANT_ID>",
googleMerchantName = "<MERCHANT_NAME>",
threeDSConfig = ThreeDSConfig(
uiCustomization = ThreeDSUiCustomization(
toolbarStyle = ThreeDSToolbarStyle(
headerText = "<APP_NAME>"
)
),
challengeTimeoutMinutes = 5
),
lifecycleOwner = this,
onInitialized = { result ->
result.onSuccess { Log.i("ComgateMvp", "Session initialized") }
result.onFailure { Log.e("ComgateMvp", "Init failed: ${it.message}", it) }
}
)
}

@Composable
private fun PaymentScreen(session: ComgateSecureSession) {
val panState = rememberSecurePanFieldState()
val expiryState = rememberSecureExpiryFieldState()
val cvvState = rememberSecureCvvFieldState()
val fullNameState = rememberSecureFullNameFieldState()
// Data collector sjednotí sběr všech citlivých polí včetně jména držitele.
val collector = rememberSecureDataCollector(panState = panState, expiryState = expiryState, cvvState = cvvState, fullNameState = fullNameState, session = session)

val statusState = rememberPaymentStatusState()
statusState.translation = session.translation

val params: () -> PaymentParams = {
PaymentParams(email = "test@example.com", price = 100, curr = "CZK", country = "CZ", label = "Test payment", refId = "mvp-001")
}

// Jeden handler zpracuje výsledek pro kartu i Google Pay.
fun handleResult(result: PaymentResult) {
statusState.showStatus(result)
Log.i("ComgateMvp", "Payment: $result")
}

val activity = LocalContext.current as AppCompatActivity
// Overlay automaticky zobrazí indikátor během zpracování platby.
DisposableEffect(session) {
val overlay = SecureLoadingOverlay().apply { setup(session, activity) }
onDispose { overlay.detach() }
}

Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(start = 20.dp, end = 20.dp, bottom = 20.dp, top = 60.dp)) {
SecureFullNameField(state = fullNameState, modifier = Modifier.fillMaxWidth())
Spacer(Modifier.height(12.dp))
SecurePanField(state = panState, modifier = Modifier.fillMaxWidth())
Spacer(Modifier.height(12.dp))
SecureExpiryField(state = expiryState, modifier = Modifier.fillMaxWidth())
Spacer(Modifier.height(12.dp))
SecureCvvField(state = cvvState, modifier = Modifier.fillMaxWidth())
Spacer(Modifier.height(24.dp))
SecurePayButton(
session = session, collector = collector,
onPaymentResult = { handleResult(it) },
paymentParamsProvider = params,
modifier = Modifier.fillMaxWidth().height(52.dp)
)
Spacer(Modifier.height(16.dp))
SecureGooglePayButton(
session = session,
onPaymentResult = { handleResult(it) },
paymentParamsProvider = params,
modifier = Modifier.fillMaxWidth().height(48.dp)
)
Spacer(Modifier.height(16.dp))
SecurePaymentStatusView(state = statusState, modifier = Modifier.fillMaxWidth().padding(bottom = 16.dp))
}
}