Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Pay button styling #1820

Open
wants to merge 4 commits into
base: feature/google-pay
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions example-app/src/main/res/values-night/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<resources>

<style name="GooglePayButton">
<item name="buttonTheme">light</item>
<style name="AdyenCheckout.GooglePay.Button">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we/merchants still need to do this manually?

<item name="adyenGooglePayButtonTheme">light</item>
</style>
</resources>
4 changes: 2 additions & 2 deletions example-app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@

<style name="AppTheme" parent="MyAppTheme" />

<style name="GooglePayButton">
<item name="buttonTheme">dark</item>
<style name="AdyenCheckout.GooglePay.Button">
<item name="adyenGooglePayButtonTheme">dark</item>
</style>

</resources>
56 changes: 55 additions & 1 deletion googlepay/api/googlepay.api
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,58 @@ public final class com/adyen/checkout/googlepay/GooglePayButtonParameters {
public fun toString ()Ljava/lang/String;
}

public final class com/adyen/checkout/googlepay/GooglePayButtonStyling : android/os/Parcelable {
public static final field CREATOR Landroid/os/Parcelable$Creator;
public fun <init> ()V
public fun <init> (Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;Lcom/adyen/checkout/googlepay/GooglePayButtonType;Ljava/lang/Integer;)V
public synthetic fun <init> (Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;Lcom/adyen/checkout/googlepay/GooglePayButtonType;Ljava/lang/Integer;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;
public final fun component2 ()Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public final fun component3 ()Ljava/lang/Integer;
public final fun copy (Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;Lcom/adyen/checkout/googlepay/GooglePayButtonType;Ljava/lang/Integer;)Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;
public static synthetic fun copy$default (Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;Lcom/adyen/checkout/googlepay/GooglePayButtonType;Ljava/lang/Integer;ILjava/lang/Object;)Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;
public fun describeContents ()I
public fun equals (Ljava/lang/Object;)Z
public final fun getButtonTheme ()Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;
public final fun getButtonType ()Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public final fun getCornerRadius ()Ljava/lang/Integer;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
public fun writeToParcel (Landroid/os/Parcel;I)V
}

public final class com/adyen/checkout/googlepay/GooglePayButtonStyling$Creator : android/os/Parcelable$Creator {
public fun <init> ()V
public final fun createFromParcel (Landroid/os/Parcel;)Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;
public synthetic fun createFromParcel (Landroid/os/Parcel;)Ljava/lang/Object;
public final fun newArray (I)[Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;
public synthetic fun newArray (I)[Ljava/lang/Object;
}

public final class com/adyen/checkout/googlepay/GooglePayButtonTheme : java/lang/Enum {
public static final field DARK Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;
public static final field LIGHT Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public final fun getValue ()I
public static fun valueOf (Ljava/lang/String;)Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;
public static fun values ()[Lcom/adyen/checkout/googlepay/GooglePayButtonTheme;
}

public final class com/adyen/checkout/googlepay/GooglePayButtonType : java/lang/Enum {
public static final field BOOK Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field BUY Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field CHECKOUT Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field DONATE Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field ORDER Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field PAY Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field PLAIN Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static final field SUBSCRIBE Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static fun getEntries ()Lkotlin/enums/EnumEntries;
public final fun getValue ()I
public static fun valueOf (Ljava/lang/String;)Lcom/adyen/checkout/googlepay/GooglePayButtonType;
public static fun values ()[Lcom/adyen/checkout/googlepay/GooglePayButtonType;
}

public final class com/adyen/checkout/googlepay/GooglePayComponent : androidx/lifecycle/ViewModel, com/adyen/checkout/action/core/internal/ActionHandlingComponent, com/adyen/checkout/components/core/internal/ActivityResultHandlingComponent, com/adyen/checkout/components/core/internal/ButtonComponent, com/adyen/checkout/components/core/internal/PaymentComponent, com/adyen/checkout/ui/core/internal/ui/ViewableComponent {
public static final field Companion Lcom/adyen/checkout/googlepay/GooglePayComponent$Companion;
public static final field PAYMENT_METHOD_TYPES Ljava/util/List;
Expand Down Expand Up @@ -106,7 +158,7 @@ public final class com/adyen/checkout/googlepay/GooglePayComponentState : com/ad

public final class com/adyen/checkout/googlepay/GooglePayConfiguration : com/adyen/checkout/components/core/internal/ButtonConfiguration, com/adyen/checkout/components/core/internal/Configuration {
public static final field CREATOR Landroid/os/Parcelable$Creator;
public synthetic fun <init> (Ljava/util/Locale;Lcom/adyen/checkout/core/Environment;Ljava/lang/String;Lcom/adyen/checkout/components/core/AnalyticsConfiguration;Lcom/adyen/checkout/components/core/Amount;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Lcom/adyen/checkout/googlepay/MerchantInfo;Ljava/util/List;Ljava/util/List;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Lcom/adyen/checkout/googlepay/ShippingAddressParameters;Ljava/lang/Boolean;Lcom/adyen/checkout/googlepay/BillingAddressParameters;Lcom/adyen/checkout/action/core/GenericActionConfiguration;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Ljava/util/Locale;Lcom/adyen/checkout/core/Environment;Ljava/lang/String;Lcom/adyen/checkout/components/core/AnalyticsConfiguration;Lcom/adyen/checkout/components/core/Amount;Ljava/lang/Boolean;Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/String;Ljava/lang/String;Lcom/adyen/checkout/googlepay/MerchantInfo;Ljava/util/List;Ljava/util/List;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Ljava/lang/Boolean;Lcom/adyen/checkout/googlepay/ShippingAddressParameters;Ljava/lang/Boolean;Lcom/adyen/checkout/googlepay/BillingAddressParameters;Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;Lcom/adyen/checkout/action/core/GenericActionConfiguration;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun describeContents ()I
public final fun getAllowedAuthMethods ()Ljava/util/List;
public final fun getAllowedCardNetworks ()Ljava/util/List;
Expand All @@ -116,6 +168,7 @@ public final class com/adyen/checkout/googlepay/GooglePayConfiguration : com/ady
public fun getClientKey ()Ljava/lang/String;
public final fun getCountryCode ()Ljava/lang/String;
public fun getEnvironment ()Lcom/adyen/checkout/core/Environment;
public final fun getGooglePayButtonStyling ()Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;
public final fun getGooglePayEnvironment ()Ljava/lang/Integer;
public final fun getMerchantAccount ()Ljava/lang/String;
public final fun getMerchantInfo ()Lcom/adyen/checkout/googlepay/MerchantInfo;
Expand Down Expand Up @@ -150,6 +203,7 @@ public final class com/adyen/checkout/googlepay/GooglePayConfiguration$Builder :
public final fun setCountryCode (Ljava/lang/String;)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
public final fun setEmailRequired (Z)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
public final fun setExistingPaymentMethodRequired (Z)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
public final fun setGooglePayButtonStyling (Lcom/adyen/checkout/googlepay/GooglePayButtonStyling;)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
public final fun setGooglePayEnvironment (I)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
public final fun setMerchantAccount (Ljava/lang/String;)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
public final fun setMerchantInfo (Lcom/adyen/checkout/googlepay/MerchantInfo;)Lcom/adyen/checkout/googlepay/GooglePayConfiguration$Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 Adyen N.V.
*
* This file is open source and available under the MIT license. See the LICENSE file for more info.
*
* Created by oscars on 11/10/2024.
*/

package com.adyen.checkout.googlepay

import android.os.Parcelable
import androidx.annotation.Dimension
import com.google.android.gms.wallet.button.ButtonConstants
import kotlinx.parcelize.Parcelize

/**
* Object to style the Google Pay button. Check [the Google docs](https://developers.google.com/pay/api/android/guides/resources/pay-button-api) for more details.
*
* @param buttonTheme Affects the color scheme of the button.
* @param buttonType Changes the text displayed inside of the button.
* @param cornerRadius Sets the corner radius of the button. For example, passing 16 means the radius will be 16 dp.
*/
@Suppress("MaxLineLength")
@Parcelize
data class GooglePayButtonStyling(
val buttonTheme: GooglePayButtonTheme? = null,
val buttonType: GooglePayButtonType? = null,
@Dimension(Dimension.DP) val cornerRadius: Int? = null,
) : Parcelable

enum class GooglePayButtonTheme(
val value: Int,
) {
LIGHT(ButtonConstants.ButtonTheme.LIGHT),
DARK(ButtonConstants.ButtonTheme.DARK),
}

enum class GooglePayButtonType(
val value: Int,
) {
BUY(ButtonConstants.ButtonType.BUY),
BOOK(ButtonConstants.ButtonType.BOOK),
CHECKOUT(ButtonConstants.ButtonType.CHECKOUT),
DONATE(ButtonConstants.ButtonType.DONATE),
ORDER(ButtonConstants.ButtonType.ORDER),
PAY(ButtonConstants.ButtonType.PAY),
SUBSCRIBE(ButtonConstants.ButtonType.SUBSCRIBE),
PLAIN(ButtonConstants.ButtonType.PLAIN),
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class GooglePayConfiguration private constructor(
val shippingAddressParameters: ShippingAddressParameters?,
val isBillingAddressRequired: Boolean?,
val billingAddressParameters: BillingAddressParameters?,
val googlePayButtonStyling: GooglePayButtonStyling?,
internal val genericActionConfiguration: GenericActionConfiguration,
) : Configuration, ButtonConfiguration {

Expand All @@ -80,6 +81,7 @@ class GooglePayConfiguration private constructor(
private var isBillingAddressRequired: Boolean? = null
private var billingAddressParameters: BillingAddressParameters? = null
private var totalPriceStatus: String? = null
private var googlePayButtonStyling: GooglePayButtonStyling? = null
private var isSubmitButtonVisible: Boolean? = null

/**
Expand Down Expand Up @@ -383,6 +385,16 @@ class GooglePayConfiguration private constructor(
return super.setAmount(amount)
}

/**
* Set a [GooglePayButtonStyling] object for customization of the Google Pay button.
*
* @param googlePayButtonStyling The customization object.
*/
fun setGooglePayButtonStyling(googlePayButtonStyling: GooglePayButtonStyling): Builder {
this.googlePayButtonStyling = googlePayButtonStyling
return this
}

/**
* Sets if submit button will be visible or not.
*
Expand Down Expand Up @@ -419,6 +431,7 @@ class GooglePayConfiguration private constructor(
shippingAddressParameters = shippingAddressParameters,
isBillingAddressRequired = isBillingAddressRequired,
billingAddressParameters = billingAddressParameters,
googlePayButtonStyling = googlePayButtonStyling,
genericActionConfiguration = genericActionConfigurationBuilder.build(),
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
package com.adyen.checkout.googlepay.internal.ui

import android.content.Context
import android.content.res.Resources
import android.util.AttributeSet
import android.view.LayoutInflater
import com.adyen.checkout.googlepay.GooglePayButtonTheme
import com.adyen.checkout.googlepay.GooglePayButtonType
import com.adyen.checkout.googlepay.R
import com.adyen.checkout.googlepay.databinding.ViewGooglePayButtonBinding
import com.adyen.checkout.ui.core.internal.ui.ButtonDelegate
import com.adyen.checkout.ui.core.internal.ui.view.PayButton
import com.google.android.gms.wallet.button.ButtonConstants.ButtonType
import com.google.android.gms.wallet.button.ButtonOptions

internal class GooglePayButtonView @JvmOverloads constructor(
Expand All @@ -25,14 +28,54 @@ internal class GooglePayButtonView @JvmOverloads constructor(

private val binding = ViewGooglePayButtonBinding.inflate(LayoutInflater.from(context), this)

private val styledButtonType: GooglePayButtonType?
private val styledButtonTheme: GooglePayButtonTheme?
private val styledCornerRadius: Int?

init {
val typedArray = context.theme.obtainStyledAttributes(
attrs,
R.styleable.GooglePayButtonView,
defStyleAttr,
R.style.AdyenCheckout_GooglePay_Button,
)
styledButtonType =
typedArray.getInt(R.styleable.GooglePayButtonView_adyenGooglePayButtonType, -1).mapStyledButtonType()
styledButtonTheme =
typedArray.getInt(R.styleable.GooglePayButtonView_adyenGooglePayButtonTheme, -1).mapStyledButtonTheme()
styledCornerRadius =
typedArray.getDimensionPixelSize(R.styleable.GooglePayButtonView_adyenGooglePayButtonCornerRadius, -1)
.mapStyledCornerRadius()
typedArray.recycle()
}

override fun initialize(delegate: ButtonDelegate) {
check(delegate is GooglePayDelegate)

val buttonStyle = delegate.componentParams.googlePayButtonStyling

val buttonType = buttonStyle?.buttonType ?: styledButtonType
val buttonTheme = buttonStyle?.buttonTheme ?: styledButtonTheme
val cornerRadius =
buttonStyle?.cornerRadius?.let { (it * Resources.getSystem().displayMetrics.density).toInt() }
?: styledCornerRadius

binding.payButton.initialize(
ButtonOptions.newBuilder()
.setButtonType(ButtonType.PAY)
.setAllowedPaymentMethods(delegate.getGooglePayButtonParameters().allowedPaymentMethods)
.build(),
ButtonOptions.newBuilder().apply {
if (buttonType != null) {
setButtonType(buttonType.value)
}

if (buttonTheme != null) {
setButtonTheme(buttonTheme.value)
}

if (cornerRadius != null) {
setCornerRadius(cornerRadius)
}

setAllowedPaymentMethods(delegate.getGooglePayButtonParameters().allowedPaymentMethods)
}.build(),
)
}

Expand All @@ -45,4 +88,29 @@ internal class GooglePayButtonView @JvmOverloads constructor(
}

override fun setText(text: String?) = Unit

@Suppress("MagicNumber")
private fun Int.mapStyledButtonType(): GooglePayButtonType? = when (this) {
0 -> GooglePayButtonType.BUY
1 -> GooglePayButtonType.BOOK
2 -> GooglePayButtonType.CHECKOUT
3 -> GooglePayButtonType.DONATE
4 -> GooglePayButtonType.ORDER
5 -> GooglePayButtonType.PAY
6 -> GooglePayButtonType.SUBSCRIBE
7 -> GooglePayButtonType.PLAIN
else -> null
}

private fun Int.mapStyledButtonTheme(): GooglePayButtonTheme? = when (this) {
0 -> GooglePayButtonTheme.LIGHT
1 -> GooglePayButtonTheme.DARK
else -> null
}

private fun Int.mapStyledCornerRadius(): Int? = if (this == -1) {
null
} else {
this
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.adyen.checkout.components.core.internal.ui.PaymentComponentDelegate
import com.adyen.checkout.core.exception.CheckoutException
import com.adyen.checkout.googlepay.GooglePayButtonParameters
import com.adyen.checkout.googlepay.GooglePayComponentState
import com.adyen.checkout.googlepay.internal.ui.model.GooglePayComponentParams
import com.adyen.checkout.ui.core.internal.ui.ButtonDelegate
import com.adyen.checkout.ui.core.internal.ui.ViewProvidingDelegate
import com.google.android.gms.tasks.Task
Expand All @@ -26,6 +27,8 @@ internal interface GooglePayDelegate :
ViewProvidingDelegate,
ButtonDelegate {

override val componentParams: GooglePayComponentParams

val componentStateFlow: Flow<GooglePayComponentState>

val exceptionFlow: Flow<CheckoutException>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.adyen.checkout.components.core.internal.ui.model.ButtonParams
import com.adyen.checkout.components.core.internal.ui.model.CommonComponentParams
import com.adyen.checkout.components.core.internal.ui.model.ComponentParams
import com.adyen.checkout.googlepay.BillingAddressParameters
import com.adyen.checkout.googlepay.GooglePayButtonStyling
import com.adyen.checkout.googlepay.MerchantInfo
import com.adyen.checkout.googlepay.ShippingAddressParameters

Expand All @@ -36,4 +37,5 @@ internal data class GooglePayComponentParams(
val shippingAddressParameters: ShippingAddressParameters?,
val isBillingAddressRequired: Boolean,
val billingAddressParameters: BillingAddressParameters?,
val googlePayButtonStyling: GooglePayButtonStyling?,
) : ComponentParams by commonComponentParams, ButtonParams
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ internal class GooglePayComponentParamsMapper(
shippingAddressParameters = googlePayConfiguration?.shippingAddressParameters,
isBillingAddressRequired = googlePayConfiguration?.isBillingAddressRequired ?: false,
billingAddressParameters = googlePayConfiguration?.billingAddressParameters,
googlePayButtonStyling = googlePayConfiguration?.googlePayButtonStyling,
)
}

Expand Down
1 change: 1 addition & 0 deletions googlepay/src/main/res/layout/view_google_pay_button.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<com.google.android.gms.wallet.button.PayButton
android:id="@+id/payButton"
style="@style/AdyenCheckout.GooglePay.Button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp" />
Expand Down
30 changes: 30 additions & 0 deletions googlepay/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2024 Adyen N.V.
~
~ This file is open source and available under the MIT license. See the LICENSE file for more info.
~
~ Created by oscars on 11/10/2024.
-->

<resources>

<declare-styleable name="GooglePayButtonView">
<attr name="adyenGooglePayButtonType">
<enum name="buy" value="0" />
<enum name="book" value="1" />
<enum name="checkout" value="2" />
<enum name="donate" value="3" />
<enum name="order" value="4" />
<enum name="pay" value="5" />
<enum name="subscribe" value="6" />
<enum name="plain" value="7" />
</attr>

<attr name="adyenGooglePayButtonTheme">
<enum name="light" value="0" />
<enum name="dark" value="1" />
</attr>

<attr name="adyenGooglePayButtonCornerRadius" format="dimension" />
</declare-styleable>
</resources>
15 changes: 15 additions & 0 deletions googlepay/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright (c) 2024 Adyen N.V.
~
~ This file is open source and available under the MIT license. See the LICENSE file for more info.
~
~ Created by oscars on 11/10/2024.
-->

<resources>

<style name="AdyenCheckout.GooglePay" />

<style name="AdyenCheckout.GooglePay.Button" />

</resources>
Loading