Search Overlay

Form Field Styling

This page provides guidelines on customizing the checkout experience for card payments in Android apps using the Paysafe SDK. You can style and theme form fields in two primary ways:

  1. Applying a global theme to all fields.
  2. Updating each field's appearance individually.

Global theming with PSTheme

The PSTheme in the Paysafe SDK allows for a consistent look and feel across all card payment fields (card number, holder name, CVV, expiry date) and expiry picker/dialog.

Structure of PSTheme

The fields that can be styled:

<resources>
<declare-styleable name="PSCardView">
<attr name="psBackgroundColor" format="color" />
<attr name="psBorderColor" format="color" />
<attr name="psFocusedBorderColor" format="color" />
<attr name="psBorderCornerRadius" format="dimension" />
<attr name="psErrorColor" format="color" />
<attr name="psTextInputColor" format="color" />
<attr name="psTextInputFontSize" format="dimension" />
<attr name="psTextInputFontFamily" format="string" />
<attr name="psPlaceholderColor" format="color" />
<attr name="psPlaceholderFontSize" format="dimension" />
<attr name="psPlaceholderFontFamily" format="string" />
<attr name="psHintColor" format="color" />
<attr name="psHintFontSize" format="dimension" />
<attr name="psHintFontFamily" format="string" />
<attr name="psExpiryPickerButtonBackgroundColor" format="color" />
<attr name="psExpiryPickerButtonTextColor" format="color" />
<attr name="psHint" format="string" />
<attr name="psAnimateTopPlaceholderLabel" format="boolean" />
</declare-styleable>

<declare-styleable name="PSCvvView">
<attr name="psIsMasked" format="boolean" />
</declare-styleable>

<declare-styleable name="PSCardNumberView">
<attr name="psSeparator" format="enum">
<enum name="whitespace" value="0" />
<enum name="none" value="1" />
<enum name="dash" value="2" />
<enum name="slash" value="3" />
</attr>
</declare-styleable>
</resources>

The default PSTheme style definition can be found below:

<style name="PSTheme">
<item name="psBackgroundColor">@color/ps_card_background</item>
<item name="psBorderColor">@color/ps_card_border</item>
<item name="psFocusedBorderColor">@color/ps_card_focused_border</item>
<item name="psBorderCornerRadius">@dimen/ps_card_border_corner_radius</item>
<item name="psErrorColor">@color/ps_card_error</item>
<item name="psTextInputColor">@color/ps_card_text_input</item>
<item name="psTextInputFontSize">@dimen/ps_card_text_input_font_size</item>
<item name="psTextInputFontFamily">@null</item>
<item name="psPlaceholderColor">@color/ps_card_placeholder</item>
<item name="psPlaceholderFontSize">@dimen/ps_card_placeholder_font_size</item>
<item name="psPlaceholderFontFamily">@null</item>
<item name="psHintColor">@color/ps_card_hint</item>
<item name="psHintFontSize">@dimen/ps_card_hint_font_size</item>
<item name="psHintFontFamily">@null</item>
<item name="psExpiryPickerButtonBackgroundColor">@color/ps_expiry_picker_button_background</item>
<item name="psExpiryPickerButtonTextColor">@color/ps_expiry_picker_button_text</item>
</style>

The default <resources> values:

<resources>
<color name="ps_card_background">#FFFFFFFF</color>
<color name="ps_card_border">#FF787878</color>
<color name="ps_card_focused_border">#FF000000</color>
<color name="ps_card_error">#FFFF0000</color>
<color name="ps_card_text_input">#FF000000</color>
<color name="ps_card_placeholder">#FF000000</color>
<color name="ps_card_hint">#FF808080</color>
<color name="ps_expiry_picker_button_background">#FF000000</color>
<color name="ps_expiry_picker_button_text">#FFFFFFFF</color>
</resources>

<resources>
<color name="ps_card_background">#FF000000</color>
<color name="ps_card_border">#FFD3D3D3</color>
<color name="ps_card_focused_border">#FFFFFFFF</color>
<color name="ps_card_error">#FFAA0000</color>
<color name="ps_card_text_input">#FFFFFFFF</color>
<color name="ps_card_placeholder">#FFFFFFFF</color>
<color name="ps_card_hint">#FFD3D3D3</color>
<color name="ps_expiry_picker_button_background">#FFFFFFFF</color>
<color name="ps_expiry_picker_button_text">#FF000000</color>
</resources>

<resources>
<dimen name="ps_card_border_corner_radius">0dp</dimen>
<dimen name="ps_card_text_input_font_size">16sp</dimen>
<dimen name="ps_card_placeholder_font_size">16sp</dimen>
<dimen name="ps_card_hint_font_size">16sp</dimen>
</resources>

Internally each form field loads the PSTheme attributes defined inside the XML either from the field definition, or from the default PSTheme style which will result in a PSTheme data class described below:

/**
* PSTheme used for styling Paysafe components
*/
data class PSTheme(
/** Card component background color. */
@ColorInt
var backgroundColor: Int,
/** Card component border color in default state. */
@ColorInt
var borderColor: Int,
/** Card component border color in focused state. */
@ColorInt
var focusedBorderColor: Int,
/** Card component border corner radius. */
@Dimension
var borderCornerRadius: Float,
/** Card component border & placeholder color for invalid/error state. */
@ColorInt
var errorColor: Int,
/** Card component text input color. */
@ColorInt
var textInputColor: Int,
/** Card component text input font size. */
@Dimension
var textInputFontSize: Float,
/** Card component text input font family. */
@FontRes
var textInputFontFamily: Int? = null,
/** Card component placeholder text color. */
@ColorInt
var placeholderColor: Int,
/** Card component placeholder text font size. */
@Dimension
var placeholderFontSize: Float,
/** Card component placeholder text font family. */
@FontRes
var placeholderFontFamily: Int? = null,
/** Card component hint text color. */
@ColorInt
var hintColor: Int,
/** Card component hint text font size. */
@Dimension
var hintFontSize: Float,
/** Card component hint text font family. */
@FontRes
var hintFontFamily: Int? = null,
/** Card component expiry picker/dialog button background color. */
@ColorInt
var expiryPickerButtonBackgroundColor: Int,
/** Card component expiry picker/dialog button text color. */
@ColorInt
var expiryPickerButtonTextColor: Int
)

Configure custom PSTheme

The Paysafe SDK allows for theme configuration by extending the predefined style PSTheme if only some properties need to be changed, or by creating a new style if complete customization is required.

Example of a custom theme: 

<style name="CustomTheme" parent="PSTheme">
<item name="psBackgroundColor">@color/black</item>
<item name="psBorderColor">@color/grey</item>
<item name="psFocusedBorderColor">@color/white</item>
<item name="psBorderCornerRadius">@dimen/primary_border_radius</item>
<item name="psErrorColor">@color/error</item>
<item name="psTextInputColor">@color/primary_text</item>
<item name="psTextInputFontSize">@dimen/primary_text_size</item>
<item name="psTextInputFontFamily">@font/primary_font_name</item>
<item name="psPlaceholderColor">@color/secondary_text</item>
<item name="psPlaceholderFontSize">@dimen/secondary_text_size</item>
<item name="psPlaceholderFontFamily">@font/primary_font_name</item>
<item name="psHintColor">@color/light_text</item>
<item name="psHintFontSize">@dimen/light_text_size</item>
<item name="psHintFontFamily">@font/light_font_name</item>
<item name="psExpiryPickerButtonBackgroundColor">@color/dialog_button_background</item>
<item name="psExpiryPickerButtonTextColor">@color/dialog_button_text</item>
</style>

This can be applied to any field:

<com.paysafe.android.hostedfields.holdername.PSCardholderNameView
android:id="@+id/cardholderNameView"
style="@style/CustomTheme"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/otherViewId" />

Individual field styling

To update the "look and feel" of an individual field, you can update an individual theme property directly inside the XML.

<com.paysafe.android.hostedfields.cardnumber.PSCardNumberView
android:id="@+id/cardNumberView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/otherViewId"
app:psAnimateTopPlaceholderLabel="false"
app:psHint="Custom hint"
app:psBackgroundColor="#55FF0000" />

Dynamic style updates

  • Change styles dynamically for different states (normal/valid, error).
  • Customize each PSTheme property, such as background color, border color, corner radius, text color, font size and font family.

For more information about the available events/ callbacks, see Event Handling and Helper Functions.

Example using onInvalid event:

cardNumberView.onEvent = { event ->
when (event) {
PSCardFieldInputEvent.VALID -> cardNumberView.psTheme.backgroundColor = Color.MAGENTA
PSCardFieldInputEvent.INVALID -> cardNumberView.psTheme.backgroundColor = Color.GREEN
else -> {}
}
}

Summary

You can create a customized checkout experience in your Android apps by using PSTheme for a consistent global look, only customizing individual fields as needed. It's important to balance aesthetics with functionality and accessibility to ensure a smooth and inclusive customer experience.