From 6f1d5ed0bed327c13aeb8dc3071d4efd72b28811 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Date: Tue, 3 Feb 2026 07:59:26 +0530 Subject: [PATCH 1/5] feat: added support for the layout types --- .../io/hyperswitch/demoapp/MainActivity.kt | 12 +- .../hyperswitch/paymentsheet/PaymentSheet.kt | 120 +++++++++++++++++- 2 files changed, 129 insertions(+), 3 deletions(-) diff --git a/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt b/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt index 1e2c9480..95e36dd9 100644 --- a/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt +++ b/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt @@ -105,6 +105,13 @@ class MainActivity : AppCompatActivity(), HyperInterface { surface = "#F5F8F9".toColorInt(), ) + val layout = PaymentSheet.Layout( + type = PaymentSheet.LayoutType.Tabs, + showOneClickWalletsOnTop = true, + paymentMethodsArrangementForTabs = PaymentSheet.PaymentMethodsArrangement.Default + + ) + val appearance: PaymentSheet.Appearance = PaymentSheet.Appearance( typography = PaymentSheet.Typography( sizeScaleFactor = 1f, fontResId = R.font.montserrat @@ -112,12 +119,13 @@ class MainActivity : AppCompatActivity(), HyperInterface { primaryButton = primaryButton, colorsLight = color1, colorsDark = color2, - theme = PaymentSheet.Theme.Light + theme = PaymentSheet.Theme.Light, + layout = layout ) val configuration = PaymentSheet.Configuration.Builder("Example, Inc.") - //.appearance(appearance) + .appearance(appearance) .defaultBillingDetails(billingDetails).primaryButtonLabel("Purchase ($2.00)") .paymentSheetHeaderLabel("Select payment method") .savedPaymentSheetHeaderLabel("Payment methods").shippingDetails(shippingDetails) diff --git a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt index 51d137ca..4adc19ce 100644 --- a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt +++ b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt @@ -375,7 +375,9 @@ class PaymentSheet internal constructor( val locale: String? = null, - val theme: Theme? = null + val theme: Theme? = null, + + val layout: Layout? = null ) : Parcelable { val bundle: Bundle get() { @@ -387,6 +389,7 @@ class PaymentSheet internal constructor( putBundle("primaryButton", primaryButton?.bundle) putString("locale", locale) putString("theme", theme?.name) + putBundle("layout", layout?.bundle) } } @@ -398,6 +401,7 @@ class PaymentSheet internal constructor( private var primaryButton: PrimaryButton? = null private var theme: Theme? = null private var locale: String? = null + private var layout: Layout? = null fun colorsLight(colors: Colors) = apply { this.colorsLight = colors } fun colorsDark(colors: Colors) = apply { this.colorsDark = colors } @@ -408,6 +412,18 @@ class PaymentSheet internal constructor( fun theme(theme: Theme) = apply { this.theme = theme } fun locale(locale: String) = apply { this.locale = locale } + fun layout(layout: Layout) = apply { this.layout = layout } + + fun build() = Appearance( + colorsLight, + colorsDark, + shapes, + typography, + primaryButton, + locale, + theme, + layout + ) } } @@ -992,6 +1008,108 @@ class PaymentSheet internal constructor( Default, } + enum class LayoutType { + Tabs, + Accordion, + SpacedAccordion + } + + enum class PaymentMethodsArrangement { + Default, + Grid + } + + enum class GroupingBehavior { + GroupByPaymentMethods, + Default + } + + @Parcelize + data class SavedMethodCustomization( + /** + * How to group saved payment methods. + * Can be GroupByPaymentMethods or Default. + */ + val groupingBehavior: GroupingBehavior? = null + ) : Parcelable { + val bundle: Bundle + get() { + return Bundle().apply { + if (groupingBehavior != null) { + val behaviorString = when (groupingBehavior) { + GroupingBehavior.GroupByPaymentMethods -> "groupByPaymentMethods" + GroupingBehavior.Default -> "default" + } + putString("groupingBehavior", behaviorString) + } + } + } + } + + @Parcelize + data class Layout( + /** + * The type of layout to display payment methods in. + * Can be Tabs, Accordion, or SpacedAccordion. + */ + val type: LayoutType? = null, + + /** + * Whether to show one-click wallets (like Google Pay, Apple Pay) at the top of the payment sheet. + */ + val showOneClickWalletsOnTop: Boolean? = null, + + /** + * The arrangement of payment methods in tabs layout. + * Can be Default or Grid. + */ + val paymentMethodsArrangementForTabs: PaymentMethodsArrangement? = null, + + /** + * Whether accordion items should be collapsed by default. + */ + val defaultCollapsed: Boolean? = null, + + /** + * Show radio buttons instead of accordion style. + */ + val radios: Boolean? = null, + + /** + * Add spacing between accordion items. + */ + val spacedAccordionItems: Boolean? = null, + + /** + * Maximum number of accordion items to show before "show more". + */ + val maxAccordionItems: Int? = null, + + /** + * Customization options for saved payment methods display. + */ + val savedMethodCustomization: SavedMethodCustomization? = null + ) : Parcelable { + val bundle: Bundle + get() { + return Bundle().apply { + putString("type", type?.name?.lowercase()) + putBoolean("showOneClickWalletsOnTop", showOneClickWalletsOnTop ?: true) + putString( + "paymentMethodsArrangementForTabs", + paymentMethodsArrangementForTabs?.name?.lowercase() + ) + putBoolean("defaultCollapsed", defaultCollapsed ?: false) + putBoolean("radios", radios ?: false) + putBoolean("spacedAccordionItems", spacedAccordionItems ?: false) + if (maxAccordionItems != null) { + putInt("maxAccordionItems", maxAccordionItems) + } + putBundle("savedMethodCustomization", savedMethodCustomization?.bundle) + } + } + } + /** * A class that presents the individual steps of a payment sheet flow. */ From a59c75d2d35ac6a64ea1fa152126679e8269b40f Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Date: Tue, 3 Feb 2026 08:20:54 +0530 Subject: [PATCH 2/5] chore: removed the spacedAccordion type but functionality exists via flag --- .../src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt | 4 ++-- .../main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt b/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt index 95e36dd9..2d2bea4e 100644 --- a/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt +++ b/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt @@ -108,8 +108,8 @@ class MainActivity : AppCompatActivity(), HyperInterface { val layout = PaymentSheet.Layout( type = PaymentSheet.LayoutType.Tabs, showOneClickWalletsOnTop = true, - paymentMethodsArrangementForTabs = PaymentSheet.PaymentMethodsArrangement.Default - + paymentMethodsArrangementForTabs = PaymentSheet.PaymentMethodsArrangement.Default, + spacedAccordionItems = false ) val appearance: PaymentSheet.Appearance = PaymentSheet.Appearance( diff --git a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt index 4adc19ce..1f01ac51 100644 --- a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt +++ b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt @@ -1010,8 +1010,7 @@ class PaymentSheet internal constructor( enum class LayoutType { Tabs, - Accordion, - SpacedAccordion + Accordion } enum class PaymentMethodsArrangement { @@ -1050,7 +1049,7 @@ class PaymentSheet internal constructor( data class Layout( /** * The type of layout to display payment methods in. - * Can be Tabs, Accordion, or SpacedAccordion. + * Can be Tabs or Accordion. */ val type: LayoutType? = null, From 6b61d41b71b11fd5f3012d3b7fa3a51e0dda9e15 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Date: Sun, 22 Mar 2026 18:31:35 +0530 Subject: [PATCH 3/5] feat: Layout structure change from common to layout specific --- .../io/hyperswitch/demoapp/MainActivity.kt | 7 +- .../hyperswitch/paymentsheet/PaymentSheet.kt | 157 +++++++++++------- 2 files changed, 101 insertions(+), 63 deletions(-) diff --git a/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt b/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt index 2d2bea4e..fa72522d 100644 --- a/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt +++ b/demo-app/src/main/kotlin/io/hyperswitch/demoapp/MainActivity.kt @@ -105,12 +105,7 @@ class MainActivity : AppCompatActivity(), HyperInterface { surface = "#F5F8F9".toColorInt(), ) - val layout = PaymentSheet.Layout( - type = PaymentSheet.LayoutType.Tabs, - showOneClickWalletsOnTop = true, - paymentMethodsArrangementForTabs = PaymentSheet.PaymentMethodsArrangement.Default, - spacedAccordionItems = false - ) + val layout = PaymentSheet.Layout.Tabs() val appearance: PaymentSheet.Appearance = PaymentSheet.Appearance( typography = PaymentSheet.Typography( diff --git a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt index 1f01ac51..113151bc 100644 --- a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt +++ b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt @@ -1008,11 +1008,6 @@ class PaymentSheet internal constructor( Default, } - enum class LayoutType { - Tabs, - Accordion - } - enum class PaymentMethodsArrangement { Default, Grid @@ -1045,68 +1040,116 @@ class PaymentSheet internal constructor( } } - @Parcelize - data class Layout( - /** - * The type of layout to display payment methods in. - * Can be Tabs or Accordion. - */ - val type: LayoutType? = null, + sealed class Layout : Parcelable { + abstract val bundle: Bundle + + @Parcelize + data class Tabs( + val showOneClickWalletsOnTop: Boolean = true, + val paymentMethodsArrangement: PaymentMethodsArrangement = PaymentMethodsArrangement.Default, + val savedMethodCustomization: SavedMethodCustomization? = null + ) : Layout() { + override val bundle: Bundle + get() { + return Bundle().apply { + putString("type", "tabs") + putBoolean("showOneClickWalletsOnTop", showOneClickWalletsOnTop) + putString( + "paymentMethodsArrangementForTabs", + paymentMethodsArrangement.name.lowercase() + ) + putBoolean("defaultCollapsed", false) + putBoolean("radios", false) + putBoolean("spacedAccordionItems", false) + putBundle("savedMethodCustomization", savedMethodCustomization?.bundle) + } + } - /** - * Whether to show one-click wallets (like Google Pay, Apple Pay) at the top of the payment sheet. - */ - val showOneClickWalletsOnTop: Boolean? = null, + class Builder { + private var showOneClickWalletsOnTop: Boolean = true + private var paymentMethodsArrangement: PaymentMethodsArrangement = + PaymentMethodsArrangement.Default + private var savedMethodCustomization: SavedMethodCustomization? = null - /** - * The arrangement of payment methods in tabs layout. - * Can be Default or Grid. - */ - val paymentMethodsArrangementForTabs: PaymentMethodsArrangement? = null, + fun setShowOneClickWalletsOnTop(value: Boolean) = + apply { this.showOneClickWalletsOnTop = value } - /** - * Whether accordion items should be collapsed by default. - */ - val defaultCollapsed: Boolean? = null, - - /** - * Show radio buttons instead of accordion style. - */ - val radios: Boolean? = null, + fun setPaymentMethodsArrangement(value: PaymentMethodsArrangement) = + apply { this.paymentMethodsArrangement = value } - /** - * Add spacing between accordion items. - */ - val spacedAccordionItems: Boolean? = null, + fun setSavedMethodCustomization(value: SavedMethodCustomization) = + apply { this.savedMethodCustomization = value } - /** - * Maximum number of accordion items to show before "show more". - */ - val maxAccordionItems: Int? = null, + fun build() = Tabs( + showOneClickWalletsOnTop, + paymentMethodsArrangement, + savedMethodCustomization + ) + } + } - /** - * Customization options for saved payment methods display. - */ - val savedMethodCustomization: SavedMethodCustomization? = null - ) : Parcelable { - val bundle: Bundle - get() { - return Bundle().apply { - putString("type", type?.name?.lowercase()) - putBoolean("showOneClickWalletsOnTop", showOneClickWalletsOnTop ?: true) - putString( - "paymentMethodsArrangementForTabs", - paymentMethodsArrangementForTabs?.name?.lowercase() - ) - putBoolean("defaultCollapsed", defaultCollapsed ?: false) - putBoolean("radios", radios ?: false) - putBoolean("spacedAccordionItems", spacedAccordionItems ?: false) - if (maxAccordionItems != null) { + @Parcelize + data class Accordion( + val showOneClickWalletsOnTop: Boolean = true, + val defaultCollapsed: Boolean = false, + val radios: Boolean = false, + val spacedAccordionItems: Boolean = false, + val maxAccordionItems: Int = 4, + val savedMethodCustomization: SavedMethodCustomization? = null + ) : Layout() { + override val bundle: Bundle + get() { + return Bundle().apply { + putString("type", "accordion") + putBoolean("showOneClickWalletsOnTop", showOneClickWalletsOnTop) + putString( + "paymentMethodsArrangementForTabs", + PaymentMethodsArrangement.Default.name.lowercase() + ) + putBoolean("defaultCollapsed", defaultCollapsed) + putBoolean("radios", radios) + putBoolean("spacedAccordionItems", spacedAccordionItems) putInt("maxAccordionItems", maxAccordionItems) + putBundle("savedMethodCustomization", savedMethodCustomization?.bundle) } - putBundle("savedMethodCustomization", savedMethodCustomization?.bundle) } + + class Builder { + private var showOneClickWalletsOnTop: Boolean = true + private var defaultCollapsed: Boolean = false + private var radios: Boolean = false + private var spacedAccordionItems: Boolean = false + private var maxAccordionItems: Int = 4 + private var savedMethodCustomization: SavedMethodCustomization? = null + + fun setShowOneClickWalletsOnTop(value: Boolean) = + apply { this.showOneClickWalletsOnTop = value } + + fun setDefaultCollapsed(value: Boolean) = + apply { this.defaultCollapsed = value } + + fun setRadios(value: Boolean) = + apply { this.radios = value } + + fun setSpacedAccordionItems(value: Boolean) = + apply { this.spacedAccordionItems = value } + + fun setMaxAccordionItems(value: Int) = + apply { this.maxAccordionItems = value } + + fun setSavedMethodCustomization(value: SavedMethodCustomization) = + apply { this.savedMethodCustomization = value } + + fun build() = Accordion( + showOneClickWalletsOnTop, + defaultCollapsed, + radios, + spacedAccordionItems, + maxAccordionItems, + savedMethodCustomization + ) } + } } /** From 8c1bc7de54abe3b2ba1ea6fff553040ed6330b4b Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Date: Sun, 22 Mar 2026 18:42:02 +0530 Subject: [PATCH 4/5] fix: removed the unnecessary builder --- .../kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt index 113151bc..767a81cd 100644 --- a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt +++ b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt @@ -414,16 +414,6 @@ class PaymentSheet internal constructor( fun locale(locale: String) = apply { this.locale = locale } fun layout(layout: Layout) = apply { this.layout = layout } - fun build() = Appearance( - colorsLight, - colorsDark, - shapes, - typography, - primaryButton, - locale, - theme, - layout - ) } } From 59a3c73ad6f107d413a7b0f7ad9c5855d76539f8 Mon Sep 17 00:00:00 2001 From: Pradeep Kumar Date: Thu, 26 Mar 2026 15:29:56 +0530 Subject: [PATCH 5/5] chore: Added GroupingBehavior type in layout type --- .../hyperswitch/paymentsheet/PaymentSheet.kt | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt index 767a81cd..a688688e 100644 --- a/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt +++ b/hyperswitch-sdk-android-api/src/main/kotlin/io/hyperswitch/paymentsheet/PaymentSheet.kt @@ -1003,16 +1003,22 @@ class PaymentSheet internal constructor( Grid } - enum class GroupingBehavior { - GroupByPaymentMethods, - Default + @Parcelize + data class GroupingBehavior( + val displayInSeparateScreen: Boolean = true, + val groupByPaymentMethods: Boolean = false + ) : Parcelable { + val bundle: Bundle + get() = Bundle().apply { + putBoolean("displayInSeparateScreen", displayInSeparateScreen) + putBoolean("groupByPaymentMethods", groupByPaymentMethods) + } } @Parcelize data class SavedMethodCustomization( /** - * How to group saved payment methods. - * Can be GroupByPaymentMethods or Default. + * How to group and display saved payment methods. */ val groupingBehavior: GroupingBehavior? = null ) : Parcelable { @@ -1020,11 +1026,7 @@ class PaymentSheet internal constructor( get() { return Bundle().apply { if (groupingBehavior != null) { - val behaviorString = when (groupingBehavior) { - GroupingBehavior.GroupByPaymentMethods -> "groupByPaymentMethods" - GroupingBehavior.Default -> "default" - } - putString("groupingBehavior", behaviorString) + putBundle("groupingBehavior", groupingBehavior.bundle) } } }