Výsledky platby
Výsledek platby je reprezentován výčtem PaymentResult. Asynchronní metody processPayment(...) a processApplePayPayment(...) vrací PaymentResult přímo, callback onResult v SecurePayButton a SecureApplePayButton je vždy volán na hlavním vlákně.
PaymentResult
V praxi rozlišujte tyto typy výsledku:
Případ PaymentResult | Asociované hodnoty | Popis |
|---|---|---|
.paid(transId:) | String | Platba byla dokončena a potvrzena. |
.authorized(transId:) | String | Platba byla autorizována bankou (předautorizace). |
.pending(transId:) | String | Platba se stále zpracovává (mezistav). |
.cancelled(errorReason:transId:) | String?, String | Platba byla zrušena nebo zamítnuta serverem. |
.failed(ComgateError) | ComgateError | Chyba na straně knihovny během platebního procesu. |
Paid
Platba je úspěšně dokončená.
case .paid(let transId):
// Platba dokončena
print("Paid: \(transId)")
Authorized
Platba byla autorizována (předautorizována) bankou. Jde o finální stav. Zachycení (settlement) platby provede obchodník samostatně pomocí standardních endpointů /capturePreauth nebo /cancelPreauth.
case .authorized(let transId):
// Platba autorizována, čeká na zachycení
print("Authorized: \(transId)")
Pending
Platba ještě není finální, backend ji stále zpracovává. Finálním stavem bude .paid, .authorized nebo .cancelled.
case .pending(let transId):
// Čekáme na finální stav
print("Pending: \(transId)")
Cancelled
Platba byla zrušena nebo zamítnuta serverem. Obsahuje identifikátor transakce a volitelný důvod.
case .cancelled(let errorReason, let transId):
// Platba byla ukončena bez úhrady
print("Cancelled: \(errorReason ?? "-") (\(transId))")
Možné hodnoty errorReason
errorReason je raw value výčtu ErrorReason (může být nil, pokud server hodnotu nedodá):
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é. |
NOT_SPECIFIED | Nespecifikováno. |
V dev režimu (devMode = true) můžete tyto hodnoty simulovat pomocí parametru errorReason v PaymentParams. Viz sekci Simulace chybového důvodu.
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, neinicializovaná session apod.
Asociovanou hodnotou je objekt ComgateError s machine-readable kódem (code) a lidsky čitelnou zprávou (message).
case .failed(let error):
let errorCode = error.code // např. "PAYMENT_NETWORK_ERROR"
let errorMessage = error.message // např. "Network error during payment."
// Zobrazení chyby uživateli
ComgateError
Všechny chyby jsou definovány jako case výčtu ComgateError. Každý case vystavuje:
code: String— strojově čitelný identifikátor chybymessage: String— lidsky čitelný popis v angličtině
Inicializace
| Případ | Kód | Popis |
|---|---|---|
.deviceRooted | DEVICE_ROOTED | Zařízení je pravděpodobně jailbreaknuté nebo jinak pozměněné. Inicializace je zablokovaná za účelem ochrany karetních dat. V devMode se tato kontrola přeskočí. |
.initNetworkError | INIT_NETWORK_ERROR | Inicializace session selhala kvůli síťové chybě. |
.initUnauthorized | INIT_UNAUTHORIZED | Server vrátil HTTP 401 při inicializaci — neplatná nebo expirovaná autorizace. |
.initFailed | INIT_FAILED | Inicializace session selhala (jiný než síťový důvod). |
.applicationNotAllowed | APPLICATION_NOT_ALLOWED | Aplikace není povolena pro použití SDK (Bundle ID není na allow-listu). |
Zpracování platby
| Případ | Kód | Popis |
|---|---|---|
.sessionNotInitialized | SESSION_NOT_INITIALIZED | Session nebyla inicializována. Zavolejte nejprve initialize(). |
.invalidCardData | INVALID_CARD_DATA | Karetní data nejsou validní. |
.missingCardholderName | MISSING_CARDHOLDER_NAME | Jméno držitele karty nebylo poskytnuto. |
.paymentFailed | PAYMENT_FAILED | Platba selhala (jiný než síťový důvod). |
.paymentNetworkError | PAYMENT_NETWORK_ERROR | Platební požadavek selhal kvůli síťové chybě. |
.paymentCreateFailed | PAYMENT_CREATE_FAILED | Vytvoření platby selhalo. |
.pollingTimeout | POLLING_TIMEOUT | Kontrola stavu platby vypršela. |
.pollingNetworkError | POLLING_NETWORK_ERROR | Kontrola stavu platby selhala kvůli síťové chybě. |
.threeDSChallengeCancelled | THREE_DS_CHALLENGE_CANCELLED | 3D Secure challenge byla zrušena. |
.threeDSChallengeTimeout | THREE_DS_CHALLENGE_TIMEOUT | 3D Secure challenge vypršela časem. |
.threeDSFailed | THREE_DS_FAILED | 3D Secure autentizace selhala. |
Apple Pay
| Případ | Kód | Popis |
|---|---|---|
.applePayNotConfigured | APPLE_PAY_NOT_CONFIGURED | Apple Pay není nakonfigurován. |
.applePayCancelled | APPLE_PAY_CANCELLED | Apple Pay byl zrušen uživatelem. |
.applePayFailed | APPLE_PAY_FAILED | Apple Pay platba selhala. |
Validace polí
| Případ | Kód | Popis |
|---|---|---|
.invalidPan | INVALID_PAN | Neplatné číslo karty. |
.invalidExpiryMonth | INVALID_EXPIRY_MONTH | Neplatný měsíc expirace. |
.cardExpired | CARD_EXPIRED | Karta je expirovaná. |
.invalidCvv | INVALID_CVV | Neplatný CVV kód. |
.conflictingPaymentOptions | CONFLICTING_PAYMENT_OPTIONS | initRecurring a preauth nemohou být oba true. |
.invalidPrice | INVALID_PRICE | price musí být kladné celé číslo v nejmenší jednotce měny. |
SecurePaymentStatusView
Komponenta SecurePaymentStatusView slouží k zobrazování stavových hlášek platby (úspěch, zpracování, chyba). Pracuje s objektem PaymentStatusState, který drží aktuální zobrazenou zprávu.
PaymentStatusState
| Vlastnost / Metoda | Typ | Popis |
|---|---|---|
visible | Bool | true pokud má být view zobrazené (read-only, @Published). |
text | String | Aktuální text (read-only, @Published). |
translation | Translation | Překlady použité pro automatické zprávy. Nastavte na session.translation. |
show(result:) | func show(result: PaymentResult) | Automaticky vybere a zobrazí lokalizovanou zprávu pro daný výsledek. |
showError(_:) | func showError(_ message: String) | Zobrazí vlastní chybovou zprávu. |
hide() | func hide() | Skryje view (text zůstává). |
clear() | func clear() | Skryje view a vyčistí text. |
Zobrazení stavu z PaymentResult
@StateObject private var statusState = PaymentStatusState()
statusState.translation = session.translation
statusState.show(result: paymentResult)
// V SwiftUI:
SecurePaymentStatusView(state: statusState)
PaymentResult | Chování |
|---|---|
.paid | Zobrazí lokalizovanou zprávu z Translation.statusPaid se zeleným stylem (úspěch). |
.authorized | Zobrazí lokalizovanou zprávu z Translation.statusAuthorized se zeleným stylem (úspěch). |
.pending | Zobrazí lokalizovanou zprávu z Translation.statusPending s oranžovým stylem (zpracování). |
.cancelled | Zobrazí errorReason s červeným stylem (chyba). |
.failed | Zobrazí error.message s červeným stylem (chyba). |
Skrytí view
statusState.clear() // skryje view a vyčistí text
statusState.hide() // pouze skryje view, text zůstává
Stylizace
Podrobnosti o stylizaci SecurePaymentStatusView prostřednictvím struktury PaymentStatusStyle naleznete v sekci Stylizace komponent.
Kompletní příklad zpracování výsledků
struct PaymentResultHandler: View {
@ObservedObject var session: ComgateSecureSession
@StateObject private var statusState = PaymentStatusState()
@State private var resultText = ""
@State private var resultVisible = false
func handle(_ result: PaymentResult) {
statusState.translation = session.translation
switch result {
case .paid(let t):
statusState.show(result: result)
resultVisible = true
resultText = "Platba dokončena\nTransId: \(t)"
case .authorized(let t):
statusState.show(result: result)
resultVisible = true
resultText = "Platba autorizována\nTransId: \(t)"
case .pending(let t):
statusState.show(result: result)
resultVisible = true
resultText = "Platba se zpracovává\nTransId: \(t)"
case .cancelled:
statusState.show(result: result)
resultVisible = false
case .failed(let err):
statusState.show(result: result)
resultVisible = false
print("Failed: \(err.code) — \(err.message)")
}
}
var body: some View {
VStack {
// ... (karetní pole, tlačítko — viz sekce Karetní data)
SecurePaymentStatusView(state: statusState)
if resultVisible {
Text(resultText)
.padding(.top, 8)
}
}
}
}