# Integrácia mobilného SDK (/sk/in-store/integration/sdk_integration)





Tapaya Accept SDK vkladá spracovanie platieb kartou priamo do vašej aplikácie. Je dostupné pre &#x2A;*Android
(Kotlin)** a pre **React Native / Expo** a obe verzie sú určené pre zariadenia s Androidom. Balík pre React Native je
tenká vrstva nad Android SDK, takže rozhrania, typy a chybové prípady uvedené nižšie sú v oboch rovnaké.

Každá ukážka kódu na tejto stránke má karty pre jednotlivé jazyky. Keď jeden vyberiete, prepne sa naň celá stránka.

## Inštalácia [#installation]

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin title="build.gradle.kts"
    dependencies {
        implementation("com.tapaya:accept:1.15.0")
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```json title="app.json"
    {
      "expo": {
        "plugins": ["@tapayadot/accept-react-native"]
      }
    }
    ```
  </CodeBlockTab>
</CodeBlockTabs>

**Android:** pridajte závislosť do súboru `build.gradle.kts` na úrovni modulu a potom synchronizujte projekt.

**React Native:** nainštalujte balík príkazom `npx expo install @tapayadot/accept-react-native`, pridajte konfiguračný plugin podľa
ukážky, potom pregenerujte natívny projekt príkazom `npx expo prebuild --clean` a spustite ho príkazom
`npx expo run:android`.

## Inicializácia [#initialization]

`Accept` je vstupný bod pre všetky funkcie SDK. Inicializujte ho raz pri spustení aplikácie (na Androide
zvyčajne vo vašej triede `Application`) a potom sa samostatne autentifikujte tokenom obchodníka.

### Krok 1: Inicializácia [#step-1-initialize]

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    // Sandbox is the default (isProduction = false)
    Accept.initialize(context = this)

    // Target production explicitly
    Accept.initialize(context = this, isProduction = true)

    // Or drive it from your build type
    Accept.initialize(context = this, isProduction = !BuildConfig.DEBUG)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    import Accept from '@tapayadot/accept-react-native';

    // Sandbox is the default
    Accept.initialize();

    // Target production explicitly
    Accept.initialize({ isProduction: true });

    // Or drive it from your build
    Accept.initialize({ isProduction: !__DEV__ });
    ```
  </CodeBlockTab>
</CodeBlockTabs>

V React Native sa `context` neodovzdáva; drží ho za vás natívny modul.

### Krok 2: Autentifikácia [#step-2-authenticate]

Po inicializácii zavolajte `Accept.auth.authenticate()`, aby ste prihlásili obchodníka pomocou tokenu získaného z vášho
backendu. Volanie je asynchrónne a pri zlyhaní skončí chybou SDK. Pri úspechu sa stav SDK zmení na *authenticated*.

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    // suspend; call from a coroutine
    try {
        val sdkToken = myBackendApi.getSdkToken()
        Accept.auth.authenticate(sdkToken)
        // Accept.state now emits SdkState.Authenticated
    } catch (e: AcceptException) {
        // handle authentication failure
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    try {
        const sdkToken = await myBackendApi.getSdkToken();
        await Accept.auth.authenticate(sdkToken);
        // Accept.state is now 'authenticated'
    } catch (error) {
        // handle authentication failure
    }
    ```
  </CodeBlockTab>
</CodeBlockTabs>

Sledujte životný cyklus, aby ste mohli reagovať na tieto prechody: `idle → initialized → authenticated`.

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    // Accept.state is a StateFlow<SdkState>
    Accept.state.collect { state ->
        if (state == SdkState.Authenticated) loadMerchant()
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    // Accept.state is a plain getter; subscribe for changes
    const subscription = Accept.addStateListener((state) => {
        if (state === 'authenticated') loadMerchant();
    });

    // later
    subscription.remove();
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## Základné koncepty [#core-concepts]

Objekt `Accept` sprístupňuje SDK prostredníctvom niekoľkých rozhraní:

| Rozhranie         | Účel                                                                                                 |
| :---------------- | :--------------------------------------------------------------------------------------------------- |
| `Accept.auth`     | Autentifikácia relácie obchodníka.                                                                   |
| `Accept.merchant` | Profil obchodníka, konfigurácia, stav onboardingu.                                                   |
| `Accept.payments` | Vytváranie a správa platieb kartou.                                                                  |
| `Accept.plugin`   | Inštalácia a aktivácia terminálu (pluginovej aplikácie).                                             |
| `Accept.displays` | Informácie o displejoch zariadenia pre obojstranné terminály (s displejom na oboch stranách).        |
| `Accept.sdk`      | Verzia SDK, prostredie, ID zariadenia, minimálne sumy.                                               |
| `Accept.state`    | Stav životného cyklu: v Kotline `StateFlow<SdkState>`, v React Native getter a `addStateListener()`. |

### Prijatie platby [#taking-a-payment]

Zavolajte `Accept.payments.pay()` so sumou (v najmenšej jednotke meny) a kódom meny podľa ISO 4217 a potom
sledujte prúd udalostí `PaymentEvent`, ktoré hlási: najprv priebeh, potom konečný výsledok. `pay()` nikdy
nevyhadzuje výnimku; zlyhanie pri vytváraní platby namiesto toho príde ako udalosť `CreationFailed`.

Jediné, čím sa verzie líšia, je spôsob sledovania tohto prúdu: Kotlin vracia `Flow<PaymentEvent>`, ktorý odoberáte (collect)
v korutine, zatiaľ čo React Native prijíma listener a vracia odber (subscription), ktorý môžete zrušiť cez `remove()`.

`amount` a `currency` sú povinné. Voliteľné parametre (`paymentToken`, `receiptConfig`, `nfcPosition`,
`metadata`, `tip`, `transactionTimeout`, `display`) nájdete v časti [Vytvorenie platby](./card_terminal#create-a-payment).

<Callout title="V React Native" type="info">
  Rovnaké parametre sa odovzdávajú ako jeden objekt `PaymentRequest`, `pay({ amount, currency, tip, … })`, pričom
  sa používa `number` namiesto `Long` a `Record<string, string>` namiesto `Map<String, String>`. Jeden parameter je premenovaný:
  časový limit je `transactionTimeoutMs` a namiesto hodnoty `Duration` prijíma obyčajné milisekundy (`0`…`120000`).
</Callout>

<div className="bg-background relative h-auto w-full overflow-hidden rounded-lg border px-10">
    <img alt="Priebeh platby" src="__img0" />
</div>

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    Accept.payments.pay(amount = 15000, currency = "CZK") // 150.00 Kč
        .collect { event ->
            when (event) {
                PaymentEvent.Creating -> Log.d("pay", "creating")
                is PaymentEvent.Created -> Log.d("pay", "created ${event.paymentToken}")
                PaymentEvent.Launched -> Log.d("pay", "launched")
                is PaymentEvent.Result -> Log.d("pay", event.payResult.toString())
                is PaymentEvent.CreationFailed -> Log.e("pay", event.cause.toString())
            }
        }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    const subscription = Accept.payments.pay(
        { amount: 15000, currency: 'CZK' }, // 150.00 Kč
        (event) => {
            switch (event.type) {
                case 'creating':
                    setStatus('Creating payment…');
                    break;
                case 'created':
                    // The payment token and receipt URL exist before the plugin is launched.
                    setReceiptUrl(event.receiptUrl);
                    break;
                case 'launched':
                    setStatus('Waiting for the card…');
                    break;
                case 'result':
                    setResult(event.payResult);
                    break;
                case 'creationFailed':
                    setError(event.error); // the payment never started
                    break;
            }
        },
    );

    // The stream ends itself after `result` or `creationFailed`.
    // Call subscription.remove() only to stop listening early.
    ```
  </CodeBlockTab>
</CodeBlockTabs>

Udalosť s konečným výsledkom nesie `PayResult`: úspech (s `paymentToken`, `metadata`, `authCode`,
`receiptDetails`), zamietnutie (`metadata`, `receiptDetails`), zrušenie (`metadata`) alebo zlyhanie (`reason`,
`metadata`). Kotlin ich modeluje ako podtriedy `PayResult.Success` / `Declined` / `Canceled` / `Failed`;
React Native ako discriminated union, v ktorom vetvíte podľa `payResult.type === 'success'`. Úplný prehľad nájdete v časti
[Výsledok platby](./card_terminal#payment-outcome). Stav platby môžete neskôr zistiť cez
`Accept.payments.status(paymentToken)`, platbu zastaviť cez `Accept.payments.cancel(paymentToken)` alebo ju vrátiť cez
`Accept.payments.refund(paymentToken, reason)`.

#### Iba výsledok (React Native) [#just-the-outcome-react-native]

Ak vaše UI nevykresľuje priebežné stavy, `payAsync()` zredukuje celý prúd na jeho konečný
`PayResult` a pri všetkom, čo by `pay()` nahlásilo ako `creationFailed`, odmietne promise (reject)
s chybou `AcceptError`. V Kotline nemá obdobu; tam odoberajte `Flow` alebo si vezmite iba jeho poslednú udalosť.

```typescript
const result = await Accept.payments.payAsync({ amount: 15000, currency: 'CZK' });
if (result.type === 'success') {
    console.log(result.paymentToken, result.receiptUrl);
}
```

## Informácie o obchodníkovi a SDK [#merchant--sdk-info]

`Accept.merchant` sprístupňuje profil a platobnú konfiguráciu prihláseného obchodníka. `Accept.sdk` sprístupňuje
údaje o zostavení SDK a o tomto zariadení. Každý člen uvedený nižšie vyžaduje najprv `Accept.initialize()` (okrem
`Accept.sdk.version`) a všetko na `Accept.merchant` navyše vyžaduje dokončené
`Accept.auth.authenticate()`, inak volanie vyhodí `NotInitialized` alebo `NotAuthenticated`.

### Obchodník [#merchant]

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    val info = Accept.merchant.info()                      // MerchantInformation?
    val config = Accept.merchant.config()                  // MerchantConfig
    val currencies = Accept.merchant.availableCurrencies() // List<String>
    val status = Accept.merchant.onboardingStatus()        // OnboardingStatus
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    const info = await Accept.merchant.info();                      // MerchantInformation | null
    const config = await Accept.merchant.config();                  // MerchantConfig
    const currencies = await Accept.merchant.availableCurrencies(); // string[]
    const status = await Accept.merchant.onboardingStatus();        // OnboardingStatus
    ```
  </CodeBlockTab>
</CodeBlockTabs>

| Člen                    | Vracia                 | Popis                                                                                     |
| :---------------------- | :--------------------- | :---------------------------------------------------------------------------------------- |
| `info()`                | `MerchantInformation?` | Registrovaný firemný profil obchodníka. `null`, ak profil ešte nie je k dispozícii.       |
| `config()`              | `MerchantConfig`       | Platobná konfigurácia obchodníka.                                                         |
| `availableCurrencies()` | `List<String>`         | Kódy ISO 4217, ktoré obchodník môže prijímať. Skratka pre `config().availableCurrencies`. |
| `onboardingStatus()`    | `OnboardingStatus`     | Či obchodník už môže prijímať platby.                                                     |

Všetky štyri sú `suspend` a pri zlyhaní vyhadzujú `NotAuthenticated`, `NoInternetConnection` alebo `Unknown`.

**`MerchantInformation`** nesie registrovaný firemný profil. Vždy prítomné: `merchantId` (`UUID`),
`email`, `businessType` (`BusinessType`), `legalName`, `registrationNumber`, `mcc` a registrovaná adresa
(`addressLine1`, `city`, `country`). Voliteľné (`null`, pokiaľ ich obchodník nezadal): `vatNumber`,
`incorporationDate`, `addressLine2`, `postalCode`, `state`, `phone`, `averageItemValue`,
`expectedMonthlyTurnover`, `businessModelDescription`, `numberOfEmployees`, `annualTurnover`,
`balanceSheetTotal`, `statementDescriptor`, `termsVersion`.

`BusinessType` je jedna z hodnôt `INDIVIDUAL`, `COMPANY`, `NONPROFIT_ORGANIZATION`, `GOVERNMENT_ENTITY` alebo
`PARTNERSHIP`.

**`MerchantConfig`** obsahuje `availableCurrencies: List<String>` a predvolenú menu obchodníka `currency: String?`.

**`OnboardingStatus`** je sealed interface: buď `ReadyForPayments`, alebo `RequiresAction(state)`, kde
`state` je `OnboardingState`: `NOT_STARTED`, `PENDING`, `ACTIVE`, `ATTENTION_NEEDED`, `ACTION_REQUIRED`,
`BLOCKED`, `WAITING_FOR_KYB`, `WAITING_FOR_STAKEHOLDERS` alebo `PENDING_ACQUIRER_APPROVAL`. Čo jednotlivé stavy znamenajú,
nájdete v časti [Onboarding obchodníkov](/merchants/onboarding).

### SDK [#sdk]

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    Accept.sdk.version            // String, e.g. "1.15.0"
    Accept.sdk.isProduction       // Boolean
    Accept.sdk.deviceId()         // String?  (suspend)
    Accept.sdk.minimumAmounts()   // List<MinimumAmount>  (suspend)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    Accept.sdk.version                  // string, e.g. "1.15.0"
    Accept.sdk.isProduction             // boolean
    await Accept.sdk.deviceId()         // string | null
    await Accept.sdk.minimumAmounts()   // MinimumAmount[]
    ```
  </CodeBlockTab>
</CodeBlockTabs>

| Člen               | Vracia                | Popis                                                                                                                                                                           |
| :----------------- | :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `version`          | `String`              | Verzia SDK. Dá sa prečítať aj pred `initialize()`.                                                                                                                              |
| `isProduction`     | `Boolean`             | Či `initialize()` cielilo na produkciu (`true`), alebo na sandbox (`false`).                                                                                                    |
| `deviceId()`       | `String?`             | Stabilné ID tohto zariadenia, pridelené pri prvom úspešnom `authenticate()` a zachované až do odinštalovania aplikácie. Dovtedy `null`. Uvádzajte ho v požiadavkách na podporu. |
| `minimumAmounts()` | `List<MinimumAmount>` | Minimálna suma platby pre každú podporovanú menu. Každá položka je `currency: String, amount: Long` v najmenšej jednotke meny.                                                  |

## Pluginová aplikácia [#plugin-app]

Každá platba kartou sa odovzdáva aplikácii **Tapaya Terminal**, pluginovej aplikácii Tapaya; je vždy povinná, neexistuje
žiadna cesta platby kartou, ktorá by ju obišla. Skontrolujte, či je nainštalovaná, a potom aktivujte terminál, alebo otvorte jej stránku
v obchode, aby ju obchodník mohol nainštalovať.

Použite na to `Accept.plugin.isInstalled()`, `Accept.plugin.activateTerminal()` a `Accept.plugin.install()`. Kód a všetky
výsledky aktivácie nájdete v časti [Inštalácia a aktivácia terminálu](./card_terminal#install-and-activate-the-terminal).

Aktuálny stav pluginu zistíte cez `Accept.plugin.status()` a obchodníka z pluginu odhlásite cez
`Accept.plugin.logout()`.

## Oprávnenia [#permissions]

Platby kartou vyžadujú, aby hostiteľská aplikácia mala oprávnenie na prístup k polohe (`ACCESS_FINE_LOCATION`). SDK oň
nežiada za vás; pred volaním `pay()` ho získajte pomocou štandardných API pre oprávnenia v Androide.

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    class PaymentActivity : AppCompatActivity() {
        private val requestLocation = registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { granted ->
            if (granted) launchPaymentFlow() else showPermissionRationale()
        }

        fun startPayment() {
            requestLocation.launch(Manifest.permission.ACCESS_FINE_LOCATION)
        }
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    import { PermissionsAndroid } from 'react-native';

    const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
    );

    if (granted === PermissionsAndroid.RESULTS.GRANTED) launchPaymentFlow();
    else showPermissionRationale();
    ```
  </CodeBlockTab>
</CodeBlockTabs>

Ak poloha chýba alebo ju nie je možné zistiť v čase spustenia `pay()`, prúd vyšle `PaymentEvent.CreationFailed`
s príčinou `LocationPermissionRequired`, `LocationUnavailable` alebo `LocationTimeout`.

## Spracovanie chýb [#error-handling]

Každé ošetrené zlyhanie nesie jeden z názvov uvedených nižšie. V Kotline je každé podtriedou sealed triedy
`AcceptException`; v React Native ide vždy o jedinú triedu `AcceptError`, ktorej `code` obsahuje názov a
polia s údajmi (`minimum`, `currency`, `state`, …) sú na tom istom objekte.

Asynchrónne volania (`authenticate`, `merchant.*`, `payments.status`/`cancel`/`refund`,
`plugin.activateTerminal`/`status`/`logout`/`updateInfo`, `clear`) zlyhávajú s jedným z nich. Výnimkou je
`payments.pay()`: nikdy nevyhadzuje výnimku a tie isté zlyhania hlási ako udalosť `CreationFailed` s príčinou.

### Typy výnimiek [#exception-types]

| Výnimka                                            | Popis                                                                                                        |
| :------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- |
| **Životný cyklus**                                 |                                                                                                              |
| `NotInitialized`                                   | Volanie vyžaduje najprv `Accept.initialize()`.                                                               |
| `NotAuthenticated`                                 | Volanie vyžaduje najprv `Accept.auth.authenticate()`.                                                        |
| `SessionExpired`                                   | Platnosť autentifikovanej relácie vypršala; znova sa autentifikujte.                                         |
| `UnknownEnvironment(key)`                          | Kľúč prostredia nebol rozpoznaný (interné preťaženie metódy initialize).                                     |
| **Platby**                                         |                                                                                                              |
| `PaymentInProgress`                                | Predchádzajúce volanie `pay()` stále čaká na výsledok.                                                       |
| `CurrencyNotAvailableForMerchant(code)`            | Mena nie je pre obchodníka nakonfigurovaná.                                                                  |
| `UnsupportedCurrency(code)`                        | SDK menu nerozpoznáva.                                                                                       |
| `AmountBelowMinimum(minimum, currency)`            | Suma je pod nakonfigurovaným minimom.                                                                        |
| `TransactionTimeoutOutOfRange(transactionTimeout)` | `transactionTimeout` je mimo rozsahu 0 až 120 sekúnd.                                                        |
| `PaymentCreationFailed(cause)`                     | Akékoľvek iné zlyhanie pri vytváraní platby.                                                                 |
| `PaymentNotFound`                                  | Backend nepozná token zadaný v `status()`/`cancel()`/`refund()`.                                             |
| **Poloha**                                         |                                                                                                              |
| `LocationPermissionRequired`                       | Hostiteľská aplikácia nemá oprávnenie na prístup k polohe.                                                   |
| `LocationUnavailable`                              | Žiadny poskytovateľ polohy nedokázal určiť polohu.                                                           |
| `LocationTimeout`                                  | Poloha nebola určená včas.                                                                                   |
| **Plugin / terminál**                              |                                                                                                              |
| `PluginUnavailable`                                | Pluginová aplikácia nie je nainštalovaná alebo sa nepodarilo pripojiť k jej službe.                          |
| `PluginTimeout`                                    | Plugin neodpovedal včas.                                                                                     |
| `ActivationInProgress`                             | Predchádzajúce volanie `activateTerminal()` stále čaká na výsledok.                                          |
| `NoTidsAvailableForMerchant`                       | Obchodníkovi nezostal žiadny nepridelený terminál (TID) na aktiváciu.                                        |
| `PluginAlreadyAuthenticated`                       | Plugin je už autentifikovaný pre tohto obchodníka.                                                           |
| `PluginMerchantMismatch`                           | Plugin je autentifikovaný pod iným obchodníkom; najprv zavolajte `plugin.logout()`.                          |
| `PluginNotReadyForPayments(status)`                | `pay()` sa spustilo, keď plugin nebol v stave `PluginStatus.ReadyForPayments`; `status` nesie aktuálny stav. |
| `MerchantOnboardingIncomplete(state)`              | Obchodník nedokončil onboarding.                                                                             |
| **Systém**                                         |                                                                                                              |
| `NoInternetConnection`                             | Zariadenie nemá pripojenie k sieti.                                                                          |
| `Unknown(cause)`                                   | Akékoľvek zlyhanie, ktoré SDK nerozpozná ako jedno z vlastných.                                              |

<Callout title="Výsledok vs. výnimka" type="info">
  Platba, ktorá sa dostane na terminál, ale neuspeje, **nie je** výnimkou; príde ako
  `PaymentEvent.Result` s `PayResult.Declined`, `Canceled` alebo `Failed(reason)`. Podobne aj aktivácia
  terminálu hlási `ActivateTerminalResult.Failed(reason)`.
</Callout>

### Ošetrenie výnimiek [#handling-exceptions]

Volanie obaľte do `try`/`catch`, vetvite podľa konkrétnych prípadov, ktoré ošetrujete, a ostatné zachyťte všeobecným catch.
Kotlin vetví podľa podtriedy výnimky; React Native overuje typ cez `AcceptError.is()` a vetví podľa `code`.

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    try {
        val status = Accept.payments.status(paymentToken)
    } catch (e: SessionExpired) {
        // Re-authenticate
    } catch (e: NoInternetConnection) {
        // Ask the user to check connectivity
    } catch (e: AcceptException) {
        // Handle any other SDK error
        Log.e("Payment", "Error: ${e.message}")
    }
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    import Accept, { AcceptError } from '@tapayadot/accept-react-native';

    try {
        const status = await Accept.payments.status(paymentToken);
    } catch (error) {
        if (!AcceptError.is(error)) throw error;

        switch (error.code) {
            case 'SessionExpired':
                // Re-authenticate
                break;
            case 'NoInternetConnection':
                // Ask the user to check connectivity
                break;
            case 'AmountBelowMinimum':
                // Payload fields sit on the error itself
                alert(`Minimum is ${error.minimum} ${error.currency}`);
                break;
            default:
                throw error;
        }
    }
    ```
  </CodeBlockTab>
</CodeBlockTabs>

### Logovanie [#logging]

Počas vývoja zapnite ladiace logovanie, aby ste mohli riešiť problémy.

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    Accept.setDebugLoggingEnabled(true)
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    Accept.setDebugLoggingEnabled(true);
    ```
  </CodeBlockTab>
</CodeBlockTabs>

### Odhlásenie [#logging-out]

Vymažte všetok lokálne uložený stav SDK (autentifikačný token, ID zariadenia, konfiguráciu vo vyrovnávacej pamäti) a vráťte stav SDK späť na
*idle*. Toto volanie použite pri odhlásení používateľa. Ak chcete obchodníka odhlásiť aj z aplikácie Tapaya Terminal, najprv zavolajte
`Accept.plugin.logout()`.

<CodeBlockTabs defaultValue="kotlin" groupId="accept-language">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="kotlin">
      Android (Kotlin)
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="typescript">
      React Native (TypeScript)
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="kotlin">
    ```kotlin
    Accept.plugin.logout() // suspend; signs out of the Tapaya Terminal app
    Accept.clear()         // suspend; clears local SDK state
    ```
  </CodeBlockTab>

  <CodeBlockTab value="typescript">
    ```typescript
    await Accept.plugin.logout(); // signs out of the Tapaya Terminal app
    await Accept.clear();         // clears local SDK state
    ```
  </CodeBlockTab>
</CodeBlockTabs>
