Integrace mobilního SDK
AndroidIntegrujte Tapaya Accept SDK do své mobilní aplikace.
Tapaya Accept SDK vkládá zpracování plateb kartou přímo do vaší aplikace. Je k dispozici pro Android (Kotlin) a pro React Native / Expo, přičemž obě varianty cílí na zařízení s Androidem. Balíček pro React Native je tenká vrstva nad Android SDK, takže rozhraní, typy a chybové stavy popsané níže jsou v obou variantách stejné.
Každá ukázka kódu na této stránce má záložky podle jazyka. Vyberte jeden a celá stránka se přizpůsobí.
Instalace
dependencies {
implementation("com.tapaya:accept:1.15.0")
}Android: přidejte závislost do souboru build.gradle.kts na úrovni modulu a poté projekt synchronizujte.
React Native: nainstalujte balíček příkazem npx expo install @tapayadot/accept-react-native, přidejte konfigurační plugin podle
ukázky, poté nativní projekt znovu vygenerujte příkazem npx expo prebuild --clean a spusťte jej příkazem
npx expo run:android.
Inicializace
Accept je vstupním bodem ke všem funkcím SDK. Inicializujte jej jednou při spuštění aplikace (na Androidu
obvykle ve třídě Application) a poté se samostatně autentizujte tokenem obchodníka.
Krok 1: Inicializace
// 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)V React Native se context nepředává; drží jej za vás nativní modul.
Krok 2: Autentizace
Po inicializaci zavolejte Accept.auth.authenticate() a přihlaste obchodníka tokenem získaným z vašeho
backendu. Volání je asynchronní a při selhání skončí chybou SDK. Po úspěšné autentizaci se stav SDK změní na authenticated.
// 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
}Sledujte životní cyklus, abyste mohli reagovat na tyto přechody: idle → initialized → authenticated.
// Accept.state is a StateFlow<SdkState>
Accept.state.collect { state ->
if (state == SdkState.Authenticated) loadMerchant()
}Základní koncepty
Objekt Accept zpřístupňuje SDK prostřednictvím několika rozhraní:
| Rozhraní | Účel |
|---|---|
Accept.auth | Autentizace relace obchodníka. |
Accept.merchant | Profil obchodníka, konfigurace, stav onboardingu. |
Accept.payments | Vytváření a správa plateb kartou. |
Accept.plugin | Instalace a aktivace terminálu (pluginové aplikace). |
Accept.displays | Informace o displejích zařízení pro oboustranné terminály („double-sided“). |
Accept.sdk | Verze SDK, prostředí, ID zařízení, minimální částky. |
Accept.state | Stav životního cyklu: StateFlow<SdkState> v Kotlinu, getter a addStateListener() v React Native. |
Přijetí platby
Zavolejte Accept.payments.pay() s částkou (v nejmenší jednotce měny) a kódem měny podle ISO 4217 a poté
sledujte proud událostí PaymentEvent, které metoda hlásí: nejprve průběh, pak konečný výsledek. pay() nikdy
nevyhazuje výjimku; selhání při vytváření platby místo toho přijde jako událost CreationFailed.
Liší se jen způsob, jakým tento proud sledujete: Kotlin vrací Flow<PaymentEvent>, který sbíráte
v korutině, kdežto React Native přijímá listener a vrací odběr, který můžete zrušit metodou remove().
amount a currency jsou povinné. Volitelné parametry (paymentToken, receiptConfig, nfcPosition,
metadata, tip, transactionTimeout, display) popisuje Vytvoření platby.
V React Native
Tytéž parametry se předávají jako jediný objekt PaymentRequest, pay({ amount, currency, tip, … }), s
number místo Long a Record<string, string> místo Map<String, String>. Jeden parametr se jmenuje jinak:
časový limit je transactionTimeoutMs a přijímá prosté milisekundy (0…120000) místo Duration.

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())
}
}Konečná událost s výsledkem nese PayResult: úspěch (s paymentToken, metadata, authCode,
receiptDetails), zamítnutí (metadata, receiptDetails), zrušení (metadata) nebo selhání (reason,
metadata). Kotlin je modeluje jako podtřídy PayResult.Success / Declined / Canceled / Failed;
React Native jako diskriminované sjednocení, ve kterém větvíte podle payResult.type === 'success'. Úplný
rozpis najdete v části Výsledek platby. Stav platby můžete později zjistit pomocí
Accept.payments.status(paymentToken), zastavit ji pomocí Accept.payments.cancel(paymentToken) nebo ji vrátit pomocí
Accept.payments.refund(paymentToken, reason).
Pouze výsledek (React Native)
Pokud vaše UI nezobrazuje mezistavy, payAsync() zredukuje celý proud na konečný
PayResult a ve všech případech, které by pay() ohlásila jako creationFailed,
odmítne promise s chybou AcceptError. V Kotlinu nemá obdobu; tam sbírejte Flow, nebo si vezměte jen jeho poslední událost.
const result = await Accept.payments.payAsync({ amount: 15000, currency: 'CZK' });
if (result.type === 'success') {
console.log(result.paymentToken, result.receiptUrl);
}Informace o obchodníkovi a SDK
Accept.merchant zpřístupňuje profil a platební konfiguraci přihlášeného obchodníka. Accept.sdk poskytuje
údaje o sestavení SDK a o tomto zařízení. Každý z níže uvedených členů vyžaduje předchozí volání Accept.initialize() (kromě
Accept.sdk.version) a vše na Accept.merchant navíc vyžaduje dokončené
Accept.auth.authenticate(), jinak volání vyhodí NotInitialized nebo NotAuthenticated.
Obchodník
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| Člen | Vrací | Popis |
|---|---|---|
info() | MerchantInformation? | Registrovaný firemní profil obchodníka. null, pokud profil zatím není k dispozici. |
config() | MerchantConfig | Platební konfigurace obchodníka. |
availableCurrencies() | List<String> | Kódy ISO 4217, ve kterých může obchodník přijímat platby. Zkratka pro config().availableCurrencies. |
onboardingStatus() | OnboardingStatus | Zda už obchodník smí přijímat platby. |
Všechny čtyři jsou suspend a při selhání vyhazují NotAuthenticated, NoInternetConnection nebo Unknown.
MerchantInformation nese registrovaný firemní profil. Vždy obsahuje: merchantId (UUID),
email, businessType (BusinessType), legalName, registrationNumber, mcc a registrovanou adresu
(addressLine1, city, country). Volitelně (null, pokud je obchodník nevyplnil): vatNumber,
incorporationDate, addressLine2, postalCode, state, phone, averageItemValue,
expectedMonthlyTurnover, businessModelDescription, numberOfEmployees, annualTurnover,
balanceSheetTotal, statementDescriptor, termsVersion.
BusinessType nabývá jedné z hodnot INDIVIDUAL, COMPANY, NONPROFIT_ORGANIZATION, GOVERNMENT_ENTITY nebo
PARTNERSHIP.
MerchantConfig obsahuje availableCurrencies: List<String> a výchozí měnu obchodníka currency: String?.
OnboardingStatus je sealed interface: buď ReadyForPayments, nebo RequiresAction(state), kde
state je OnboardingState: NOT_STARTED, PENDING, ACTIVE, ATTENTION_NEEDED, ACTION_REQUIRED,
BLOCKED, WAITING_FOR_KYB, WAITING_FOR_STAKEHOLDERS nebo PENDING_ACQUIRER_APPROVAL. Co jednotlivé stavy
znamenají, popisuje Onboarding obchodníků.
SDK
Accept.sdk.version // String, e.g. "1.15.0"
Accept.sdk.isProduction // Boolean
Accept.sdk.deviceId() // String? (suspend)
Accept.sdk.minimumAmounts() // List<MinimumAmount> (suspend)| Člen | Vrací | Popis |
|---|---|---|
version | String | Verze SDK. Lze ji číst ještě před initialize(). |
isProduction | Boolean | Zda initialize() cílilo na produkci (true), nebo na sandbox (false). |
deviceId() | String? | Stálé ID tohoto zařízení, přidělené při prvním úspěšném authenticate() a zachované až do odinstalace aplikace. Do té doby null. Uvádějte jej v žádostech o podporu. |
minimumAmounts() | List<MinimumAmount> | Minimální částka platby pro každou podporovanou měnu. Každá položka je currency: String, amount: Long v nejmenší jednotce měny. |
Pluginová aplikace
Každá platba kartou se předává aplikaci Tapaya Terminal, pluginové aplikaci Tapaya; ta je vždy nutná a neexistuje žádný způsob platby kartou, který by ji obešel. Ověřte, zda je nainstalovaná, a poté aktivujte terminál, nebo otevřete stránku aplikace v obchodě, aby si ji obchodník mohl nainstalovat.
K tomu slouží Accept.plugin.isInstalled(), Accept.plugin.activateTerminal() a Accept.plugin.install(). Kód
a všechny možné výsledky aktivace najdete v části Instalace a aktivace terminálu.
Aktuální stav pluginu zjistíte pomocí Accept.plugin.status() a obchodníka z pluginu odhlásíte pomocí
Accept.plugin.logout().
Oprávnění
Platby kartou vyžadují, aby hostitelská aplikace měla oprávnění k poloze (ACCESS_FINE_LOCATION). SDK si o něj
nežádá samo; před voláním pay() zajistěte jeho udělení pomocí standardních API pro oprávnění v Androidu.
class PaymentActivity : AppCompatActivity() {
private val requestLocation = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { granted ->
if (granted) launchPaymentFlow() else showPermissionRationale()
}
fun startPayment() {
requestLocation.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
}Pokud v okamžiku spuštění pay() chybí poloha nebo ji nelze zjistit, proud vyšle PaymentEvent.CreationFailed
s příčinou LocationPermissionRequired, LocationUnavailable nebo LocationTimeout.
Zpracování chyb
Každé ošetřované selhání nese jeden z níže uvedených názvů. V Kotlinu je každé z nich podtřídou sealed třídy
AcceptException; v React Native jde vždy o jedinou třídu AcceptError, jejíž code obsahuje název, a
pole s doplňujícími údaji (minimum, currency, state, …) jsou přímo na témže objektu.
Asynchronní volání (authenticate, merchant.*, payments.status/cancel/refund,
plugin.activateTerminal/status/logout/updateInfo, clear) selhávají s jedním z nich. Výjimkou je
payments.pay(): nikdy nevyhazuje výjimku a stejná selhání hlásí jako událost CreationFailed nesoucí příčinu.
Typy výjimek
| Výjimka | Popis |
|---|---|
| Životní cyklus | |
NotInitialized | Volání vyžaduje předchozí Accept.initialize(). |
NotAuthenticated | Volání vyžaduje předchozí Accept.auth.authenticate(). |
SessionExpired | Platnost autentizované relace vypršela; znovu se autentizujte. |
UnknownEnvironment(key) | Klíč prostředí nebyl rozpoznán (interní přetížení metody initialize). |
| Platby | |
PaymentInProgress | Předchozí pay() stále čeká na výsledek. |
CurrencyNotAvailableForMerchant(code) | Měna není pro obchodníka nakonfigurována. |
UnsupportedCurrency(code) | SDK měnu nerozpoznalo. |
AmountBelowMinimum(minimum, currency) | Částka je nižší než nakonfigurované minimum. |
TransactionTimeoutOutOfRange(transactionTimeout) | transactionTimeout je mimo rozsah 0 až 120 sekund. |
PaymentCreationFailed(cause) | Jakékoli jiné selhání při vytváření platby. |
PaymentNotFound | Token pro status()/cancel()/refund() backend nezná. |
| Poloha | |
LocationPermissionRequired | Hostitelská aplikace nemá oprávnění k poloze. |
LocationUnavailable | Žádný poskytovatel nedokázal určit polohu. |
LocationTimeout | Poloha nebyla určena včas. |
| Plugin / terminál | |
PluginUnavailable | Pluginová aplikace není nainstalovaná nebo se nepodařilo připojit k její službě. |
PluginTimeout | Plugin neodpověděl včas. |
ActivationInProgress | Předchozí activateTerminal() stále čeká na výsledek. |
NoTidsAvailableForMerchant | Obchodníkovi nezbyl žádný nepřiřazený terminál (TID) k aktivaci. |
PluginAlreadyAuthenticated | Plugin je pro tohoto obchodníka již autentizován. |
PluginMerchantMismatch | Plugin je autentizován pod jiným obchodníkem; nejprve zavolejte plugin.logout(). |
PluginNotReadyForPayments(status) | pay() bylo spuštěno, když plugin nebyl ve stavu PluginStatus.ReadyForPayments; status nese aktuální stav. |
MerchantOnboardingIncomplete(state) | Obchodník nedokončil onboarding. |
| Systém | |
NoInternetConnection | Zařízení nemá připojení k síti. |
Unknown(cause) | Jakékoli selhání, které SDK nerozpozná jako vlastní. |
Výsledek vs. výjimka
Platba, která dorazí do terminálu, ale neproběhne úspěšně, není výjimka; přijde jako
PaymentEvent.Result s PayResult.Declined, Canceled nebo Failed(reason). Obdobně aktivace
terminálu hlásí ActivateTerminalResult.Failed(reason).
Ošetření výjimek
Obalte volání blokem try/catch, větvěte podle konkrétních případů, které ošetřujete, a pro ostatní použijte obecné zachycení.
Kotlin větví podle podtřídy výjimky; React Native ověřuje pomocí AcceptError.is() a větví podle code.
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}")
}Logování
Během vývoje zapněte ladicí logování, abyste mohli řešit problémy.
Accept.setDebugLoggingEnabled(true)Odhlášení
Vymažte veškerý lokálně uložený stav SDK (autentizační token, ID zařízení, konfiguraci v mezipaměti) a vraťte stav SDK zpět na
idle. Volejte to při odhlášení uživatele. Chcete-li obchodníka odhlásit i z aplikace Tapaya Terminal, zavolejte
nejprve Accept.plugin.logout().
Accept.plugin.logout() // suspend; signs out of the Tapaya Terminal app
Accept.clear() // suspend; clears local SDK state