Výsledky platby
Výsledek platby je reprezentován sealed třídou PaymentResult. Callback onPaymentResult v SecurePayButton.setup() i SecureGooglePayButton.setup() je vždy volán na hlavním vlákně (main thread).
PaymentResult
V praxi rozlišujte tyto 4 typy výsledku:
Typ PaymentResult | Popis |
|---|---|
PaymentResult.Paid | Platba byla dokončena a potvrzena. |
PaymentResult.Pending | Platba se stále zpracovává (mezistav). |
PaymentResult.Cancelled | Platba byla zrušena nebo zamítnuta serverem. |
PaymentResult.Failed | Chyba na straně knihovny během platebního procesu. |
Paid
Platba je úspěšně dokončená.
is PaymentResult.Paid -> {
val transId = result.transId
// Platba dokončena
}
PENDING
Platba ještě není finální, backend ji stále zpracovává.
is PaymentResult.Pending -> {
val transId = result.transId
// Čekáme na finální stav
}
CANCELLED
Platba byla zrušena nebo zamítnuta serverem. Obsahuje identifikátor transakce a volitelný důvod.
is PaymentResult.Cancelled -> {
val transId = result.transId
val reason = result.errorReason
// Platba byla ukončena bez úhrady
}
Pokud je výsledek PaymentResult.Cancelled, obsahuje odpověď i errorReason.
V SDK je tento důvod dostupný jako PaymentResult.Cancelled.errorReason.
PaymentResult.Cancelled také zahrnuje situace, kdy uživatel nedokončil 3D Secure challenge (zrušení, vypršení časového limitu nebo selhání ověření) — v takovém případě hodnota errorReason pochází ze serveru a odpovídá hodnotám jako TRANSACTION_CANCELLED, ACS_TIMEOUT nebo 3DS_AUTH_FAIL.
Možné hodnoty errorReason
errorReason | Význam |
|---|---|
CUSTOMER_CLICK | Zrušeno plátcem. |
FRAUD_SUSPECTED | Podezření na podvod. |
ESHOP_CANCELLED | Zrušeno obchodníkem. |
PROVIDER_REPORT | Zrušeno providerem. |
PROVIDER_TIMEOUT | Vypršel časový limit poskytovatele. |
CUSTOMER_TIMEOUT | Vypršel časový limit platby. |
ACS_TIMEOUT | Vypršel časový limit pro ověření. |
INVALID_CARDNO_EXPIRY | Chybně zadané číslo karty nebo datum platnosti karty. |
INVALID_CVC | Chybně zadaný CVC / CVV kód. |
LIMIT_EXCEEDED | Limit karty byl překročen. |
NO_FUNDS | Na účtu není dostatečný zůstatek. |
REJECTED_BY_BANK | Platba byla zamítnuta bankou. |
3DS_AUTH_FAIL | Ověření platby nebylo úspěšné. |
BANK_TIMEOUT | Vypršel časový limit pro provedení platby. |
BANK_FORBIDDEN | Plátce neudělil přístup ke svým účtům. |
TRANSACTION_CANCELLED | Plátce zrušil ověření platby. |
3RDPART_APP_LIMIT_EXCEEDED | Překročen limit transakcí pro třetí strany. |
UNAVAILABLE | Platební metoda je dočasně nedostupná. |
BAD_ACCOUNT_TYPE | Typ účtu plátce nepodporuje tuto platbu. |
NOT_SPECIFIED | Nespecifikováno. |
FAILED
Chyba na straně knihovny, která nastala během platebního procesu. Na rozdíl od Cancelled (kde server aktivně zamítl platbu), Failed značí, že k dokončení platby vůbec nedošlo — např. síťová chyba,...
Výsledek obsahuje objekt ComgateError s machine-readable kódem (code) a lidsky čitelnou zprávou (message).
is PaymentResult.Failed -> {
val errorCode = result.error.code // např. "PAYMENT_NETWORK_ERROR"
val errorMessage = result.error.message // např. "Payment request failed due to a network error"
// Zobrazení chyby uživateli
}
ComgateError
Všechny chyby jsou definovány jako podtypy sealed třídy ComgateError. Každý typ obsahuje:
code— strojově čitelný identifikátor chybymessage— lidsky čitelný popis v angličtině
Inicializace
| Kód | Popis |
|---|---|
INIT_NETWORK_ERROR | Inicializace session selhala kvůli síťové chybě. |
INIT_FAILED | Inicializace session selhala (jiný než síťový důvod). |
Zpracování platby
| Kód | Popis |
|---|---|
SESSION_NOT_INITIALIZED | Session nebyla inicializována. Zavolejte nejprve initialize(). |
INVALID_CARD_DATA | Karetní data nejsou validní. |
PAYMENT_FAILED | Platba selhala (jiný než síťový důvod). |
PAYMENT_NETWORK_ERROR | Platební požadavek selhal kvůli síťové chybě. |
POLLING_TIMEOUT | Kontrola stavu platby vypršela. |
POLLING_NETWORK_ERROR | Kontrola stavu platby selhala kvůli síťové chybě. |
3D Secure
| Kód | Popis |
|---|---|
THREE_DS_FAILED | Selhání na úrovni 3D Secure SDK — nastane při inicializaci nebo spuštění autentizace (technická chyba, ne výsledek challenge). |
Pokud uživatel zruší 3D Secure challenge, vyprší časový limit nebo autentizace selže, výsledkem je PaymentResult.Cancelled (nikoliv PaymentResult.Failed). Hodnota errorReason pak obsahuje například TRANSACTION_CANCELLED, ACS_TIMEOUT nebo 3DS_AUTH_FAIL.
Google Pay
| Kód | Popis |
|---|---|
GOOGLE_PAY_NOT_CONFIGURED | Google Pay není nakonfigurován. |
GOOGLE_PAY_CANCELLED | Google Pay byl zrušen uživatelem. |
GOOGLE_PAY_FAILED | Google Pay platba selhala. |
Validace polí
| Kód | Popis |
|---|---|
INVALID_PAN | Neplatné číslo karty. |
INVALID_EXPIRY_MONTH | Neplatný měsíc expirace. |
CARD_EXPIRED | Karta je expirovaná. |
INVALID_CVV | Neplatný CVV kód. |
SecurePaymentStatusView
Komponenta SecurePaymentStatusView slouží k zobrazování stavových hlášek platby (úspěch, zpracování, chyba). Začíná ve skrytém stavu (GONE) a zobrazí se po zavolání showStatus().
Zobrazení stavu z PaymentResult
Metoda showStatus(PaymentResult) automaticky rozpozná typ výsledku a zobrazí odpovídající styl:
val statusState = rememberPaymentStatusState()
// Automatické mapování PaymentResult na stavovou zprávu
statusState.showStatus(paymentResult)
// V Composable:
SecurePaymentStatusView(state = statusState)
| PaymentResult | Chování |
|---|---|
Paid | Zobrazí lokalizovanou zprávu „Paid“ se zeleným stylem (úspěch). |
Pending | Zobrazí lokalizovanou zprávu „Processing“ s oranžovým stylem (zpracování). |
Cancelled | Zobrazí errorReason s červeným stylem (chyba). |
Skrytí view
statusState.clear()
Stylizace
Podrobnosti o stylizaci SecurePaymentStatusView prostřednictvím update bloku, setter metod a XML atributů naleznete v sekci Stylizace komponent.
Kompletní příklad zpracování výsledků
@Composable
private fun PaymentResultHandler(session: ComgateSecureSession) {
val statusState = rememberPaymentStatusState()
var resultText by remember { mutableStateOf("") }
var resultVisible by remember { mutableStateOf(false) }
// ... (karetní pole, kolektor, tlačítko — viz sekce Karetní data)
// Zpracování výsledku platby:
fun handlePaymentResult(result: PaymentResult) {
when (result) {
is PaymentResult.Paid -> {
statusState.showStatus(result)
resultVisible = true
resultText = "Platba dokončena\nTransId: ${result.transId ?: "-"}"
}
is PaymentResult.Pending -> {
statusState.showStatus(result)
resultVisible = true
resultText = "Platba se zpracovává\nTransId: ${result.transId ?: "-"}"
}
is PaymentResult.Cancelled -> {
resultVisible = false
statusState.showStatus(result)
// Volitelne: Toast.makeText(context, "Platba zrušena: ${result.errorReason ?: "bez detailu"}", Toast.LENGTH_LONG).show()
}
is PaymentResult.Failed -> {
resultVisible = false
statusState.showStatus(result)
Log.w("PaymentResult", "Failed: ${result.error.code} — ${result.error.message}")
// Volitelne: Toast.makeText(context, "Chyba: ${result.error.message}", Toast.LENGTH_LONG).show()
}
}
}
Column(modifier = Modifier.fillMaxWidth()) {
SecurePaymentStatusView(
state = statusState,
modifier = Modifier.fillMaxWidth()
)
if (resultVisible) {
Text(
text = resultText,
modifier = Modifier.padding(top = 8.dp)
)
}
}
}