# Quickstart

Follow our walkthrough to get Checkout Drop-in running in minutes.

## Pre-requisites

Before you start, make sure you have:

ul
li
Android Studio installed on your computer
li
Android SDK 24 or higher (`minSdk = 24`)
li
Kotlin 2.x (2.2.10 or higher), with a Compose compiler plugin version that matches your Kotlin version
li
Jetpack Compose enabled in your app module (SDK UI is Compose-only)
li
JitPack repository configured (required for some SDK transitive dependencies)
li
Your API credentials from the 
a
Unity Portal
Add the JitPack repository and enable Compose in your Gradle files.

#### Kotlin DSL

```kotlin
// settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven("https://jitpack.io")
    }
}

// Root build.gradle.kts. Compose plugin version must match Kotlin
plugins {
    kotlin("android") version "{kotlinVersion}" apply false
    id("org.jetbrains.kotlin.plugin.compose") version "{kotlinVersion}" apply false
}

// App build.gradle.kts
plugins {
    id("org.jetbrains.kotlin.plugin.compose")
}

android {
    buildFeatures {
        compose = true
    }
}
```

#### Groovy

```groovy
// settings.gradle
dependencyResolutionManagement {
    repositories {
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}

// Root build.gradle
buildscript {
    ext.kotlin_version = '{kotlinVersion}'
    dependencies {
        classpath "org.jetbrains.kotlin:compose-compiler-gradle-plugin:$kotlin_version"
    }
}

// App build.gradle
plugins {
    id 'org.jetbrains.kotlin.plugin.compose'
}

android {
    buildFeatures {
        compose true
    }
}
```

Where to find your credentials
Find your client ID and token in the Unity Portal:

1. In the Unity Portal, go to **Merchant setup > Merchant groups** and select a merchant group.
2. Click the **Inbound calls** tab. Your client ID is in the top right:

3. Click **+ New token** to create a token, then copy both the **ID** and the **Value**.



## Add the SDK dependency

To get started, add the latest version of the Android SDK to your project using Maven Central.

In your app-level `build.gradle` file, add the dependency:

```kotlin
dependencies {
    implementation("io.pxp:android-components-sdk:{versionNumber}")
}
```

The walkthrough samples (`create-session.kt`, `CheckoutActivity.kt`, and `webhook-handler.kt`) also use Ktor and kotlinx serialization. Add these when you follow the samples as written:

#### Kotlin DSL

```kotlin
// Root build.gradle.kts
plugins {
    kotlin("plugin.serialization") version "{kotlinVersion}" apply false
}

// App build.gradle.kts
plugins {
    kotlin("plugin.serialization")
}

dependencies {
    implementation("io.ktor:ktor-client-core:{ktorVersion}")
    implementation("io.ktor:ktor-client-cio:{ktorVersion}")
    implementation("io.ktor:ktor-client-content-negotiation:{ktorVersion}")
    implementation("io.ktor:ktor-serialization-kotlinx-json:{ktorVersion}")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:{serializationVersion}")
}
```

#### Groovy

```groovy
// Root build.gradle
buildscript {
    ext.kotlin_version = '{kotlinVersion}'
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
    }
}

// App build.gradle
plugins {
    id 'org.jetbrains.kotlin.plugin.serialization'
}

dependencies {
    implementation "io.ktor:ktor-client-core:{ktorVersion}"
    implementation "io.ktor:ktor-client-cio:{ktorVersion}"
    implementation "io.ktor:ktor-client-content-negotiation:{ktorVersion}"
    implementation "io.ktor:ktor-serialization-kotlinx-json:{ktorVersion}"
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:{serializationVersion}"
}
```

The SDK automatically includes the required Android permissions in its manifest (`INTERNET`, `ACCESS_NETWORK_STATE`, and `SYSTEM_ALERT_WINDOW`). These permissions are necessary for payment processing, network connectivity checks, and 3DS authentication challenges.

## Create a session on your backend

Drop-in needs a session from the PXP API. This must happen on your backend using HMAC authentication.

Set up your API credentials as environment variables. Never hardcode them in your application.

This function generates a secure authentication hash by combining the timestamp, request ID, request path, and request body (no separators), then hashing with your token value using HMAC SHA256. Put the Token ID in the `Authorization` header (`PXP-UST1 $TOKEN_ID:$timestamp:$hmac`), not in the HMAC message body.

Create a request with your merchant details and transaction information. Set `serviceType` to `"CheckoutDropIn"`. For returning shoppers, include optional `customerProfileId` (omit it for guest checkout). The request body must be minified (no whitespace) for the HMAC signature. See [Implementation — Customer Profile](/guides/checkout/drop-in/android/implementation#customer-profile).

POST to `https://api-services.pxp.io/api/v1/sessions` with these headers and your minified JSON body:

* `Content-Type: application/json`
* `X-Client-Id`: your Unity Portal client ID
* `X-Request-Id`: the same request ID used in the HMAC message
* `Authorization`: `PXP-UST1 $TOKEN_ID:$timestamp:$hmac`


The API returns `sessionId`, `hmacKey`, `data`, `encryptionKey`, `locale`, `allowedFundingTypes`, and optional `restrictions`. Return that JSON from your backend. Map it into `SessionConfig` on the Android client with `toSessionConfig()` (see `CheckoutActivity.kt`). Include `allowedFundingTypes` (at minimum a non-null `cards` array, which may be empty) so the card UI can render. `cardSchemes` alone doesn't enable the card panel.

To show the Aeropay panel, include `allowedFundingTypes.payByBanks.aeropay` (with `externalMerchantId` and `configurationId` from the session response). Aeropay isn't part of `WalletsConfig`. Map it under `payByBanks`, as in the sample `toAllowedFundingTypes()` in `CheckoutActivity.kt`.

## Initialise Drop-in in your app

Wire session data into `CheckoutDropInConfig`, then create and render Drop-in in your Compose UI.

Import `CheckoutDropIn`, `CheckoutDropInConfig`, and the necessary types from the Android SDK. Use `com.pxp.checkout.models.SessionConfig`, `CardIntentType`, `DropInPayPalIntentType`, and `DropInAeropayIntentType` (when Aeropay is enabled), and `com.pxp.checkout.services.models.transaction.Shopper`.

Create a Jetpack Compose activity that will host the Checkout Drop-in interface.

Call your backend endpoint to get the session data you created in the previous steps, and map it to `SessionConfig` with `toSessionConfig()`. Include `allowedFundingTypes` from the response (at minimum a non-null `cards` array, which may be empty) so that the card UI can render. For Aeropay, also map `payByBanks.aeropay`. Map optional `restrictions` when the Sessions API returns them.

Create sessions on your backend with HMAC authentication. Don't call the Sessions API from the Android app or embed `PXP_CLIENT_ID`, token ID, or token value in the app process. The walkthrough shortcut that calls `createSession()` from the client is for local exploration only.

Configure Drop-in with your environment, `SessionConfig`, and transaction details.

Specify the currency, amount, entry type, and payment intents for each payment method. Use `CardIntentType` for `card`. Import `DropInAeropayIntentType` when Aeropay is enabled, and set `aeropayDropInIntent` to `DropInAeropayIntentType.Authorisation`, `Purchase`, or `EstimatedAuthorisation`, as in `CheckoutActivity.kt`.

Optionally implement the `onGetShopper` callback. Card-on-file requires a non-empty `Shopper.id` when `showCOF` resolves to `true` (the default when omitted). This is separate from optional `customerProfileId` on the session request. See [Implementation — Customer Profile](/guides/checkout/drop-in/android/implementation#customer-profile).

Use `methodConfig.card` to show or hide card-on-file and new card entry. See [Cards](/guides/checkout/drop-in/android/cards#card-display-properties). How Drop-in stores a new card for card-on-file is controlled by site `storeCardConsent` in the Unity Portal (including `ConsentAlreadyObtained` when consent was already collected outside Drop-in). See [Cards — Store-card consent](/guides/checkout/drop-in/android/cards#store-card-consent).

Implement the `onSuccess` callback to handle successful payments. Always verify payments on your backend before fulfilling orders. Frontend callbacks can be manipulated.

Implement the `onError` callback as `(PaymentMethod?, BaseSdkException) -> Unit`. Use `error.errorCode` for programmatic handling. `paymentMethod` is `null` for initialisation or cross-method errors.

Call the suspend `create()` method from a coroutine (for example `LaunchedEffect`) after initialisation.

Call `checkoutDropIn.Content()` to display the payment interface. Prefer this over calling `Content()` on the `create()` return value so Drop-in can show its loading UI.

## Verify payments

When a payment succeeds, the `onSuccess` callback fires with transaction details. However, you must always verify the payment on your backend before fulfilling orders.

Configure webhooks in the Unity Portal to receive real-time payment notifications on your backend.

Set up an endpoint at `/webhooks/pxp` to receive payment notifications from Unity.

Verify the webhook HMAC signature before processing events. Reject unauthenticated requests.

Loop through the events array and filter for Transaction events.

Verify the transaction state is `Authorised` or `Captured` before processing.

Check if you've already processed this transaction using `systemTransactionId`.

Match the `merchantTransactionId`, amount, and currency against your order records.

If verification passes, fulfil the order and mark the transaction as processed.

Always return `{ state: 'Success' }` to acknowledge receipt, even if processing failed.

You can also verify payments using the Transactions API to query transaction status directly. See the [Implementation guide](/guides/checkout/drop-in/android/implementation#backend-verification-critical) for details.

That's it! You now have a working Checkout Drop-in integration.

## What's next?

Now that you have Drop-in running, here are the recommended next steps:

ul
li
strong
a
Customise the look and feel
to match your brand (configured in the Unity Portal).
li
strong
a
Configure card display
to show or hide card-on-file and new card entry.
li
strong
a
Enable Aeropay
for USD pay-by-bank payments when Aeropay is enabled in your session.
li
strong
a
Set up backend verification
to verify payments before fulfilling orders.
li
strong
a
Add optional callbacks
to enhance the user experience with validation and loading states.