Quick Start Guide
AndroidDiscover how to set up the SDK, configure your environment, and successfully execute your first transaction.
The Accept SDK runs inside your app and handles payments on the device: it captures the card or Tap to Pay, encrypts the data, and keeps card handling out of your code so you stay outside PCI scope. Your backend authenticates each SDK session against the Tapaya API, onboards merchants, and triggers KYB. Tapaya runs the KYB checks and settles funds to the merchant.
Choose Your Integration Path
There are two ways to take card payments with Tap to Pay. Both hand the actual card interaction off to the Tapaya Terminal plugin app on the same device. They differ in how much of that handoff your app manages:
- Accept SDK (this guide): embed the Tapaya Accept SDK in your app. The SDK creates the payment, launches
Tapaya Terminal, and delivers the result to your
onResult/onErrorcallbacks. This is the recommended path for native Android apps and is what the rest of this guide walks through. - Tapaya Terminal app only, no SDK: if you can't embed the Accept SDK (a cross-platform framework without native bindings, a thin POS shell, a WebView-based till), you can drive the Tapaya Terminal app directly with an Android intent or a deeplink. In this mode your backend creates the payment and your app polls its status, instead of relying on SDK callbacks. See Integrate without the SDK for the intent and deeplink contracts.
Create Your Tapaya Account
Before writing any code, set up the account your backend will authenticate against:
- Sign up at platform.tapaya.com/register. This is self-serve: no invite is required.
- Log in, then create or join your organization; you'll be prompted for this automatically right after registering.
- Generate your Server Secret Token from the API Keys page: your backend uses this to call the Tapaya Platform API (see API Integration).
Not the same as merchant onboarding
This is account setup for you, the integrator. Your merchants are onboarded separately, either through
the SDK, the Tapaya Platform UI, your own UI, or an invite link. See Merchant
Onboarding for details. POST /merchant/auth/register only creates the merchant
shell; hosted invite onboarding starts with POST /integrator/merchant/send-registration-invite.
The rest of this guide covers adding the SDK to your project, authenticating a session, and running your first transaction.
Add Dependency
The SDK is published to Maven Central. Add the dependency to your app module.
dependencies {
implementation("com.tapaya:accept:1.10.0")
}Sync your project, then initialize and authenticate in your application code.
// Step 1: Initialize (once, in Application.onCreate)
Accept.initialize(this) // sandbox by default; pass isProduction = true to go liveAuthenticate a merchant session with a token obtained from your backend.
authenticate is a suspend function and throws an AcceptException on failure.
// Step 2: Authenticate (suspend; call from a coroutine)
try {
val merchantToken = myBackend.login() // fetch from your backend
Accept.auth.authenticate(merchantToken)
// Accept.state now emits SdkState.Authenticated
} catch (e: AcceptException) {
// handle authentication failure
}Onboard the Merchant
Before any transactions are allowed, the merchant must finish KYB onboarding. Onboarding is no longer driven by the Accept SDK. Complete it through the Tapaya Platform UI, your own UI against the Tapaya API, or an invite link. See Merchant Onboarding for all methods.
Sandbox Auto-Approval
In the sandbox environment, merchants are automatically approved right after onboarding, so you don't have to wait for payment processor review.
Verify Merchant Readiness
Ensure the merchant has finished onboarding and is approved to accept payments.
val ready = when (val status = Accept.merchant.onboardingStatus()) {
OnboardingStatus.ReadyForPayments -> true
is OnboardingStatus.RequiresAction -> false // status.state describes what's blocking
}The merchant is ready only after the payment processor has approved it. If some information is missing, the onboarding must be repeated. In some cases, the payment processor might block the merchant completely, such as when selling prohibited goods.
Install & Activate Terminal
Plugin App Required
Card payments require the Tapaya Accept plugin to be installed on the device.
Use Accept.plugin.isInstalled() to check, and Accept.plugin.install() to open the store
listing if it is missing.
The Tapaya Accept plugin is required for card payments. Check if it is installed, then activate the terminal, or open the Play Store listing to install it.
if (Accept.plugin.isInstalled()) {
// suspend; returns ActivateTerminalResult (Success / Canceled / Failed)
Accept.plugin.activateTerminal()
} else {
Accept.plugin.install() // opens the store listing
}Create Payment Transaction
To execute a transaction, call Accept.payments.pay() with the amount (in the currency's minor unit)
and an ISO 4217 currency code. It returns a Flow<PaymentEvent>; collect it to observe progress and
the terminal outcome. pay() never throws: failures arrive as PaymentEvent.CreationFailed.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | Long | ✓ | Amount to charge, in the minor unit of currency. |
currency | String | ✓ | ISO 4217 currency code. |
paymentToken | String? | Resumes an existing payment session instead of starting a new one. Defaults to null. | |
receiptConfig | PaymentReceiptConfig? | Overrides the post-payment receipt screen for this call only. Defaults to null (uses the app-wide default from Accept.payments.setOptions()). See Configuring the receipt screen for the full breakdown. | |
nfcPosition | NfcPositionConfig? | Overrides where the tap-to-pay animation points, for this call only. Defaults to null. See Positioning the NFC tap animation. | |
metadata | Map<String, String> | Key-value data attached to the payment, echoed back on the PayResult if the plugin returns it. Defaults to emptyMap(). | |
tip | Long? | Fixed tip, in the minor unit of currency. When set, the plugin skips its own tip screen and charges amount + tip. Defaults to null. |
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())
}
}