Overview
The SDK has two main styling surfaces:
Styles are set at creation time and use Compose-native types (
Color, Dp, TextStyle, PaddingValues).
Card Form Styling
Style Hierarchy
Card form styles cascade from general to specific:Basic Example
Per-Field Styling
Override styles for specific fields:Default Values
The SDK applies these defaults if you don’t provide styles:
Use
CardFormStylesConfig.defaultConfig as a baseline and override only what you need. Custom styles are merged over defaults — you only need to specify properties you want to change.
Spacing Tokens
Control form-level spacing with tokens onCardFormStylesConfig:
null, the hardcoded default is used. These tokens are merged the same way as other style properties — a non-null value wins, null falls through to the fallback. Error spacing is only applied when a field has an active error — fields without errors have no reserved space below them.
Field Content Padding
fieldContentPadding controls the inner padding of every text field — the distance between the field border and the text cursor. When not set, the SDK applies variant-specific defaults:
The
OUTLINED default (16.dp) matches Material3’s standard inset so text sits visibly away from the border. The FILLED default (0.dp) lets text align flush with any decoration you’ve applied to the wrapper.
To override for both variants at once:
CardFormStylesConfig instances and pass the appropriate one based on your chosen FieldVariant.
Label Placement
Choose where field labels appear:LabelPlacement.FLOATING(default) — labels render as Material3 floating labels inside the text field.LabelPlacement.ABOVE— labels render as separateTextcomposables above each field, with a configurable gap.
LabelPlacement.ABOVE, use fieldContentPadding on CardFormStylesConfig to control the inner padding of the text field (the distance from the field edges to the text cursor). The SDK default is start = 16.dp for OUTLINED and start = 0.dp for FILLED; all other sides fall through to Material3 defaults. See Field Content Padding for details.
Field Variant
Choose the Material3 text field style:FieldVariant.OUTLINED(default) —OutlinedTextFieldwith a full border.FieldVariant.FILLED—TextFieldwith a background fill and bottom indicator.
CardStyle Properties
CardStyle (alias of Style) supports these properties:
Pay Button Styling
Button styling is configured onCardPaymentButton, not on the card form.
Basic Example
Button States
The button supports three visual states. Configure each independently:CardButtonStyle Properties
All new tokens participate in state-variant merging — set them on
disabledStyle or loadingStyle to vary by state.
Disable-Until-Valid Pattern
To keep the button disabled until the card form is valid:Card Form Layout
Customize which fields appear and how they’re arranged:Layout Rules
- Each inner list is a row; fields in the same row share space equally
EXPIRATION_DATEis a combined MM/YY field (use withshowSingleExpiryDateField = true)EXPIRATION_MONTH+EXPIRATION_YEARare separate fields (use withoutshowSingleExpiryDateField)- Cannot mix
EXPIRATION_DATEwithEXPIRATION_MONTH/EXPIRATION_YEAR - No duplicate fields allowed
Card Network Icons
Show detected card network icons in the card number field:Translations
Customize all user-facing text:Save Instrument Label Priority
The checkbox label resolves in this order:labels.storeInstrument(if set)labels.saveInstrument(if set)labels.saveCreditCard(if set)"Save instrument"(default)
Stored Instruments
The SDK does not provide a pre-built stored-instruments UI. Retrieve saved cards withsession.getStoredInstruments() (called on the Session returned by Payrails.createSession(...)) and build your own picker using standard Compose components. When the user selects an instrument, call cardPaymentButton.setStoredInstrument(instrument) to pay with it.
Card Brand Selector
For co-branded cards, the Card Brand selector renders automatically inside the card form. Style it viaCardFormStylesConfig.cardBrandSelector; localize the title/subtitle via CardTranslations.
CardBrandSelectorStyle Properties
All fields are optional. Color fields are@ColorInt (ARGB); an unset color falls back to the current MaterialTheme.colorScheme, so the selector adapts to light/dark themes automatically.
Tiles are styled uniformly (no per-scheme styling) per the EU IFR 2015/751 visual-balance requirement — the only per-tile difference is the selected check mark.
Further Reading
- Quick Start — Get a basic integration working first
- API Reference — Full property reference for all style classes
- SDK Concepts — Understand element composition and button modes