Přeskočit na hlavní obsah

Výsledky platby

Výsledek platby je reprezentován sealed třídou PaymentResult. Callback onPaymentResultSecurePayButton.setup()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 PaymentResultPopis
PaymentResult.PaidPlatba byla dokončena a potvrzena.
PaymentResult.PendingPlatba se stále zpracovává (mezistav).
PaymentResult.CancelledPlatba byla zrušena nebo zamítnuta serverem.
PaymentResult.FailedChyba na straně knihovny během platebního procesu.

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

errorReasonVýznam
CUSTOMER_CLICKZrušeno plátcem.
FRAUD_SUSPECTEDPodezření na podvod.
ESHOP_CANCELLEDZrušeno obchodníkem.
PROVIDER_REPORTZrušeno providerem.
PROVIDER_TIMEOUTVypršel časový limit poskytovatele.
CUSTOMER_TIMEOUTVypršel časový limit platby.
ACS_TIMEOUTVypršel časový limit pro ověření.
INVALID_CARDNO_EXPIRYChybně zadané číslo karty nebo datum platnosti karty.
INVALID_CVCChybně zadaný CVC / CVV kód.
LIMIT_EXCEEDEDLimit karty byl překročen.
NO_FUNDSNa účtu není dostatečný zůstatek.
REJECTED_BY_BANKPlatba byla zamítnuta bankou.
3DS_AUTH_FAILOvěření platby nebylo úspěšné.
BANK_TIMEOUTVypršel časový limit pro provedení platby.
BANK_FORBIDDENPlátce neudělil přístup ke svým účtům.
TRANSACTION_CANCELLEDPlátce zrušil ověření platby.
3RDPART_APP_LIMIT_EXCEEDEDPřekročen limit transakcí pro třetí strany.
UNAVAILABLEPlatební metoda je dočasně nedostupná.
BAD_ACCOUNT_TYPETyp účtu plátce nepodporuje tuto platbu.
NOT_SPECIFIEDNespecifiková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 chyby
  • message — lidsky čitelný popis v angličtině
Inicializace
KódPopis
INIT_NETWORK_ERRORInicializace session selhala kvůli síťové chybě.
INIT_FAILEDInicializace session selhala (jiný než síťový důvod).
Zpracování platby
KódPopis
SESSION_NOT_INITIALIZEDSession nebyla inicializována. Zavolejte nejprve initialize().
INVALID_CARD_DATAKaretní data nejsou validní.
PAYMENT_FAILEDPlatba selhala (jiný než síťový důvod).
PAYMENT_NETWORK_ERRORPlatební požadavek selhal kvůli síťové chybě.
POLLING_TIMEOUTKontrola stavu platby vypršela.
POLLING_NETWORK_ERRORKontrola stavu platby selhala kvůli síťové chybě.
3D Secure
KódPopis
THREE_DS_FAILEDSelhání na úrovni 3D Secure SDK — nastane při inicializaci nebo spuštění autentizace (technická chyba, ne výsledek challenge).
Poznámka

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ódPopis
GOOGLE_PAY_NOT_CONFIGUREDGoogle Pay není nakonfigurován.
GOOGLE_PAY_CANCELLEDGoogle Pay byl zrušen uživatelem.
GOOGLE_PAY_FAILEDGoogle Pay platba selhala.
Validace polí
KódPopis
INVALID_PANNeplatné číslo karty.
INVALID_EXPIRY_MONTHNeplatný měsíc expirace.
CARD_EXPIREDKarta je expirovaná.
INVALID_CVVNeplatný 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)
PaymentResultChování
PaidZobrazí lokalizovanou zprávu „Paid“ se zeleným stylem (úspěch).
PendingZobrazí lokalizovanou zprávu „Processing“ s oranžovým stylem (zpracování).
CancelledZobrazí 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)
)
}
}
}