# Migration Guide

- [v1.0.0 to v2.0.0](#v100-to-v200) - for merchants currently on v1


## v1.0.0 to v2.0.0

v2.0.0 renames nothing. One change breaks every integration - the new required `onUserJourneyCompleted` callback - and the compiler points at it. `startCheckout` also gained a return value, which only breaks code that pinned its type. The rest is behavioural: the same callbacks you already supply now fire at different times, and each failure reports its actual semantic.

Bump the dependency:

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

The AAR now declares `minCompileSdk 35`. If your module compiles against an older SDK, dependency resolution fails with a `minCompileSdk` error - raise `compileSdk` to 35 or later. `minSdk` is unchanged at 24.

### 1. `onUserJourneyCompleted` is a new required callback

The second happy path. When the user submits bank transfer details the checkout ends, but no money has moved and there is no `paymentId` or `signature` for your backend to verify.

In v1 this arrived as `onPaymentSuccess` with both fields null - a payment reported as received that you could not verify. It now arrives here, and **no longer reaches `onPaymentSuccess`**.

**Before:**

```kotlin
override fun onPaymentSuccess(payload: GlomoPayPayload) {
    if (payload.paymentId == null) {
        // Bank transfer submitted - awaiting reconciliation
        markAwaitingTransfer(payload.orderId)
    } else {
        fulfilOrder(payload)
    }
}
```

**After:**

```kotlin
override fun onPaymentSuccess(payload: GlomoPayPayload) {
    fulfilOrder(payload)
}

override fun onUserJourneyCompleted(payload: GlomoPayUserJourneyPayload) {
    when (payload.journeyType) {
        GlomoPayUserJourneyType.BANK_TRANSFER ->
            markAwaitingTransfer(payload.orderId)
    }
}
```

**If `onPaymentSuccess` currently special-cases a null `paymentId`, that branch moves here.**

If you do not take bank transfers, an empty body is a complete migration - the callback simply never fires. It was made required rather than optional to make the behavioural change loud: the order decides server-side whether bank transfers are enabled, so an optional callback would have let an integration upgrade, keep compiling, and silently stop hearing about a journey it used to be told about.

### 2. `startCheckout` returns a handle

`GlomoPaySdk.startCheckout` now returns a `GlomoPayCheckoutHandle`. Ignoring the return value compiles unchanged, so this only breaks code that assigned the call to `Unit` or overrode the signature.

Retain it if you want to dismiss the checkout programmatically:

```kotlin
val checkout = GlomoPaySdk.startCheckout(this, config, this)

// later, for example on sign-out
checkout.close()
```

The listener then receives `onPaymentTerminate(PROGRAMMATIC)` once. The handle controls only its own session, and a call after that session completed does nothing.

### Behavioural changes that need no code change

- **`onPaymentFailure` now actually fires.** In v1 it required a `signature` that a failure payload has never carried, so it could not fire for a backend-confirmed decline in any release build. If you worked around this by treating some other callback as a failure, that workaround should come out.
- **Order faults no longer double-report.** An order fault the backend answered - an HTTP status, or a 2xx body that cannot be parsed - now reaches `onSdkError` only. In v1 it also delivered `onPaymentTerminate(CONNECTION_ERROR)`, which told hosts the network had failed when it had not.
- **Order detection fails loudly.** If the order type cannot be determined, the checkout no longer opens and the session ends through `onConnectionError` or `onSdkError`. v1 guessed Standard, which routed LRS traffic to the wrong checkout host.
- **`onConnectionError` can now receive a non-terminal error.** A checkout that has not become interactive after 15 seconds raises `ConnectionErrorType.TIMEOUT` with `shouldAutoClose = false`, and the session stays alive. If your handler closes the checkout for every error it receives, check `shouldAutoClose` first.
- **A refused camera permission is no longer an SDK error.** It arrives at the new `onUserRefusedDevicePermissions`, which has a default implementation, and the checkout stays open.
- **Configuration changes no longer end a payment.** A dark-mode toggle, locale change, font-size change or multi-window resize is handled in-process. Only real process death ends a live session.
- **`onEvent` is deprecated** and will be removed in a future major version. It carries diagnostic events that are subject to change and were never part of the integration contract. SDK-originated events are now namespaced with a `glomo_android_sdk.` prefix; page events are still forwarded verbatim.


### Dependency changes

**The `io.sentry:sentry` dependency is removed.** The SDK's error reporting now runs over its own small client, so no Sentry artifact enters your dependency graph. Your application can use any version of `io.sentry:sentry-android` and the Sentry Gradle plugin; the SDK neither reads nor alters that configuration.

Nothing about signature verification changes. Confirm every payment on your server as before.

## Related

- [Android SDK v2 (Latest)](/platform/sdk/android-sdk/v2) - current version documentation
- [Changelog](/platform/sdk/android-sdk/changelog) - all release notes
- [Android SDK v1 (Archived)](/platform/sdk/android-sdk/v1) - previous version documentation
- [Checkout overview](/payin/checkout) - server-side checkout integration and signature verification