Aplikace Tapaya Terminal
Přijímejte bezkontaktní platby kartou tak, že práci s kartou předáte pluginové aplikaci Tapaya Terminal.
Přijímejte bezkontaktní platby kartou ze své aplikace pro Android tak, že práci s kartou předáte pluginové aplikaci Tapaya Terminal.
Prodej zůstává pod kontrolou vaší aplikace; plugin obstará přiložení karty přes NFC, zadání PIN a zpracování
karty a výsledek se pak vrátí přes proud událostí Accept.payments.pay().
Tuto integraci použijte, pokud chcete Tap to Pay, aniž byste do vlastní aplikace vkládali zpracovatele plateb. Pokud má vaše platforma místo toho povolené vestavěné Tap to Pay, přečtěte si průvodce Embedded Tap to Pay.
Možnosti integrace
| Možnost | Vhodné pro | Doručení výsledku |
|---|---|---|
| Accept SDK (doporučeno) | Nativní aplikace pro Android | Accept.payments.pay() vysílá Flow<PaymentEvent>: vytvoření, spuštění i konečný výsledek z terminálu se zpracují za vás |
| Deeplink | WebView, multiplatformní frameworky, QR kódy | Platbu vytvoříte přes Tapaya API a průběžně se dotazujete na její stav; plugin se otevře přes deeplink |
Nejprve je popsána cesta přes SDK; kontrakt deeplinku najdete v části Integrace bez SDK.
Jak to funguje
- Vaše aplikace zahájí platbu voláním
Accept.payments.pay(amount, currency). - SDK zaregistruje platbu v backendu Tapaya a spustí plugin Tapaya Terminal na stejném zařízení.
- Zákazník přiloží kartu nebo telefon k obrazovce Tapaya Terminal.
- Tapaya Terminal dokončí zpracování platby s backendem Tapaya.
- SDK sleduje platbu, dokud nedosáhne konečného stavu, a vyšle
PaymentEvent.ResultsPayResult. Pokud platbu vůbec nelze vytvořit, vyšle místo tohoPaymentEvent.CreationFailed, obvykle do jedné sekundy.
Předpoklady
- Plugin Tapaya Terminal nainstalovaný v zařízení a aktivovaný pro vašeho obchodníka (viz Instalace a aktivace terminálu).
- Zařízení s NFC se systémem Android 11 (API 30) nebo novějším.
- Accept SDK nainstalované a inicializované, s autentizovaným obchodníkem.
- Oprávnění k poloze (
ACCESS_FINE_LOCATION) udělené vaší aplikaci za běhu.
Instalace a aktivace terminálu
Aktivaci proveďte jednou pro každé zařízení. Aktivace propojí plugin Tapaya Terminal se stejným účtem obchodníka, pod kterým je autentizovaná vaše aplikace.
if (!Accept.plugin.isInstalled()) {
// Opens the store listing so the user can install Tapaya Terminal
Accept.plugin.install()
return
}
// suspend; launches the plugin's activation flow and waits for the outcome
when (val result = Accept.plugin.activateTerminal()) {
ActivateTerminalResult.Success -> { /* device linked, ready to take payments */ }
ActivateTerminalResult.Canceled -> { /* user backed out */ }
is ActivateTerminalResult.Failed -> result.reason // ActivateTerminalFailureReason
}ActivateTerminalFailureReason je jedna z hodnot INVALID_INTENT, HANDOVER_FAILED, CONFIRM_FAILED,
MERCHANT_NOT_ONBOARDED nebo UNKNOWN.
Poznámka
Accept.plugin.isInstalled() vrací false, když plugin Tapaya Terminal chybí. Aktuální stav pluginu
kdykoli zjistíte voláním Accept.plugin.status(); podle něj ošetřete své platební UI.
activateTerminal() navíc vyhazuje NoTidsAvailableForMerchant, když obchodníkovi nezbývá žádný nepřiřazený terminál
(TID) k aktivaci, a to odděleně od výše uvedených výsledků ActivateTerminalResult.Failed. Pokud chcete tento případ
zobrazit zvlášť, například vyzvat obchodníka, aby uvolnil nebo si vyžádal další TID, obalte volání do
try-catch.
Kontrola aktualizací pluginu
Accept.plugin.updateInfo() hlásí, zda je na Google Play k dispozici novější sestavení pluginu Tapaya Terminal,
takže můžete obchodníka vyzvat k aktualizaci dřív, než platba narazí na rozdíl verzí.
when (val info = Accept.plugin.updateInfo()) {
PluginUpdateInfo.UpToDate -> { /* nothing to do */ }
is PluginUpdateInfo.UpdateAvailable -> promptUpdate(info.priority) // Int, higher is more urgent
PluginUpdateInfo.Unknown -> { /* not installed, or an older plugin build that predates this check */ }
}Poznámka
SDK se nikdy nedotazuje Google Play přímo; pluginová aplikace si dostupnost aktualizace ověřuje sama přes Play Core a výsledek hlásí
svým stávajícím stavovým kanálem. Sestavení pluginu starší než to, se kterým byla tato funkce vydána, vždy hlásí
Unknown.
Vytvoření platby
Částky jsou vždy v nejmenší jednotce měny: haléře pro CZK, centy pro EUR. 1500 s
měnou "CZK" naúčtuje 15,00 Kč. Měny se zadávají jako kódy ISO 4217.
pay() vrací Flow<PaymentEvent>; sbírejte jej, abyste sledovali průběh a konečný výsledek. Nikdy nevyhazuje výjimku;
selhání se projeví jako PaymentEvent.CreationFailed.
Accept.payments.pay(amount = 1500, currency = "CZK") // 15.00 Kč
.collect { event ->
when (event) {
PaymentEvent.Creating -> { /* registering the payment */ }
is PaymentEvent.Created -> { /* backend payment created: event.paymentToken */ }
PaymentEvent.Launched -> { /* Tapaya Terminal is in the foreground */ }
is PaymentEvent.Result -> when (val r = event.payResult) {
is PayResult.Success -> showReceipt(r.paymentToken, r.authCode)
is PayResult.Declined -> showDeclined(r.metadata)
is PayResult.Canceled -> showCancelled(r.metadata)
is PayResult.Failed -> showUnexpected(r.reason) // PayFailureReason
}
is PaymentEvent.CreationFailed -> handleError(event.cause) // AcceptException
}
}Parametry:
| Parametr | Typ | Povinné | Popis |
|---|---|---|---|
amount | Long | ✓ | Částka k naúčtování v nejmenší jednotce měny currency (např. centy pro USD, haléře pro CZK). |
currency | String | ✓ | Kód měny ISO 4217. |
paymentToken | String? | Obnoví existující platební relaci místo zahájení nové. Výchozí hodnota je null. | |
receiptConfig | PaymentReceiptConfig? | Přepíše obrazovku účtenky zobrazenou po schválené platbě, jen pro toto volání. Výchozí hodnota je null, při které se použije výchozí nastavení z Accept.payments.setOptions(). | |
nfcPosition | NfcPositionConfig? | Přepíše, kam míří animace přiložení karty, jen pro toto volání. Výchozí hodnota je null, při které se použije výchozí nastavení z Accept.payments.setOptions(). | |
metadata | Map<String, String> | Data ve tvaru klíč-hodnota připojená k platbě. Odesílají se pluginu Tapaya Terminal v intentu PAY a vracejí se zpět ve výsledném PayResult, pokud je plugin vrátí. Výchozí hodnota je emptyMap(). | |
tip | Long? | Pevné spropitné v nejmenší jednotce měny currency. Je-li nastaveno, plugin přeskočí vlastní interaktivní obrazovku spropitného a naúčtuje amount + tip. Výchozí hodnota je null (plugin se plátce na spropitné zeptá). | |
transactionTimeout | Duration? | Přepíše, jak dlouho terminál čeká na přiložení karty, jen pro toto volání. Výchozí hodnota je null, při které se použije výchozí nastavení z Accept.payments.setOptions(). Viz Nastavení časového limitu transakce. | |
display | PaymentDisplay? | Přepíše, na které obrazovce běží platební UI pluginu, jen pro toto volání. Výchozí hodnota je null, při které se použije výchozí nastavení z Accept.payments.setOptions(). Viz Volba displeje. |
Během platby je plugin Tapaya Terminal v popředí. Po dokončení platby se vaše aplikace automaticky
vrátí do popředí. Chcete-li obnovit přerušenou platbu, předejte její paymentToken zpět do
pay(amount, currency, paymentToken).
Vrácení metadata není zaručeno
metadata se v PayResult vracejí jen tehdy, když je plugin vrátí, proto je berte jako doplňkový kontext bez záruky
(např. ID objednávky pro vlastní logování), ne jako data, na jejichž vrácení vaše aplikace závisí.
Volba měny
pay() účtuje v měně currency, kterou předáte jako kód ISO 4217 velkými písmeny, s částkou amount v nejmenší
jednotce této měny. Stránka Podporované měny uvádí všechny měny, které Tapaya podporuje, ale obchodník
má obvykle povolené jen některé z nich.
Kódy ISO 4217, které má obchodník povolené, zjistíte voláním Accept.merchant.availableCurrencies(). Platba v jakékoli jiné
měně selže s CurrencyNotAvailableForMerchant.
Každá měna má také minimální částku k zaplacení, vynucovanou v celé platformě. Aktuální minima načtete pomocí
Accept.sdk.minimumAmounts(), které vrací List<MinimumAmount> (currency: String, amount: Long, v nejmenší
jednotce měny). Volání pay() pod tímto minimem selže s
PaymentEvent.CreationFailed(AmountBelowMinimum(minimum, currency)). Úplný seznam výjimek najdete v části
Zpracování chyb.
Nastavení obrazovky účtenky
receiptConfig určuje, co plugin Tapaya Terminal zobrazí plátci po schválené platbě, jak dlouho
to zůstane na obrazovce a zda se účtenka vytiskne. Nemá žádný vliv na zamítnuté a stornované platby ani na platby čekající
na storno; ty vždy zobrazí vlastní obrazovku výsledku bez ohledu na toto nastavení.
PaymentReceiptConfig | Popis |
|---|---|
DismissImmediately | Plátci se nic nezobrazí. |
Show(showQrCodeReceipt, dismissBehavior, printBehavior) | Zobrazí obrazovku účtenky. showQrCodeReceipt: Boolean = true zapíná nebo vypíná QR kód s odkazem na účtenku. dismissBehavior: DismissBehavior = DismissBehavior.Manual určuje, jak se obrazovka zavře: Manual (zůstane, dokud ji plátce nezavře) nebo Delayed(delay: Duration) (automaticky se zavře po uplynutí delay, pokud ji plátce nezavřel dříve). printBehavior: ReceiptPrintBehavior = ReceiptPrintBehavior.OnDemand řídí fyzickou účtenku: Automatic (vytiskne se hned, jak se obrazovka zobrazí), OnDemand (jen když tisk spustí pokladní) nebo Disabled (nikdy se netiskne). |
Výchozí nastavení pro celé zařízení nastavte jednou pomocí Accept.payments.setOptions() a pro jednotlivou platbu jej přepište
přes pay(..., receiptConfig = ...). Dokud nezavoláte setOptions(), výchozí hodnota je Show s QR účtenkou, ručním
zavřením a tiskem na vyžádání, což odpovídá vlastnímu záložnímu nastavení pluginu.
// Set a default, e.g. once at app startup
Accept.payments.setOptions(
receiptConfig = PaymentReceiptConfig.Show(
showQrCodeReceipt = true,
dismissBehavior = DismissBehavior.Delayed(30.seconds),
printBehavior = ReceiptPrintBehavior.Automatic,
),
)
// Override it for a single payment
Accept.payments.pay(
amount = 1500,
currency = "CZK",
receiptConfig = PaymentReceiptConfig.DismissImmediately,
)Umístění animace přiložení přes NFC
nfcPosition je nápověda, která pluginu Tapaya Terminal sděluje, kde má toto zařízení anténu NFC, aby mohl
správně umístit animaci „přiložte zde“. Plugin nejprve určí polohu antény sám (živou detekcí platformy,
pak z přibalené databáze zařízení a nakonec z čehokoli, co obchodník nastavil přímo v pluginu); tuto hodnotu zadávejte jen
tehdy, když chcete toto určení přepsat, například u zařízení, které plugin nedokáže rozpoznat nebo ho má ve své databázi chybně.
NfcPositionConfig | Popis |
|---|---|
Unspecified | Bez přepsání (výchozí). Plugin určí polohu sám a zachová polohu, kterou v něm obchodník již nastavil. |
OnDevice(surface, xFraction, yFraction) | Anténa je přímo v zařízení; animace míří na bod (xFraction, yFraction) na ploše surface, což je OnDeviceSurface.BACK nebo OnDeviceSurface.FRONT_SCREEN. |
ExternalAbove | Samostatný modul čtečky je umístěn nad telefonem (držák smart-POS); na zařízení tedy není žádný bod, na který by animace mířila. |
Výchozí nastavení pro celé zařízení nastavte pomocí Accept.payments.setOptions(nfcPosition = ...), nebo jej přepište pro jednotlivé volání
přes pay(..., nfcPosition = ...). setOptions() mění jen ty volby, které předáte, takže samotné setOptions(nfcPosition = ...)
nenaruší dříve nastavenou výchozí hodnotu receiptConfig a naopak.
Nastavení časového limitu transakce
transactionTimeout určuje, jak dlouho plugin Tapaya Terminal čeká na přiložení karty zákazníkem, než to
vzdá. Přijímá jakoukoli hodnotu Duration od nuly do 120 sekund; cokoli mimo tento rozsah se projeví jako
TransactionTimeoutOutOfRange(transactionTimeout) přes PaymentEvent.CreationFailed, protože pay() nikdy nevyhazuje výjimku
synchronně.
Accept.payments.pay(
amount = 1500,
currency = "CZK",
transactionTimeout = 90.seconds,
)Ponechte výchozí hodnotu null, chcete-li použít vlastní záložní limit doprovodné aplikace (přibližně 60 sekund), nebo nastavte výchozí
hodnotu pro celé zařízení pomocí Accept.payments.setOptions(transactionTimeout = ...).
Volba displeje
U oboustranného zařízení („double-sided“) je jeden panel otočený k obchodníkovi a druhý, zákaznický panel k
plátci. Accept.displays hlásí, jaké displeje zařízení právě má, a volba display říká pluginu,
na kterém panelu má spustit své platební UI.
if (Accept.displays.isDualScreen) {
val customerPanel = Accept.displays.customerFacing() // AcceptDisplay?, null on single-screen devices
}
Accept.payments.pay(
amount = 1500,
currency = "CZK",
display = PaymentDisplay.CustomerFacing,
)PaymentDisplay | Popis |
|---|---|
Default | Aktuální displej hostitelské aplikace (výchozí chování, na zařízeních s jednou obrazovkou beze změny). |
CustomerFacing | Sekundární panel oboustranného zařízení. |
Specific(displayId) | Konkrétní displej podle id uvedeného v Accept.displays.all(). |
Cíl, který nelze splnit, například CustomerFacing na zařízení s jednou obrazovkou, tiše přejde na
Default. Výchozí nastavení pro celé zařízení nastavte pomocí Accept.payments.setOptions(display = ...), nebo jej přepište pro jednotlivé volání
přes pay(..., display = ...).
Nastavte cíl před autentizací
Předběžná příprava terminálu (warm-up) spuštěná voláním Accept.auth.authenticate() se řídí stejným cílem, proto zavolejte
setOptions(display = ...) před authenticate(), pokud chcete, aby ani samotná příprava neprobíhala na
obrazovce obchodníka.
Ukázková aplikace :dualscreen předvádí kompletní placení na dvou panelech: obchodník pracuje na primárním panelu, zatímco
PaymentDisplay.CustomerFacing zobrazí platební UI pluginu na obrazovce zákazníka.
Výsledek platby
Konečná událost PaymentEvent.Result nese PayResult. Každá varianta nese metadata, která vracejí to, co jste
předali do pay(), pokud je plugin vrátí (může být null):
PayResult | Význam |
|---|---|
Success(paymentToken, metadata, authCode, receiptDetails) | Autorizováno a strženo. Prostředky budou zúčtovány obchodníkovi. authCode je autorizační kód zpracovatele hlášený terminálem; má informativní charakter a v závislosti na zpracovateli může chybět. |
Declined(metadata, receiptDetails) | Zamítnuto zpracovatelem plateb nebo vydavatelem karty. |
Canceled(metadata) | Zrušeno zákazníkem nebo obchodníkem před dokončením. |
Failed(reason, metadata) | Nedokončeno; reason je PayFailureReason. |
PayFailureReason je jedna z hodnot INVALID_INTENT, NOT_ACTIVATED, TERMINAL_INIT_FAILED, PAYMENT_SETUP_FAILED,
PLUGIN_UNAVAILABLE nebo UNKNOWN.
Čtení údajů účtenky
Success a Declined nesou volitelné receiptDetails: ReceiptDetails? se strukturovanými údaji karetní účtenky
hlášenými terminálem, určené pro volající, kteří tisknou vlastní oficiální karetní účtenku místo toho, aby se spoléhali jen na
hostovanou stránku PaymentStatus.receiptUrl.
| Pole | Typ | Popis |
|---|---|---|
merchantId | String? | ID obchodníka hlášené zpracovatelem. |
terminalId | String? | ID terminálu hlášené zpracovatelem. |
cardBrand | String? | Značka karty, např. Visa nebo Mastercard. |
appLabel | String? | Označení aplikace EMV. |
aid | String? | Identifikátor aplikace EMV. |
maskedPan | String? | Maskované číslo karty. |
responseCode | String? | Kód odpovědi zpracovatele. |
transactionTimestamp | String? | Časové razítko transakce ve formátu ISO-8601. |
Každé pole je volitelné a bez záruky; volající musí počítat s tím, že kterékoli z nich, případně i samotné receiptDetails,
bude chybět.
Čtení podrobností platby
PayResult.Success vám poskytne paymentToken. Úplný záznam, včetně receiptUrl, požadované a
zúčtované částky a časových razítek, načtete pomocí Accept.payments.status():
val status: PaymentStatus = Accept.payments.status(paymentToken)
status.state // PENDING, SUCCESS, CANCELLED, REFUNDED, FAILED, ACTION_NEEDED
status.receiptUrl // for your receipt UIProbíhající platbu zastavíte pomocí Accept.payments.cancel(paymentToken), které vrací výsledný PaymentState.
Vrácení platby
Dokončenou platbu vrátíte pomocí Accept.payments.refund(paymentToken, reason), které rovněž vrací výsledný
PaymentState.
val state: PaymentState = Accept.payments.refund(paymentToken, RefundReason.CUSTOMER_REQUEST)RefundReason je jedna z hodnot CUSTOMER_REQUEST, DUPLICATE, FRAUDULENT nebo EXPIRED_CHARGE.
Zpracování chyb
Platba, která dorazí do terminálu, ale neuspěje, není výjimka; přijde jako
PaymentEvent.Result s PayResult.Declined, Canceled nebo Failed(reason). Selhání, která zabrání
vytvoření platby, přicházejí jako PaymentEvent.CreationFailed(cause), kde cause je typovaná
AcceptException. Výjimky specifické pro tuto integraci:
| Výjimka | Kdy nastane | Co dělat |
|---|---|---|
PluginUnavailable | Plugin Tapaya Terminal není nainstalovaný nebo se nepodařilo navázat spojení s jeho službou. | Vyzvěte k instalaci pomocí Accept.plugin.install(). |
CurrencyNotAvailableForMerchant(code) | Obchodník nemá nastavenou požadovanou měnu. | Účtujte v povolené měně, nebo aktualizujte konfiguraci obchodníka. |
AmountBelowMinimum(minimum, currency) | Částka je pod nastaveným minimem. | Účtujte částku rovnou minimum nebo vyšší. |
TransactionTimeoutOutOfRange(transactionTimeout) | transactionTimeout byl mimo rozsah 0 až 120 sekund. | Předejte hodnotu v povoleném rozsahu, nebo ji vynechte, aby se použila výchozí hodnota. |
LocationPermissionRequired | Vaše aplikace nemá udělené oprávnění k poloze. | Vyžádejte ACCESS_FINE_LOCATION a akci opakujte. |
LocationUnavailable / LocationTimeout | Polohu zařízení se nepodařilo určit. | Požádejte uživatele, aby zapnul polohu, a akci opakujte. |
SessionExpired | Autentizovaná relace vypršela. | Znovu se autentizujte pomocí Accept.auth.authenticate(). |
NoInternetConnection | Není k dispozici síťové připojení. | Požádejte uživatele, aby se znovu připojil, a akci opakujte. |
PaymentInProgress | Předchozí volání pay() stále čeká na výsledek. | Počkejte, až se aktuální platba dokončí. |
Accept.payments.status(), cancel() a refund() jsou funkce suspend a tyto výjimky vyhazují
(místo vysílání událostí); obalte je do try-catch. status()/cancel()/refund() navíc pro neznámý token vyhazují
PaymentNotFound. Úplný seznam najdete v části
Zpracování chyb.
Časové limity
Platbu kartou je nutné na terminálu dokončit krátce po jejím zahájení. Pokud zákazník kartu nikdy nepřiloží nebo se
plugin Tapaya Terminal během platby zavře, platba skončí jako PayResult.Canceled nebo
PayResult.Failed a podkladová platba se na straně serveru zruší a nikdy se nezúčtuje. Než platbu považujete za dokončenou,
vždy si ověřte konečný stav pomocí Accept.payments.status().
Integrace bez SDK
Pokud nemůžete Accept SDK vložit do aplikace (multiplatformní framework, tenký POS shell, webová pokladna), můžete Tapaya Terminal ovládat přímo pomocí deeplinku. Rozdělení práce se tím mění: platbu přes Tapaya API vytváříte vy a vy se také dotazujete na její stav, abyste zjistili výsledek; Tapaya Terminal obstarává jen práci s kartou.
Postup:
- Vytvořte platbu ze svého backendu přes Payments API a uložte si
její
paymentId. - Otevřete Tapaya Terminal s tímto
paymentIdpomocí platebního deeplinku. - Dotazujte se na stav platby přes Payments API, dokud neopustí
stav
PENDING. Deeplinky nemají zpětný kanál, takže dotazování je jediným spolehlivým zdrojem výsledku.
Poznámka
Tapaya Terminal musí být nainstalovaný, přihlášený k účtu obchodníka a nastavený pro měnu platby. V tomto režimu neprobíhá žádná aktivace; obchodníkem odpovědným za transakci (merchant of record) je přihlášený účet. V případě potřeby obchodníka přihlaste pomocí přihlašovacího deeplinku.
Schémata deeplinků
Schéma určuje, které sestavení Tapaya Terminal odkaz obslouží:
| Prostředí | Schéma |
|---|---|
| Produkce | tapaya-accept |
| Sandbox | tapaya-accept-sandbox |
Pokud se odkaz nepodaří otevřít, dané sestavení Tapaya Terminal není nainstalované.
Platební deeplink
tapaya-accept://pay?paymentId=<paymentId>&amount=<amount>¤cy=<ISO4217>| Parametr dotazu | Povinné | Poznámky |
|---|---|---|
paymentId | Ano | Platba vytvořená v kroku 1. |
amount | Ano | Částka v hlavních jednotkách jako celé číslo: amount=15 naúčtuje 15,00. Pozor, tím se liší od SDK, které přijímá nejmenší jednotky. |
currency | Ano | Kód měny ISO 4217, např. CZK. |
val uri = Uri.parse("tapaya-accept://pay?paymentId=$paymentId&amount=15¤cy=CZK")
try {
startActivity(Intent(Intent.ACTION_VIEW, uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
} catch (e: ActivityNotFoundException) {
// Tapaya Terminal is not installed, send the user to Google Play
}Přihlašovací deeplink
Přihlaste obchodníka do Tapaya Terminal pomocí jeho merchantToken, identifikátoru obchodníka, který nastavíte přes POST /merchant/auth/register:
tapaya-accept://login?token=<merchantToken>| Parametr dotazu | Povinné | Poznámky |
|---|---|---|
token | Ano | merchantToken obchodníka. Jde o vaše stabilní ID obchodníka, nikoli o krátkodobý token SDK z POST /merchant/auth/login. |
activationCode | Ne | Předvyplní aktivační kód terminálu. |
Otestování integrace
- Inicializujte s
isProduction = false(výchozí hodnota); platby v sandboxu nikdy nepřesouvají skutečné peníze. - Nainstalujte plugin Tapaya Terminal do testovacího zařízení, přihlaste se testovacím obchodníkem ze sandboxu a proveďte aktivaci.
- Proveďte platbu na malou částku a ověřte celý tok
Successod začátku do konce, včetně vašeho UI účtenky. - Vyzkoušejte cesty selhání: zamítněte platbu na terminálu, jednu zrušte a jednu zahajte v nepodporované
měně; vaše zpracování
PayResult/CreationFailedby mělo pokrýt každou z nich.
Až budete připraveni spustit ostrý provoz, nastavte v initialize hodnotu isProduction = true a autentizujte se produkčními
přihlašovacími údaji. Kód plateb se nemění.