Tapaya
Zahlungsannahme vor OrtIntegrationsleitfadenIntegration des mobilen SDK

Integration des mobilen SDK

Android

Integrieren Sie das Tapaya Accept SDK in Ihre mobile Anwendung.

Das Tapaya Accept SDK bettet die Verarbeitung von Kartenzahlungen direkt in Ihre App ein. Es steht für Android (Kotlin) und für React Native / Expo zur Verfügung, und beide Varianten zielen auf Android-Geräte. Das React-Native-Paket ist ein schlanker Wrapper um das Android SDK, daher sind die unten beschriebenen Schnittstellen, Typen und Fehlerfälle in beiden Varianten gleich.

Jedes Codebeispiel auf dieser Seite ist nach Sprache in Tabs gegliedert. Wählen Sie eine Sprache aus, und die gesamte Seite passt sich an.

Installation

build.gradle.kts
dependencies {
    implementation("com.tapaya:accept:1.15.0")
}

Android: Fügen Sie die Abhängigkeit zur build.gradle.kts auf Modulebene hinzu und synchronisieren Sie dann das Projekt.

React Native: Installieren Sie das Paket mit npx expo install @tapayadot/accept-react-native, fügen Sie das Config-Plugin wie gezeigt hinzu, erzeugen Sie dann das native Projekt mit npx expo prebuild --clean neu und starten Sie es mit npx expo run:android.

Initialisierung

Accept ist der Einstiegspunkt für alle Funktionen des SDK. Initialisieren Sie es einmal beim Start der App (unter Android typischerweise in Ihrer Application-Klasse) und authentifizieren Sie sich anschließend separat mit einem Händler-Token.

Schritt 1: Initialisieren

// 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)

Unter React Native gibt es keinen context; das native Modul hält ihn für Sie.

Schritt 2: Authentifizieren

Rufen Sie nach der Initialisierung Accept.auth.authenticate() auf, um einen Händler mit einem Token anzumelden, das Sie von Ihrem Backend erhalten. Der Aufruf ist asynchron und schlägt mit einem SDK-Fehler fehl. Bei Erfolg wechselt der SDK-Zustand zu 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
}

Beobachten Sie den Lebenszyklus, um auf diese Übergänge zu reagieren: idle → initialized → authenticated.

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

Grundkonzepte

Das Objekt Accept stellt das SDK über einige wenige Schnittstellen bereit:

SchnittstelleZweck
Accept.authAuthentifizierung einer Händler-Session.
Accept.merchantHändlerprofil, Konfiguration, Onboarding-Status.
Accept.paymentsErstellung und Verwaltung von Kartenzahlungen.
Accept.pluginInstallation und Aktivierung des Terminals (Plugin-App).
Accept.displaysInformationen zu den Displays des Geräts für beidseitige Terminals („double-sided“).
Accept.sdkSDK-Version, Umgebung, Geräte-ID, Mindestbeträge.
Accept.stateLebenszyklus-Zustand: StateFlow<SdkState> unter Kotlin, ein Getter plus addStateListener() unter React Native.

Zahlung annehmen

Rufen Sie Accept.payments.pay() mit dem Betrag (in der kleinsten Einheit der Währung) und einem Währungscode nach ISO 4217 auf und beobachten Sie dann den Strom von PaymentEvents, den die Methode meldet: zuerst den Fortschritt, dann das endgültige Ergebnis. pay() wirft nie eine Exception; ein Fehler beim Erstellen der Zahlung kommt stattdessen als Ereignis CreationFailed an.

Unterschiedlich ist nur, wie Sie diesen Strom beobachten: Kotlin gibt einen Flow<PaymentEvent> zurück, den Sie in einer Coroutine sammeln, während React Native einen Listener entgegennimmt und ein Abonnement zurückgibt, das Sie mit remove() beenden können.

amount und currency sind erforderlich. Die optionalen Parameter (paymentToken, receiptConfig, nfcPosition, metadata, tip, transactionTimeout, display) finden Sie unter Zahlung erstellen.

Unter React Native

Dieselben Parameter werden als ein einzelnes PaymentRequest-Objekt übergeben, pay({ amount, currency, tip, … }), mit number anstelle von Long und Record<string, string> anstelle von Map<String, String>. Eine Umbenennung: Das Timeout heißt transactionTimeoutMs und erwartet einfache Millisekunden (0…120000) statt einer Duration.

Zahlungsablauf

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())
        }
    }

Das abschließende Ergebnisereignis enthält ein PayResult: Erfolg (mit paymentToken, metadata, authCode, receiptDetails), Ablehnung (metadata, receiptDetails), Abbruch (metadata) oder Fehlschlag (reason, metadata). Kotlin bildet diese als Unterklassen PayResult.Success / Declined / Canceled / Failed ab, React Native als Discriminated Union, in der Sie mit payResult.type === 'success' verzweigen. Die vollständige Aufschlüsselung finden Sie unter Ergebnis der Zahlung. Fragen Sie eine Zahlung später mit Accept.payments.status(paymentToken) ab, stoppen Sie sie mit Accept.payments.cancel(paymentToken) oder erstatten Sie sie mit Accept.payments.refund(paymentToken, reason).

Nur das Ergebnis (React Native)

Wenn Ihre Oberfläche die Zwischenzustände nicht darstellt, reduziert payAsync() den gesamten Strom auf sein abschließendes PayResult; das Promise wird mit einem AcceptError zurückgewiesen (rejected), wenn pay() den Fall als creationFailed gemeldet hätte. Unter Kotlin gibt es kein Gegenstück; sammeln Sie dort den Flow oder verwenden Sie nur sein letztes Ereignis.

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

Händler- und SDK-Informationen

Accept.merchant stellt das Profil und die Zahlungskonfiguration des angemeldeten Händlers bereit. Accept.sdk liefert Angaben zum SDK-Build und zu diesem Gerät. Jedes der unten aufgeführten Member setzt zuvor Accept.initialize() voraus (außer Accept.sdk.version), und alles auf Accept.merchant erfordert zusätzlich ein abgeschlossenes Accept.auth.authenticate(), andernfalls wirft der Aufruf NotInitialized oder NotAuthenticated.

Händler

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
MemberRückgabeBeschreibung
info()MerchantInformation?Das registrierte Unternehmensprofil des Händlers. null, wenn das Profil noch nicht verfügbar ist.
config()MerchantConfigDie Zahlungskonfiguration des Händlers.
availableCurrencies()List<String>ISO-4217-Codes, die der Händler akzeptieren kann. Kurzform für config().availableCurrencies.
onboardingStatus()OnboardingStatusOb der Händler bereits Zahlungen annehmen darf.

Alle vier sind suspend und werfen bei einem Fehler NotAuthenticated, NoInternetConnection oder Unknown.

MerchantInformation enthält das registrierte Unternehmensprofil. Immer vorhanden: merchantId (UUID), email, businessType (BusinessType), legalName, registrationNumber, mcc und die registrierte Adresse (addressLine1, city, country). Optional (null, sofern der Händler sie nicht angegeben hat): vatNumber, incorporationDate, addressLine2, postalCode, state, phone, averageItemValue, expectedMonthlyTurnover, businessModelDescription, numberOfEmployees, annualTurnover, balanceSheetTotal, statementDescriptor, termsVersion.

BusinessType ist einer der Werte INDIVIDUAL, COMPANY, NONPROFIT_ORGANIZATION, GOVERNMENT_ENTITY oder PARTNERSHIP.

MerchantConfig enthält availableCurrencies: List<String> und die Standardwährung des Händlers currency: String?.

OnboardingStatus ist ein Sealed Interface: entweder ReadyForPayments oder RequiresAction(state), wobei state ein OnboardingState ist: NOT_STARTED, PENDING, ACTIVE, ATTENTION_NEEDED, ACTION_REQUIRED, BLOCKED, WAITING_FOR_KYB, WAITING_FOR_STAKEHOLDERS oder PENDING_ACQUIRER_APPROVAL. Was die einzelnen Zustände bedeuten, erfahren Sie unter Händler-Onboarding.

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)
MemberRückgabeBeschreibung
versionStringDie Version des SDK. Schon vor initialize() lesbar.
isProductionBooleanOb initialize() auf die Produktion (true) oder die Sandbox (false) ausgerichtet wurde.
deviceId()String?Die stabile ID dieses Geräts, vergeben beim ersten erfolgreichen authenticate() und beibehalten, bis die App deinstalliert wird. Davor null. Geben Sie sie in Supportanfragen an.
minimumAmounts()List<MinimumAmount>Der zahlbare Mindestbetrag je unterstützter Währung. Jeder Eintrag ist currency: String, amount: Long in der kleinsten Einheit der Währung.

Plugin-App

Jede Kartenzahlung wird an Tapaya Terminal übergeben, die Plugin-App von Tapaya; sie ist immer erforderlich, es gibt keinen Weg für Kartenzahlungen, der sie umgeht. Prüfen Sie, ob sie installiert ist, und aktivieren Sie dann das Terminal, oder öffnen Sie den Store-Eintrag, damit der Händler sie installieren kann.

Verwenden Sie dafür Accept.plugin.isInstalled(), Accept.plugin.activateTerminal() und Accept.plugin.install(). Den Code und alle möglichen Ergebnisse der Aktivierung finden Sie unter Terminal installieren und aktivieren.

Den aktuellen Zustand des Plugins lesen Sie mit Accept.plugin.status() aus, und mit Accept.plugin.logout() melden Sie den Händler vom Plugin ab.

Berechtigungen

Für Kartenzahlungen muss die Host-App die Standortberechtigung (ACCESS_FINE_LOCATION) besitzen. Das SDK fordert sie nicht für Sie an; erteilen Sie sie mit den Standard-APIs für Android-Berechtigungen, bevor Sie pay() aufrufen.

class PaymentActivity : AppCompatActivity() {
    private val requestLocation = registerForActivityResult(
        ActivityResultContracts.RequestPermission()
    ) { granted ->
        if (granted) launchPaymentFlow() else showPermissionRationale()
    }

    fun startPayment() {
        requestLocation.launch(Manifest.permission.ACCESS_FINE_LOCATION)
    }
}

Fehlt der Standort oder lässt er sich nicht ermitteln, wenn pay() ausgeführt wird, gibt der Ablauf PaymentEvent.CreationFailed mit LocationPermissionRequired, LocationUnavailable oder LocationTimeout als Ursache aus.

Fehlerbehandlung

Jeder vom SDK gemeldete Fehler trägt einen der unten aufgeführten Namen. Unter Kotlin ist jeder davon eine Unterklasse der Sealed Class AcceptException; unter React Native handelt es sich immer um eine einzige Klasse AcceptError, deren code den Namen enthält, und die Payload-Felder (minimum, currency, state, …) hängen direkt am selben Objekt.

Die asynchronen Aufrufe (authenticate, merchant.*, payments.status/cancel/refund, plugin.activateTerminal/status/logout/updateInfo, clear) schlagen mit einem davon fehl. payments.pay() ist die Ausnahme: Es wirft nie, sondern meldet dieselben Fehler als Ereignis CreationFailed mit der Ursache.

Exception-Typen

ExceptionBeschreibung
Lebenszyklus
NotInitializedEin Aufruf erfordert zuvor Accept.initialize().
NotAuthenticatedEin Aufruf erfordert zuvor Accept.auth.authenticate().
SessionExpiredDie authentifizierte Session ist abgelaufen; authentifizieren Sie sich erneut.
UnknownEnvironment(key)Umgebungsschlüssel nicht erkannt (interne Überladung von initialize).
Zahlungen
PaymentInProgressEin vorheriges pay() wartet noch auf ein Ergebnis.
CurrencyNotAvailableForMerchant(code)Die Währung ist für den Händler nicht konfiguriert.
UnsupportedCurrency(code)Die Währung wird vom SDK nicht erkannt.
AmountBelowMinimum(minimum, currency)Der Betrag liegt unter dem konfigurierten Minimum.
TransactionTimeoutOutOfRange(transactionTimeout)transactionTimeout liegt außerhalb des Bereichs von 0 bis 120 Sekunden.
PaymentCreationFailed(cause)Jeder andere Fehler beim Erstellen einer Zahlung.
PaymentNotFoundDas Token für status()/cancel()/refund() ist dem Backend unbekannt.
Standort
LocationPermissionRequiredDer Host-App fehlt die Standortberechtigung.
LocationUnavailableKein Anbieter konnte eine Standortbestimmung liefern.
LocationTimeoutDer Standort wurde nicht rechtzeitig ermittelt.
Plugin / Terminal
PluginUnavailableDie Plugin-App ist nicht installiert, oder ihr Dienst konnte nicht gebunden werden.
PluginTimeoutDas Plugin hat nicht rechtzeitig geantwortet.
ActivationInProgressEin vorheriges activateTerminal() wartet noch auf ein Ergebnis.
NoTidsAvailableForMerchantDer Händler hat kein nicht zugewiesenes Terminal (TID) mehr, das aktiviert werden könnte.
PluginAlreadyAuthenticatedDas Plugin ist für diesen Händler bereits authentifiziert.
PluginMerchantMismatchDas Plugin ist unter einem anderen Händler authentifiziert; rufen Sie zuerst plugin.logout() auf.
PluginNotReadyForPayments(status)pay() wurde ausgeführt, während sich das Plugin nicht im Zustand PluginStatus.ReadyForPayments befand; status enthält den aktuellen Zustand.
MerchantOnboardingIncomplete(state)Der Händler hat das Onboarding nicht abgeschlossen.
System
NoInternetConnectionDas Gerät hat keine Netzwerkverbindung.
Unknown(cause)Jeder Fehler, den das SDK nicht als einen seiner eigenen erkennt.

Ergebnis vs. Exception

Eine Zahlung, die das Terminal erreicht, aber nicht erfolgreich ist, ist keine Exception; sie kommt als PaymentEvent.Result mit PayResult.Declined, Canceled oder Failed(reason) an. Ebenso meldet die Aktivierung des Terminals ActivateTerminalResult.Failed(reason).

Exceptions behandeln

Umschließen Sie den Aufruf mit try/catch und verzweigen Sie nach den konkreten Fällen, die Sie behandeln, mit einem allgemeinen catch als Rückfallebene. Kotlin verzweigt nach der Exception-Unterklasse; React Native prüft mit AcceptError.is() und verzweigt per switch nach 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}")
}

Logging

Aktivieren Sie während der Entwicklung das Debug-Logging, um Probleme zu beheben.

Accept.setDebugLoggingEnabled(true)

Abmelden

Löschen Sie den gesamten lokal gespeicherten SDK-Zustand (Auth-Token, Geräte-ID, zwischengespeicherte Konfiguration) und setzen Sie den SDK-Zustand auf idle zurück. Rufen Sie dies auf, wenn sich der Benutzer abmeldet. Um den Händler auch von der App Tapaya Terminal abzumelden, rufen Sie zuerst Accept.plugin.logout() auf.

Accept.plugin.logout() // suspend; signs out of the Tapaya Terminal app
Accept.clear()         // suspend; clears local SDK state
Fehlt Ihnen etwas auf dieser Seite?Wünschen Sie sich eine Funktion. Wir hängen diese Seite an, damit das Team den Kontext sieht.