SDK API Reference

This document describes the public API surface exposed by payrails-ui-compose, including payment methods, configuration, styling, translations, and event delegates. For setup and dependencies, see README.md.

Table of Contents

  • Getting Started
  • Core Concepts
  • Card Payments
  • Stored Instruments
  • Collect Elements (Custom Fields)
  • Results and Errors

Compatibility Requirements

  • JDK 17
  • Android minSdk 21
  • Android compileSdk 34

Public Artifact

  • Maven coordinate: com.payrails.checkout:android-sdk:<version>
  • Additional dependency: com.payrails.android:cse:<version>

Getting Started

Create a Session

Use a Configuration built from InitData plus optional Options.

val initData = InitData(version = "...", data = "...")
val configuration = Configuration(initData = initData, option = Options())

// Suspend API
val session = Payrails.createSession(configuration)

// Callback API
Payrails.createSession(configuration) { result ->
    result.onSuccess { /* session ready */ }
    result.onFailure { /* initialization failed */ }
}

To enable automatic SDK-managed recovery when a redirect flow is abandoned or remains non-terminal, pass onSessionExpired in Options.redirectSessionLifecycle:

val configuration = Configuration(
    initData = initData,
    option = Options(
        redirectSessionLifecycle = RedirectSessionLifecycle(
            onSessionExpired = {
                // Merchant callback: run your client-init call and return fresh init payload
                val refreshed = fetchInitPayloadFromBackend()
                InitData(version = refreshed.version, data = refreshed.data)
            }
        )
    )
)

Session-Scoped Helpers

// Keep the returned session reference from createSession(...)
val instruments = Payrails.getStoredInstruments()
val cardInstruments = Payrails.getStoredInstruments(forType = PaymentType.card)

Breaking change: Payrails.getCurrentSession() has been removed. Keep and pass the Session returned by createSession(...) when direct session APIs are needed.

Core Concepts

PaymentPresenter (3DS)

Card payments may require UI presentation for 3DS. Use the browser presenter for redirect/challenge handling.

val presenter = Payrails.createBrowserPaymentPresenter(activity) { request ->
    // Optional callback for PayPal requests when using custom/internal flows.
}

The browser presenter opens 3DS URLs in a Custom Tab when available, and falls back to the system browser if not. On app return, the presenter emits a non-terminal redirect return signal and the SDK keeps the button in a loading state while execution-status polling determines final success/failure. If polling remains non-terminal through the reconciliation window, the SDK routes the flow to authorizationFailed and triggers shared session-expiry handling (onSessionExpired) when configured. On terminal success/failure, the SDK performs best-effort Custom Tab dismissal/return-to-app handling before finalizing the result. Avoid using WebView for 3DS challenge pages because:

  • Issuer/ACS pages can block or behave inconsistently inside embedded WebViews.
  • WebViews reduce isolation compared to the system browser, increasing security and compliance risk.
  • Deep-link returns are less reliable or intuitive in embedded contexts, harming the user experience (users may not be returned to your app automatically and can get stuck or confused, leading to drop-off).

If you do not set a presenter on the card button, the SDK will use this default browser presenter automatically. To override, set presenter explicitly.

If you need custom handling, you can still implement PaymentPresenter directly.

Redirect Session Lifecycle (onSessionExpired)

onSessionExpired is configured once through Options.redirectSessionLifecycle and is shared for redirect-capable flows (3DS now, other redirect methods in future). The callback should run the merchant client-init call and return fresh InitData.

Behavior:

  • Triggered when redirect reconciliation is classified as abandoned or stuck non-terminal.
  • If callback is configured and succeeds, SDK refreshes active session/execution state automatically.
  • If callback is missing/fails/returns invalid data, SDK does not continue the stale execution.
  • Current payment attempt still resolves through standard failure handling (authorizationFailed path).

Payment Types

PaymentType supports:

  • PaymentType.card

Client Context Metadata

The SDK collects client context and attaches it to authorize requests under meta.clientContext by default.

Collected fields:

  • osType (android)
  • userAgent
  • acceptHeader
  • language
  • screenHeight
  • screenWidth
  • colorDepth
  • timeZoneOffset
  • javaEnabled
  • javaScriptEnabled

Opt-out:

val configuration = Configuration(
    initData = initData,
    option = Options(collectMetadata = false)
)

Card Payments

CardForm + CardPaymentButton

Create a CardForm, then a CardPaymentButton. Elements are decoupled and composed explicitly.

val cardForm = Payrails.createCardForm(
    config = CardFormConfig(
        showCardHolderName = true,
        showStoreInstrumentCheckbox = true
    )
)

val payButton = Payrails.createCardPaymentButton(
    translations = CardPaymenButtonTranslations(label = "Pay Now")
)

payButton.presenter = presenter
payButton.delegate = object : PayrailsCardPaymentButtonDelegate {
    override fun onPaymentButtonClicked(button: CardPaymentButton) {}
    override fun onAuthorizeSuccess(button: CardPaymentButton) {}
    override fun onThreeDSecureChallenge(button: CardPaymentButton) {}
    override fun onAuthorizeFailed(button: CardPaymentButton) {}
}

// In Compose
cardForm.Render()
payButton.Render()

Order does not matter. If CardPaymentButton is created before CardForm, creating CardForm later will auto-attach it to the current button (web-sdk-aligned behavior).

Behavior model:

  • Form mode: if no stored instrument is selected, the button validates/collects card form data, then authorizes.
  • Stored-instrument mode: if a stored instrument is selected, the button authorizes with that instrument and bypasses card form collection/validation.
  • Form interaction reset: if the user focuses/edits card fields, the selected stored instrument is cleared and button behavior returns to form mode.
  • Guardrail: if no stored instrument is selected and no card form is attached, payment does not proceed and the button emits authorization failure.

CardForm Configuration

CardFormConfig controls visibility and behavior:

  • showCardHolderName: Boolean
  • showStoreInstrumentCheckbox: Boolean
  • showSingleExpiryDateField: Boolean
  • layout: List<List<CardFieldType>>?
  • alwaysStoreInstrument: Boolean
  • defaultStoreInstrumentState: DefaultStoreInstrumentState (checked | unchecked)
  • events: CardFormEvents? (onFocus, onChange, onReady, onSaveInstrumentCheckboxChanged)
  • showCardIcon: Boolean (renders built-in Payrails network icons)
  • cardIconAlignment: CardIconAlignment (left or right)
  • styles: CardFormStylesConfig?
  • translations: CardTranslations?

Use CardFormConfig.defaultConfig as a baseline. Payrails.createCardForm(...) reads save-instrument visibility only from CardFormConfig.showStoreInstrumentCheckbox; there is no separate standalone visibility argument on createCardForm(...).

Migration rules:

  • defaultStoreInstrumentState defaults to unchecked. Visibility no longer implies a checked state.
  • alwaysStoreInstrument = true forces submission behavior to store the instrument regardless of toggle state.

Card Form Styles

CardFormStylesConfig lets you style the wrapper, fields, labels, and errors. Key types:

  • CardWrapperStyle
  • CardFieldSpecificStyles
  • CardStyle (alias of Style)

Card Translations

CardTranslations provides:

  • placeholders: CardTranslations.Placeholders
  • labels: CardTranslations.Labels
  • error: CardTranslations.ErrorMessages

Each map is keyed by CardFieldType (alias of ElementType).

When showCardIcon is enabled, the SDK loads network icons from the Payrails assets CDN and updates them as the detected network changes.

BIN length policy (PCI SSC FAQ 1091 aligned):

  • 15-digit PANs (Amex): 6-digit BIN
  • 16-digit PANs (Visa/Mastercard/Discover): 8-digit BIN
  • 17–19 digit PANs or unknown networks: 6-digit BIN

Migration note: if your integration assumes a fixed 8-digit BIN, update routing/lookup logic to accept 6-digit BINs when provided. Do not infer or pad BIN length; rely on the SDK’s bin value.

Card Payment Button Translations

CardPaymenButtonTranslations(label: String?) sets the pay button text.

Card Payment Button Styling

Button appearance is configured on the button component (for example via createCardPaymentButton(buttonStyle = ...)). CardFormStylesConfig no longer includes button styling.

CardButtonStyle is applied in CardPaymentButton.Render for:

  • backgroundColor, textColor
  • cornerRadius
  • borderWidth, borderColor
  • contentPadding

Stored Instrument Card Button

Single instrument mapping:

val cardForm = Payrails.createCardForm()
val button = Payrails.createCardPaymentButton(
    translations = CardPaymenButtonTranslations("Pay")
)
button.setStoredInstrument(instrument)

What’s Next

Troubleshooting Guide