# GlomoPay Android SDK v1

Official Android SDK for integrating GlomoPay payment checkout flows into your native Android applications.

> Full [Changelog](/platform/sdk/android-sdk/changelog) is also available.


## Prerequisites

Before using this SDK, you need:

- API credentials (Public Key) from your GlomoPay dashboard
- An order ID created via the GlomoPay API (or a subscription ID for subscription payments)


## System Requirements

| Requirement | Version |
|  --- | --- |
| Android SDK | minSdk 24 (Android 7.0+) |
| Kotlin | >= 2.0 |
| Gradle | >= 8.0 |


## Installation

The SDK is published to Maven Central.

**Gradle (Kotlin DSL):**

```kotlin
dependencies {
    implementation("com.glomopay:glomo-android-sdk:1.0.0")
}
```

**Gradle (Groovy DSL):**

```groovy
dependencies {
    implementation 'com.glomopay:glomo-android-sdk:1.0.0'
}
```

## Quick Start

```kotlin
import android.app.Activity
import android.util.Log
import com.glomopay.sdk.android.*

class CheckoutActivity : Activity(), GlomoPayListener {

    fun startPayment() {
        val config = GlomoPayConfig(
            publicKey = "live_your_public_key",
            orderId = "order_your_order_id",
        )
        GlomoPaySdk.startCheckout(this, config, this)
    }

    override fun onPaymentSuccess(payload: GlomoPayPayload) {
        // Verify signature server-side before fulfilling the order
        val orderId = payload.orderId
        val paymentId = payload.paymentId
        val signature = payload.signature
    }

    override fun onPaymentFailure(payload: GlomoPayPayload) {
        // Handle payment failure
    }

    override fun onSdkError(errors: List<SdkError>) {
        // Handle validation or device compliance errors
        errors.forEach { error ->
            Log.e("GlomoPay", "${error.type}: ${error.message}")
        }
    }

    override fun onConnectionError(error: ConnectionError) {
        // Handle network / WebView errors
        if (error.isRecoverable) {
            // Retry or show retry UI
        }
    }

    override fun onPaymentTerminate(source: TerminationSource) {
        // User dismissed checkout
    }

    override fun onEvent(name: String, payload: Map<String, Any?>) {
        // Diagnostic / analytics events (optional)
    }
}
```

The SDK's `AndroidManifest.xml` declares `INTERNET`, `ACCESS_NETWORK_STATE`, and the checkout activity automatically. These merge into your app's manifest — no additional manifest configuration is required.

## Subscriptions Checkout

To process subscription payments, pass a `subscriptionId` instead of an `orderId`:

```kotlin
val config = GlomoPayConfig(
    publicKey = "live_your_public_key",
    subscriptionId = "sub_your_subscription_id",
)
GlomoPaySdk.startCheckout(this, config, this)
```

When `subscriptionId` is provided:

- The SDK skips order type detection
- The `subscriptionId` must start with `sub_`
- Do not pass both `orderId` and `subscriptionId` - the SDK will fire `onSdkError`


## Features

- **Standard, LRS, and Subscriptions** checkout flows
- **Automatic order type detection** based on API response
- **WebView-based secure checkout** - payment data never passes through merchant code
- **Payment callbacks** with signature verification
- **Device security compliance** - root and debugger detection for live keys
- **Mock mode** for testing with `test_` and `mock_` key prefixes
- **Connection error handling** with recovery hints (`isRecoverable`)
- **File upload support** via system document picker
- **ProGuard/R8 compatible** - consumer rules included automatically


## API Reference

### GlomoPaySdk

```kotlin
object GlomoPaySdk {
    fun startCheckout(
        context: Context,
        config: GlomoPayConfig,
        listener: GlomoPayListener,
        orderType: String = "auto"
    )
}
```

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `context` | `Context` | Yes | Android Activity or application context |
| `config` | `GlomoPayConfig` | Yes | Checkout configuration |
| `listener` | `GlomoPayListener` | Yes | Callback listener for payment events |
| `orderType` | `String` | No | `"auto"` (default, recommended), `"standard"`, or `"lrs"`. Auto-detects from API response. |


### GlomoPayConfig

| Parameter | Type | Required | Description |
|  --- | --- | --- | --- |
| `publicKey` | `String` | Yes | Your GlomoPay public key. Must start with `live_`, `test_`, or `mock_`. |
| `orderId` | `String?` | Conditional | Order ID (starts with `order_`). Required unless using `subscriptionId`. |
| `subscriptionId` | `String?` | Conditional | Subscription ID (starts with `sub_`). Mutually exclusive with `orderId`. |


Exactly one of `orderId` or `subscriptionId` must be provided. If both or neither are set, `onSdkError` fires.

### GlomoPayListener

| Callback | Parameters | Description |
|  --- | --- | --- |
| `onPaymentSuccess` | `payload: GlomoPayPayload` | Payment completed successfully. Verify `signature` server-side before fulfilling. |
| `onPaymentFailure` | `payload: GlomoPayPayload` | Payment failed. |
| `onSdkError` | `errors: List<SdkError>` | Validation errors (invalid config) or device compliance failures. Called instead of opening checkout. |
| `onConnectionError` | `error: ConnectionError` | Network, DNS, SSL, or HTTP errors during checkout. Check `isRecoverable` for retry hint. |
| `onPaymentTerminate` | `source: TerminationSource` | User dismissed checkout (close button, back button) or SDK closed it. Default no-op. |
| `onEvent` | `name: String, payload: Map<String, Any?>` | Diagnostic lifecycle events. Default no-op. |


### GlomoPayPayload

```kotlin
data class GlomoPayPayload(
    val orderId: String,
    val paymentId: String? = null,
    val signature: String? = null,
)
```

**Merchant responsibility:** Always verify the `signature` on your server using your secret key before fulfilling an order. See [Checkout overview](/payin/checkout#steps-to-integrate-checkout) for verification instructions.

### SdkError

```kotlin
enum class SdkErrorType {
    VALIDATION_ERROR,
    DEVICE_FORBIDDEN,
    NETWORK_ERROR,
    UNKNOWN,
}

data class SdkError(
    val type: SdkErrorType,
    val message: String,
    val field: String? = null,
)
```

| Type | When |
|  --- | --- |
| `VALIDATION_ERROR` | Invalid public key, order ID, or subscription ID format. `field` indicates which failed. |
| `DEVICE_FORBIDDEN` | Root or debugger detected on a device using a `live_` key. |
| `NETWORK_ERROR` | Failed to fetch order details before opening checkout. |
| `UNKNOWN` | Unexpected error. |


### ConnectionError

```kotlin
enum class ConnectionErrorType {
    NO_INTERNET,
    DNS_FAILURE,
    TIMEOUT,
    SSL_ERROR,
    HTTP_CLIENT_ERROR,
    HTTP_SERVER_ERROR,
    WEB_RESOURCE_ERROR,
    UNKNOWN,
}

data class ConnectionError(
    val type: ConnectionErrorType,
    val message: String,
    val statusCode: Int? = null,
    val failedUrl: String? = null,
    val isRecoverable: Boolean,
)
```

| Type | Recoverable | Description |
|  --- | --- | --- |
| `NO_INTERNET` | Yes | Device is offline |
| `DNS_FAILURE` | No | DNS resolution failed |
| `TIMEOUT` | Yes | Request timed out |
| `SSL_ERROR` | No | SSL/TLS handshake failed |
| `HTTP_CLIENT_ERROR` | No | HTTP 4xx response |
| `HTTP_SERVER_ERROR` | Yes | HTTP 5xx response |
| `WEB_RESOURCE_ERROR` | No | WebView resource loading failed |
| `UNKNOWN` | No | Unexpected error |


### TerminationSource

```kotlin
enum class TerminationSource {
    USER_DISMISS,
    BACK_BUTTON,
    PROGRAMMATIC,
    CONNECTION_ERROR,
}
```

## Platform Behavior

- Checkout launches as a new Activity (fullscreen, portrait)
- Back button dismisses the checkout and fires `onPaymentTerminate(BACK_BUTTON)`
- Close button fires `onPaymentTerminate(USER_DISMISS)`
- The checkout Activity is declared in the SDK's manifest and merges automatically — merchants do not need to declare it


## Device Security Compliance

| Scenario | Behavior |
|  --- | --- |
| `live_` key + rooted/debuggable device | `onSdkError` with `DEVICE_FORBIDDEN`. Checkout does not open. |
| `live_` key + clean device | Checkout proceeds normally |
| `test_` or `mock_` key | Compliance checks skipped entirely |


## Mock Mode

| Key prefix | Mode | Description |
|  --- | --- | --- |
| `live_` | Production | Real payments. Device compliance enforced. |
| `test_` | Test | Mock checkout. No real transactions. Compliance skipped. |
| `mock_` | Mock | Same as `test_`. |


## Input Validation

| Field | Rule |
|  --- | --- |
| `publicKey` | Length > 5. Must start with `live_`, `test_`, or `mock_`. |
| `orderId` | Length > 6. Must start with `order_`. |
| `subscriptionId` | Length > 4. Must start with `sub_`. |


- Exactly one of `orderId` or `subscriptionId` must be provided.
- Validation errors fire `onSdkError` with `VALIDATION_ERROR` and the `field` that failed.


## ProGuard / R8

The SDK includes consumer ProGuard rules that are applied automatically. Merchants do not need to add any ProGuard configuration. R8 full mode is safe.

## Troubleshooting

### `onSdkError` fires immediately

Check that `publicKey` format is valid and exactly one of `orderId`/`subscriptionId` is provided.

### `DEVICE_FORBIDDEN` in development

Use a `test_` or `mock_` key prefix during development.

### Checkout opens but shows blank/loading screen

Check network connectivity. Verify the order exists and is in a valid state.

### `onConnectionError` with `SSL_ERROR`

Ensure the device's system time is correct. Check for corporate proxy or certificate pinning issues.

## Security

- Payment data is handled within a secure, isolated WebView — it never passes through the merchant's application code
- JavaScript bridge communication is limited to payment lifecycle events; no PAN, CVV, or sensitive payment data crosses the bridge
- Root and debugger detection blocks checkout on compromised devices (live keys only)
- File access is disabled in the WebView; only `content://` URIs from the system document picker are allowed


To report a security vulnerability, email security@glomopay.com. Do not open a public GitHub issue for security reports.

## Related

- [Changelog](/platform/sdk/android-sdk/changelog) - all release notes
- [React Native SDK](/platform/sdk/react-native-sdk) - GlomoPay SDK for React Native apps
- [Flutter SDK](/platform/sdk/flutter-sdk) - GlomoPay SDK for Flutter apps
- [Unified SDK (Web)](/platform/sdk/unified-sdk) - GlomoPay SDK for web apps
- [Checkout overview](/payin/checkout) - server-side checkout integration and signature verification