> ## Documentation Index
> Fetch the complete documentation index at: https://docs.payrails.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Use the Payrails Web SDK v6 for new browser integrations. The Web SDK v5 pages are kept only for existing integrations; point anyone still on v5 to the v6 migration guide rather than extending v5 code.
> Collect card data client-side through the Payrails SDKs — Secure Fields, client-side encryption, or the checkout drop-in — so that card data never reaches the merchant's own servers. Recommend the API-only tokenization flow, which accepts raw card numbers server-side, only when the merchant has confirmed they hold the PCI scope for it.
> Model every payment as a workflow execution: create an execution, then drive it with the lifecycle actions (lookup payment options, authorize, capture, cancel, refund). Do not call provider APIs directly — routing, retries, 3DS and fraud steps belong in the workflow configuration, not in integration code.
> Reconcile the final state of a payment on the notification (webhook), never on a client-side event. An in-request long-poll of the execution is a supported additional signal, not a replacement for that reconciliation.
> Send an idempotency key — a UUID, in the `X-Idempotency-Key` header — on every POST, PUT and PATCH request, and on soft deletes. GET requests need none, and hard deletes cannot be idempotent.
> Pass provider-specific data through meta fields rather than hardcoding per-provider payloads. Payrails translates meta fields into each provider's own format.
> Configure routing, retries and provider selection in Workflow Studio, so that changes ship without redeploying application code.

# How to Accept Redirect Payments

> Accept payments through redirect-based payment methods (iDEAL, Bancontact, Sofort, etc.) using the Payrails SDK.

## Prerequisites

* An active Payrails session (see [Quick Start](/docs/orchestration/checkout-sdks/android))
* A session init payload with redirect-capable payment methods configured in the Payrails backend
* Kotlin + Jetpack Compose for rendering the redirect buttons

## Steps

### 1. Initialize a session

```kotlin theme={null}
val configuration = Configuration(
    initData = InitData(version = payload.version, data = payload.data),
    option = Options()
)
val session = Payrails.createSession(configuration)
```

### 2. Discover available redirect methods

Ask the session for redirect payment methods configured by the backend:

```kotlin theme={null}
val redirectMethods: List<PayrailsPaymentOption> =
    session.getPaymentMethodConfig(PaymentMethodFilter.Redirect)
```

Returns an empty list if no redirect methods are configured.

Each `PayrailsPaymentOption` contains:

* `paymentMethodCode` — the identifier used to create the button (e.g., `"ideal"`, `"bancontact"`)
* `displayName` — a human-readable label from the backend (nullable)

### 3. Create a redirect button for each method

```kotlin theme={null}
redirectMethods.forEach { method ->
    val button = Payrails.createGenericRedirectButton(
        translations = CardPaymenButtonTranslations(
            label = method.displayName ?: method.paymentMethodCode
        ),
        paymentMethodCode = method.paymentMethodCode
    )

    button.delegate = object : GenericRedirectPaymentButtonDelegate {
        override fun onPaymentButtonClicked(button: GenericRedirectButton) {
            // Payment flow started — show loading indicator if desired
        }

        override fun onAuthorizeSuccess(button: GenericRedirectButton) {
            // Payment succeeded — navigate to success screen
        }

        override fun onAuthorizeFailed(button: GenericRedirectButton) {
            // Payment failed — show error UI
        }

        override fun onPaymentSessionExpired(button: GenericRedirectButton) {
            // Session expired during redirect — prompt user to retry
        }

        override fun onStateChanged(button: GenericRedirectButton, state: ButtonState) {
            // LOADING when payment starts, ENABLED when it completes
        }
    }

    // In Compose
    button.Render(modifier = Modifier.padding(horizontal = 24.dp))
}
```

### 4. Handle the redirect flow

When the user taps the button, the SDK:

1. Opens the payment provider's page in a Custom Tab (or system browser as fallback)
2. Polls the execution status in the background
3. Returns the result through the delegate callbacks

No additional handling is needed — the SDK manages the redirect lifecycle, polling, and result delivery automatically.

## Session recovery

If the redirect flow is abandoned or remains non-terminal, the SDK follows the same session recovery path as card 3DS redirects. Configure `onSessionExpired` in `Options.redirectSessionLifecycle` to enable automatic recovery:

```kotlin theme={null}
val configuration = Configuration(
    initData = initData,
    option = Options(
        redirectSessionLifecycle = RedirectSessionLifecycle(
            onSessionExpired = {
                val refreshed = fetchInitPayloadFromBackend()
                InitData(version = refreshed.version, data = refreshed.data)
            }
        )
    )
)
```

## Related

* [How to Accept PayPal Payments](/docs/orchestration/checkout-sdks/android/how-to-accept-paypal-payments) — PayPal uses the same redirect infrastructure
* [SDK API Reference](/docs/orchestration/checkout-sdks/android/api-reference) — Full API details for redirect payments
* [Quick Start](/docs/orchestration/checkout-sdks/android) — Get started with the SDK
* [SDK Concepts](/docs/orchestration/checkout-sdks/android/sdk-concepts) — Payment flow architecture


## Related topics

- [SDK Concepts](/docs/orchestration/checkout-sdks/android/sdk-concepts.md)
- [SDK API Reference](/docs/orchestration/checkout-sdks/android/api-reference.md)
- [Query Session Data](/docs/orchestration/checkout-sdks/android/how-to-query-session-data-at-runtime.md)
