From 33ef7bb1aa256b7bbf067ea662cc7efe2609189c Mon Sep 17 00:00:00 2001 From: josephj Date: Thu, 25 Mar 2021 09:52:19 +0100 Subject: [PATCH 01/63] Handle card component error in PreselectedStoredPaymentMethodFragment --- .../PreselectedStoredPaymentMethodFragment.kt | 9 ++++++++ .../PreselectedStoredPaymentViewModel.kt | 22 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentMethodFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentMethodFragment.kt index 0db62fd30f..f1607cc11f 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentMethodFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentMethodFragment.kt @@ -15,6 +15,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.view.isVisible +import com.adyen.checkout.components.ComponentError import com.adyen.checkout.components.PaymentComponent import com.adyen.checkout.components.PaymentComponentState import com.adyen.checkout.components.api.ImageLoader @@ -33,6 +34,7 @@ import com.adyen.checkout.dropin.ui.base.DropInBottomSheetDialogFragment import com.adyen.checkout.dropin.ui.paymentmethods.GenericStoredModel import com.adyen.checkout.dropin.ui.paymentmethods.StoredCardModel import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.AwaitingComponentInitialization +import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.PaymentError import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.RequestPayment import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.ShowStoredPaymentDialog import com.adyen.checkout.dropin.ui.viewModelsFactory @@ -62,6 +64,7 @@ class PreselectedStoredPaymentMethodFragment : DropInBottomSheetDialogFragment() when (it) { is ShowStoredPaymentDialog -> protocol.showStoredComponentDialog(storedPaymentMethod, true) is RequestPayment -> protocol.requestPaymentsCall(it.componentState) + is PaymentError -> handleError(it.componentError) else -> { // do nothing } } @@ -74,6 +77,11 @@ class PreselectedStoredPaymentMethodFragment : DropInBottomSheetDialogFragment() else binding.progressBar.hide() } + private fun handleError(componentError: ComponentError) { + Logger.e(TAG, componentError.errorMessage) + protocol.showError(getString(R.string.component_error), componentError.errorMessage, true) + } + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { storedPaymentMethod = arguments?.getParcelable(STORED_PAYMENT_KEY) ?: StoredPaymentMethod() @@ -88,6 +96,7 @@ class PreselectedStoredPaymentMethodFragment : DropInBottomSheetDialogFragment() component = getComponentFor(this, storedPaymentMethod, dropInViewModel.dropInConfiguration) component.observe(viewLifecycleOwner, storedPaymentViewModel::componentStateChanged) + component.observeErrors(viewLifecycleOwner, storedPaymentViewModel::componentErrorOccurred) binding = FragmentStoredPaymentMethodBinding.inflate(inflater, container, false) return binding.root diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt index 3010655145..39decdcd60 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt @@ -11,6 +11,7 @@ package com.adyen.checkout.dropin.ui.stored import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel +import com.adyen.checkout.components.ComponentError import com.adyen.checkout.components.PaymentComponentState import com.adyen.checkout.components.model.paymentmethods.StoredPaymentMethod import com.adyen.checkout.components.model.payments.request.PaymentMethodDetails @@ -19,6 +20,7 @@ import com.adyen.checkout.core.log.Logger import com.adyen.checkout.dropin.ui.paymentmethods.StoredPaymentMethodModel import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.AwaitingComponentInitialization import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.Idle +import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.PaymentError import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.RequestPayment import com.adyen.checkout.dropin.ui.stored.PreselectedStoredState.ShowStoredPaymentDialog @@ -38,6 +40,7 @@ class PreselectedStoredPaymentViewModel( val componentFragmentState: LiveData = componentFragmentStateMutable private var componentState: PaymentComponentState? = null + private var lastComponentError: ComponentError? = null init { storedPaymentMethodMutableLiveData.value = makeStoredModel(storedPaymentMethod) @@ -66,14 +69,32 @@ class PreselectedStoredPaymentViewModel( "payButtonClicked - componentState.isReady: ${componentState?.isReady} - " + "fragmentState: $fragmentState" ) + val componentError = lastComponentError val state = when { componentRequiresInput -> ShowStoredPaymentDialog + componentError != null -> PaymentError(componentError) componentState?.isReady == true -> RequestPayment(componentState) else -> AwaitingComponentInitialization } Logger.v(TAG, "payButtonClicked - setting fragment state $state") componentFragmentStateMutable.value = state } + + fun componentErrorOccurred(componentError: ComponentError) { + lastComponentError = componentError + val fragmentState = componentFragmentStateMutable.value + val componentState = componentState + Logger.v( + TAG, + "componentErrorOccurred - componentState.isReady: ${componentState?.isReady} - " + + "fragmentState: $fragmentState" + ) + if (fragmentState is AwaitingComponentInitialization) { + val state = PaymentError(componentError) + Logger.v(TAG, "componentErrorOccurred - setting fragment state $state") + componentFragmentStateMutable.value = state + } + } } sealed class PreselectedStoredState { @@ -81,6 +102,7 @@ sealed class PreselectedStoredState { object ShowStoredPaymentDialog : PreselectedStoredState() object AwaitingComponentInitialization : PreselectedStoredState() class RequestPayment(val componentState: PaymentComponentState) : PreselectedStoredState() + class PaymentError(val componentError: ComponentError) : PreselectedStoredState() override fun toString(): String = this::class.simpleName ?: "" } From 50805c5bf484afd1d4f77b8f559a0933e39ad6fd Mon Sep 17 00:00:00 2001 From: josephj Date: Fri, 26 Mar 2021 10:04:28 +0100 Subject: [PATCH 02/63] Fix manifest package names --- dotpay/src/main/AndroidManifest.xml | 2 +- entercash/src/main/AndroidManifest.xml | 2 +- eps/src/main/AndroidManifest.xml | 2 +- ideal/src/main/AndroidManifest.xml | 2 +- issuer-list/src/main/AndroidManifest.xml | 2 +- mbway/src/main/AndroidManifest.xml | 2 +- molpay/src/main/AndroidManifest.xml | 2 +- openbanking/src/main/AndroidManifest.xml | 2 +- sepa/src/main/AndroidManifest.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dotpay/src/main/AndroidManifest.xml b/dotpay/src/main/AndroidManifest.xml index 7e8321da88..a1b8cfce65 100644 --- a/dotpay/src/main/AndroidManifest.xml +++ b/dotpay/src/main/AndroidManifest.xml @@ -7,4 +7,4 @@ --> + package="com.adyen.checkout.dotpay" /> diff --git a/entercash/src/main/AndroidManifest.xml b/entercash/src/main/AndroidManifest.xml index 5e14ff208a..313352ba59 100644 --- a/entercash/src/main/AndroidManifest.xml +++ b/entercash/src/main/AndroidManifest.xml @@ -7,4 +7,4 @@ --> + package="com.adyen.checkout.entercash" /> diff --git a/eps/src/main/AndroidManifest.xml b/eps/src/main/AndroidManifest.xml index f67e02e26b..7666c512c2 100644 --- a/eps/src/main/AndroidManifest.xml +++ b/eps/src/main/AndroidManifest.xml @@ -7,4 +7,4 @@ --> + package="com.adyen.checkout.eps" /> diff --git a/ideal/src/main/AndroidManifest.xml b/ideal/src/main/AndroidManifest.xml index 7e476f3ad1..25e3d7af3d 100644 --- a/ideal/src/main/AndroidManifest.xml +++ b/ideal/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ + package="com.adyen.checkout.ideal" /> diff --git a/issuer-list/src/main/AndroidManifest.xml b/issuer-list/src/main/AndroidManifest.xml index 76e770e388..73b693c6f7 100644 --- a/issuer-list/src/main/AndroidManifest.xml +++ b/issuer-list/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ + package="com.adyen.checkout.issuerlist" /> diff --git a/mbway/src/main/AndroidManifest.xml b/mbway/src/main/AndroidManifest.xml index 059405b136..50a71213d6 100644 --- a/mbway/src/main/AndroidManifest.xml +++ b/mbway/src/main/AndroidManifest.xml @@ -1,2 +1,2 @@ + package="com.adyen.checkout.mbway" /> diff --git a/molpay/src/main/AndroidManifest.xml b/molpay/src/main/AndroidManifest.xml index 1f18787ad9..fdadec83bd 100644 --- a/molpay/src/main/AndroidManifest.xml +++ b/molpay/src/main/AndroidManifest.xml @@ -7,4 +7,4 @@ --> + package="com.adyen.checkout.molpay" /> diff --git a/openbanking/src/main/AndroidManifest.xml b/openbanking/src/main/AndroidManifest.xml index 4851e7cce4..49be03fb13 100644 --- a/openbanking/src/main/AndroidManifest.xml +++ b/openbanking/src/main/AndroidManifest.xml @@ -7,4 +7,4 @@ --> + package="com.adyen.checkout.openbanking" /> diff --git a/sepa/src/main/AndroidManifest.xml b/sepa/src/main/AndroidManifest.xml index 7b574f9e38..e418d2f3bb 100644 --- a/sepa/src/main/AndroidManifest.xml +++ b/sepa/src/main/AndroidManifest.xml @@ -1,3 +1,3 @@ + package="com.adyen.checkout.sepa" /> From 9e6a7c70f60bd02a377bb8011a483248bf9c7ed9 Mon Sep 17 00:00:00 2001 From: josephj Date: Fri, 26 Mar 2021 10:14:42 +0100 Subject: [PATCH 03/63] Fix gradle artifacts name and description --- bcmc/build.gradle | 4 ++-- dotpay/build.gradle | 4 ++-- entercash/build.gradle | 4 ++-- eps/build.gradle | 4 ++-- ideal/build.gradle | 4 ++-- issuer-list/build.gradle | 4 ++-- mbway/build.gradle | 4 ++-- molpay/build.gradle | 4 ++-- openbanking/build.gradle | 4 ++-- sepa/build.gradle | 4 ++-- wechatpay/build.gradle | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/bcmc/build.gradle b/bcmc/build.gradle index 6a31fa6384..02b3bac9e4 100644 --- a/bcmc/build.gradle +++ b/bcmc/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "bcmc" -ext.mavenArtifactName = "Adyen checkout bcmc UI component" -ext.mavenArtifactDescription = "Adyen checkout bcmc UI component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout BCMC component" +ext.mavenArtifactDescription = "Adyen checkout BCMC component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/dotpay/build.gradle b/dotpay/build.gradle index 33a6ea380d..aecf56ddc6 100644 --- a/dotpay/build.gradle +++ b/dotpay/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "dotpay" -ext.mavenArtifactName = "Adyen checkout dotpay ui component" -ext.mavenArtifactDescription = "Adyen checkout dotpay ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout Dotpay component" +ext.mavenArtifactDescription = "Adyen checkout Dotpay component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/entercash/build.gradle b/entercash/build.gradle index aed232efe4..49ea38725e 100644 --- a/entercash/build.gradle +++ b/entercash/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "entercash" -ext.mavenArtifactName = "Adyen checkout entercash ui component" -ext.mavenArtifactDescription = "Adyen checkout entercash ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout Entercash component" +ext.mavenArtifactDescription = "Adyen checkout Entercash component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/eps/build.gradle b/eps/build.gradle index 91b1890515..b9702582cf 100644 --- a/eps/build.gradle +++ b/eps/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "eps" -ext.mavenArtifactName = "Adyen checkout eps ui component" -ext.mavenArtifactDescription = "Adyen checkout eps ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout EPS component" +ext.mavenArtifactDescription = "Adyen checkout EPS component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/ideal/build.gradle b/ideal/build.gradle index 2b1944de2d..1b44954eb0 100644 --- a/ideal/build.gradle +++ b/ideal/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "ideal" -ext.mavenArtifactName = "Adyen checkout ideal ui component" -ext.mavenArtifactDescription = "Adyen checkout ideal ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout iDEAL component" +ext.mavenArtifactDescription = "Adyen checkout iDEAL component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/issuer-list/build.gradle b/issuer-list/build.gradle index b121a68efc..0174f537e2 100644 --- a/issuer-list/build.gradle +++ b/issuer-list/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "issuer-list" -ext.mavenArtifactName = "Adyen checkout issuer list ui component" -ext.mavenArtifactDescription = "Adyen checkout issuer list ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout issuer list component" +ext.mavenArtifactDescription = "Adyen checkout issuer list component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/mbway/build.gradle b/mbway/build.gradle index 77e1b4633c..6ffff5bd0f 100644 --- a/mbway/build.gradle +++ b/mbway/build.gradle @@ -12,8 +12,8 @@ plugins { } ext.mavenArtifactId = "mbway" -ext.mavenArtifactName = "Adyen checkout mbway-ui component" -ext.mavenArtifactDescription = "Adyen checkout mbway-ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout MB WAY component" +ext.mavenArtifactDescription = "Adyen checkout MB WAY component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/molpay/build.gradle b/molpay/build.gradle index dc63e68576..4c30d7f155 100644 --- a/molpay/build.gradle +++ b/molpay/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "molpay" -ext.mavenArtifactName = "Adyen checkout molepay ui component" -ext.mavenArtifactDescription = "Adyen checkout molepay ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout MOLPay component" +ext.mavenArtifactDescription = "Adyen checkout MOLPay component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/openbanking/build.gradle b/openbanking/build.gradle index 034d737fc1..82fc507f50 100644 --- a/openbanking/build.gradle +++ b/openbanking/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "openbanking" -ext.mavenArtifactName = "Adyen checkout openbanking ui component" -ext.mavenArtifactDescription = "Adyen checkout openbanking ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout Open Banking component" +ext.mavenArtifactDescription = "Adyen checkout Open Banking component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/sepa/build.gradle b/sepa/build.gradle index b382fb817b..dd0f39b44a 100644 --- a/sepa/build.gradle +++ b/sepa/build.gradle @@ -13,8 +13,8 @@ plugins { // Maven artifact ext.mavenArtifactId = "sepa" -ext.mavenArtifactName = "Adyen checkout sepa-ui component" -ext.mavenArtifactDescription = "Adyen checkout sepa-ui component client for Adyen's Checkout API." +ext.mavenArtifactName = "Adyen checkout SEPA component" +ext.mavenArtifactDescription = "Adyen checkout SEPA component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" diff --git a/wechatpay/build.gradle b/wechatpay/build.gradle index 449f89cb88..d168e562e2 100644 --- a/wechatpay/build.gradle +++ b/wechatpay/build.gradle @@ -13,7 +13,7 @@ plugins { ext.mavenArtifactId = "wechatpay" ext.mavenArtifactName = "Adyen Checkout WeChat Pay component" -ext.mavenArtifactDescription = "Adyen checkout wechatpay-base component client for Adyen's Checkout API." +ext.mavenArtifactDescription = "Adyen checkout WeChat Pay component client for Adyen's Checkout API." apply from: "../config/gradle/sharedTasks.gradle" From a4dfe9084f5a38949886386e3d16b3a31bee25cf Mon Sep 17 00:00:00 2001 From: josephj Date: Fri, 26 Mar 2021 11:09:27 +0100 Subject: [PATCH 04/63] Fix R package imports --- .../adyen/checkout/issuerlist/IssuerListRecyclerAdapter.java | 1 - .../com/adyen/checkout/issuerlist/IssuerListRecyclerView.java | 1 - .../com/adyen/checkout/issuerlist/IssuerListSpinnerAdapter.java | 1 - .../com/adyen/checkout/issuerlist/IssuerListSpinnerView.java | 1 - mbway/src/main/java/com/adyen/checkout/mbway/MBWayOutputData.kt | 1 - mbway/src/main/java/com/adyen/checkout/mbway/MBWayView.kt | 1 - .../java/com/adyen/checkout/mbway/country/CountryAdapter.kt | 2 +- .../java/com/adyen/checkout/mbway/country/CountryViewHolder.kt | 2 +- sepa/src/main/java/com/adyen/checkout/sepa/SepaOutputData.java | 1 - sepa/src/main/java/com/adyen/checkout/sepa/SepaView.java | 1 - 10 files changed, 2 insertions(+), 10 deletions(-) diff --git a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerAdapter.java b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerAdapter.java index e4a2751cb9..660be37d00 100644 --- a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerAdapter.java +++ b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerAdapter.java @@ -19,7 +19,6 @@ import com.adyen.checkout.components.api.ImageLoader; import com.adyen.checkout.components.ui.adapter.ClickableListRecyclerAdapter; import com.adyen.checkout.components.ui.view.RoundCornerImageView; -import com.adyen.checkout.issuerlist.ui.R; import java.util.List; diff --git a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerView.java b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerView.java index e050f50bee..f9d5baabb3 100644 --- a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerView.java +++ b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListRecyclerView.java @@ -26,7 +26,6 @@ import com.adyen.checkout.components.ui.view.AdyenLinearLayout; import com.adyen.checkout.core.log.LogUtil; import com.adyen.checkout.core.log.Logger; -import com.adyen.checkout.issuerlist.ui.R; import java.util.Collections; import java.util.List; diff --git a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerAdapter.java b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerAdapter.java index 26c6024d01..6cd4f853d8 100644 --- a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerAdapter.java +++ b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerAdapter.java @@ -20,7 +20,6 @@ import androidx.appcompat.widget.AppCompatTextView; import com.adyen.checkout.components.api.ImageLoader; -import com.adyen.checkout.issuerlist.ui.R; import java.util.List; diff --git a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerView.java b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerView.java index 32a27e8a45..090dd8406a 100644 --- a/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerView.java +++ b/issuer-list/src/main/java/com/adyen/checkout/issuerlist/IssuerListSpinnerView.java @@ -26,7 +26,6 @@ import com.adyen.checkout.components.ui.view.AdyenLinearLayout; import com.adyen.checkout.core.log.LogUtil; import com.adyen.checkout.core.log.Logger; -import com.adyen.checkout.issuerlist.ui.R; import java.util.Collections; import java.util.List; diff --git a/mbway/src/main/java/com/adyen/checkout/mbway/MBWayOutputData.kt b/mbway/src/main/java/com/adyen/checkout/mbway/MBWayOutputData.kt index 3e6ca8159d..9b164f315e 100644 --- a/mbway/src/main/java/com/adyen/checkout/mbway/MBWayOutputData.kt +++ b/mbway/src/main/java/com/adyen/checkout/mbway/MBWayOutputData.kt @@ -12,7 +12,6 @@ import com.adyen.checkout.components.base.OutputData import com.adyen.checkout.components.ui.FieldState import com.adyen.checkout.components.ui.Validation import com.adyen.checkout.components.util.ValidationUtils -import com.adyen.checkout.mbway.ui.R class MBWayOutputData(mobilePhoneNumber: String) : OutputData { diff --git a/mbway/src/main/java/com/adyen/checkout/mbway/MBWayView.kt b/mbway/src/main/java/com/adyen/checkout/mbway/MBWayView.kt index 5715f44253..ae70e95753 100644 --- a/mbway/src/main/java/com/adyen/checkout/mbway/MBWayView.kt +++ b/mbway/src/main/java/com/adyen/checkout/mbway/MBWayView.kt @@ -27,7 +27,6 @@ import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger import com.adyen.checkout.mbway.country.CountryAdapter import com.adyen.checkout.mbway.country.CountryModel -import com.adyen.checkout.mbway.ui.R import com.google.android.material.textfield.TextInputLayout import java.util.Locale diff --git a/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryAdapter.kt b/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryAdapter.kt index 5a24ad1474..320c5f3e70 100644 --- a/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryAdapter.kt +++ b/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryAdapter.kt @@ -15,7 +15,7 @@ import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.Filter import android.widget.Filterable -import com.adyen.checkout.mbway.ui.R +import com.adyen.checkout.mbway.R class CountryAdapter(private val context: Context) : BaseAdapter(), Filterable { diff --git a/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryViewHolder.kt b/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryViewHolder.kt index 2caf0a3cfa..7bc84da062 100644 --- a/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryViewHolder.kt +++ b/mbway/src/main/java/com/adyen/checkout/mbway/country/CountryViewHolder.kt @@ -11,7 +11,7 @@ package com.adyen.checkout.mbway.country import android.view.View import android.widget.TextView import androidx.recyclerview.widget.RecyclerView -import com.adyen.checkout.mbway.ui.R +import com.adyen.checkout.mbway.R class CountryViewHolder(private val rootView: View) : RecyclerView.ViewHolder(rootView) { private val flagTextView: TextView = rootView.findViewById(R.id.textView_flag) diff --git a/sepa/src/main/java/com/adyen/checkout/sepa/SepaOutputData.java b/sepa/src/main/java/com/adyen/checkout/sepa/SepaOutputData.java index 9a107cf0bd..345572ef81 100644 --- a/sepa/src/main/java/com/adyen/checkout/sepa/SepaOutputData.java +++ b/sepa/src/main/java/com/adyen/checkout/sepa/SepaOutputData.java @@ -16,7 +16,6 @@ import com.adyen.checkout.components.base.OutputData; import com.adyen.checkout.components.ui.FieldState; import com.adyen.checkout.components.ui.Validation; -import com.adyen.checkout.sepa.ui.R; class SepaOutputData implements OutputData { diff --git a/sepa/src/main/java/com/adyen/checkout/sepa/SepaView.java b/sepa/src/main/java/com/adyen/checkout/sepa/SepaView.java index 8cb7d18e67..0c051fc703 100644 --- a/sepa/src/main/java/com/adyen/checkout/sepa/SepaView.java +++ b/sepa/src/main/java/com/adyen/checkout/sepa/SepaView.java @@ -26,7 +26,6 @@ import com.adyen.checkout.core.exception.CheckoutException; import com.adyen.checkout.core.log.LogUtil; import com.adyen.checkout.core.log.Logger; -import com.adyen.checkout.sepa.ui.R; import com.google.android.material.textfield.TextInputLayout; public class SepaView From 158d4a0cb5d581b4a0863dea72ed4ca2061ffeac Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 30 Mar 2021 09:46:18 +0200 Subject: [PATCH 05/63] Clarify use of lastComponentError --- .../dropin/ui/stored/PreselectedStoredPaymentViewModel.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt index 39decdcd60..1af84f9de0 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/stored/PreselectedStoredPaymentViewModel.kt @@ -69,6 +69,7 @@ class PreselectedStoredPaymentViewModel( "payButtonClicked - componentState.isReady: ${componentState?.isReady} - " + "fragmentState: $fragmentState" ) + // check whether an error has occurred already before Pay was clicked val componentError = lastComponentError val state = when { componentRequiresInput -> ShowStoredPaymentDialog From eb147eea1263db251c7a2c67c704435d860d6e13 Mon Sep 17 00:00:00 2001 From: jreij Date: Fri, 16 Apr 2021 09:37:19 +0200 Subject: [PATCH 06/63] Disable dokka for non kotlin modules --- config/gradle/dokka.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/config/gradle/dokka.gradle b/config/gradle/dokka.gradle index b8e8012f17..6abd36eaf3 100644 --- a/config/gradle/dokka.gradle +++ b/config/gradle/dokka.gradle @@ -6,4 +6,7 @@ * Created by josephj on 8/2/2021. */ -apply plugin: "org.jetbrains.dokka" +// only apply dokka if module supports kotlin +project.plugins.withId("kotlin-android") { + apply plugin: "org.jetbrains.dokka" +} \ No newline at end of file From aa2ea3a9834cd3675590a30a4f129e7380fef387 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 13 Apr 2021 13:23:00 +0200 Subject: [PATCH 07/63] Adding initial QR code module and files --- drop-in/build.gradle | 1 + qr-code/build.gradle | 52 +++++++++++++++++++ qr-code/consumer-rules.pro | 0 qr-code/proguard-rules.pro | 21 ++++++++ qr-code/src/main/AndroidManifest.xml | 10 ++++ .../main/res/template/values/strings.xml.tt | 11 ++++ qr-code/src/main/res/values/strings.xml | 11 ++++ qr-code/src/main/res/values/styles.xml | 12 +++++ settings.gradle | 1 + 9 files changed, 119 insertions(+) create mode 100644 qr-code/build.gradle create mode 100644 qr-code/consumer-rules.pro create mode 100644 qr-code/proguard-rules.pro create mode 100644 qr-code/src/main/AndroidManifest.xml create mode 100644 qr-code/src/main/res/template/values/strings.xml.tt create mode 100644 qr-code/src/main/res/values/strings.xml create mode 100644 qr-code/src/main/res/values/styles.xml diff --git a/drop-in/build.gradle b/drop-in/build.gradle index 0b6e751b16..84b1e28594 100644 --- a/drop-in/build.gradle +++ b/drop-in/build.gradle @@ -68,6 +68,7 @@ dependencies { api project(':ideal') api project(':mbway') api project(':molpay') + api project(':qr-code') api project(':openbanking') api project(":redirect") api project(':sepa') diff --git a/qr-code/build.gradle b/qr-code/build.gradle new file mode 100644 index 0000000000..7402656921 --- /dev/null +++ b/qr-code/build.gradle @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by josephj on 26/3/2021. + */ + +plugins { + id 'com.android.library' + id 'kotlin-android' +} + +ext.mavenArtifactId = "qr-code" +ext.mavenArtifactName = "Adyen checkout QR code component" +ext.mavenArtifactDescription = "Adyen checkout QR code component client for Adyen's Checkout API." + +apply from: "../config/gradle/sharedTasks.gradle" + +android { + compileSdkVersion compile_sdk_version + + defaultConfig { + minSdkVersion min_sdk_version + targetSdkVersion target_sdk_version + versionCode version_code + versionName version_name + + testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + consumerProguardFiles "consumer-rules.pro" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + } +} + +dependencies { + //Tests + testImplementation "junit:junit:$junit_version" + androidTestImplementation "androidx.test.ext:junit:$test_ext_version" + androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version" + + // Checkout + api project(':components-core') + api project(':ui-core') +} diff --git a/qr-code/consumer-rules.pro b/qr-code/consumer-rules.pro new file mode 100644 index 0000000000..e69de29bb2 diff --git a/qr-code/proguard-rules.pro b/qr-code/proguard-rules.pro new file mode 100644 index 0000000000..f1b424510d --- /dev/null +++ b/qr-code/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/qr-code/src/main/AndroidManifest.xml b/qr-code/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..ae58ee4ded --- /dev/null +++ b/qr-code/src/main/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + diff --git a/qr-code/src/main/res/template/values/strings.xml.tt b/qr-code/src/main/res/template/values/strings.xml.tt new file mode 100644 index 0000000000..57397b3cd0 --- /dev/null +++ b/qr-code/src/main/res/template/values/strings.xml.tt @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/qr-code/src/main/res/values/strings.xml b/qr-code/src/main/res/values/strings.xml new file mode 100644 index 0000000000..57397b3cd0 --- /dev/null +++ b/qr-code/src/main/res/values/strings.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/qr-code/src/main/res/values/styles.xml b/qr-code/src/main/res/values/styles.xml new file mode 100644 index 0000000000..b35ea61f36 --- /dev/null +++ b/qr-code/src/main/res/values/styles.xml @@ -0,0 +1,12 @@ + + + + + - \ No newline at end of file diff --git a/ui-core/src/main/res/values/dimens.xml b/ui-core/src/main/res/values/dimens.xml index ae59917662..3996762d37 100644 --- a/ui-core/src/main/res/values/dimens.xml +++ b/ui-core/src/main/res/values/dimens.xml @@ -18,6 +18,9 @@ 40dp 26dp + 80dp + 52dp + 82dp 55dp diff --git a/ui-core/src/main/res/values/styles.xml b/ui-core/src/main/res/values/styles.xml index 2d539fa8c0..06da84dd1b 100644 --- a/ui-core/src/main/res/values/styles.xml +++ b/ui-core/src/main/res/values/styles.xml @@ -90,6 +90,15 @@ @null + + + + \ No newline at end of file From b0bfd96d56c8b3df67a11ba772445bc82f064543 Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 14 Apr 2021 13:01:14 +0200 Subject: [PATCH 12/63] Add copy functionality --- .../adyen/checkout/qrcode/QRCodeComponent.kt | 13 ++++++--- .../com/adyen/checkout/qrcode/QRCodeView.kt | 7 +++++ .../extensions/ContextExtensions.kt | 27 +++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 ui-core/src/main/java/com/adyen/checkout/components/extensions/ContextExtensions.kt diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index 1d15b74495..f4b55207c6 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -10,7 +10,6 @@ package com.adyen.checkout.qrcode import android.app.Activity import android.app.Application import android.content.Context -import android.text.TextUtils import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer @@ -41,6 +40,7 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati private val outputLiveData = MutableLiveData() private var paymentMethodType: String? = null + private var qrCodeData: String? = null private val statusRepository: StatusRepository = StatusRepository.getInstance(configuration.environment) private val responseObserver: Observer = Observer { statusResponse -> @@ -61,7 +61,9 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati override fun handleActionInternal(activity: Activity, action: Action) { val configuration = configuration ?: throw ComponentException("Configuration not found") + if (action !is QrCodeAction) throw ComponentException("Unsupported action") paymentMethodType = action.paymentMethodType + qrCodeData = action.qrCodeData // Notify UI to get the logo. createOutputData(null) val data = paymentData ?: return @@ -82,9 +84,10 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati } private fun onPollingSuccessful(statusResponse: StatusResponse) { + val payload = statusResponse.payload // Not authorized status should still call /details so that merchant can get more info - if (StatusResponseUtils.isFinalResult(statusResponse) && !TextUtils.isEmpty(statusResponse.payload)) { - notifyDetails(createDetail(statusResponse.payload!!)) + if (StatusResponseUtils.isFinalResult(statusResponse) && !payload.isNullOrEmpty()) { + notifyDetails(createDetail(payload)) } else { notifyException(ComponentException("Payment was not completed. - " + statusResponse.resultCode)) } @@ -124,6 +127,10 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati outputLiveData.value = outputData } + fun getCodeString(): String? { + return qrCodeData + } + override fun getSupportedActionTypes(): List = ACTION_TYPES companion object { diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt index 72f99002da..1c0d9dd194 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt @@ -18,6 +18,7 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.Observer import com.adyen.checkout.components.ActionComponentData import com.adyen.checkout.components.api.ImageLoader +import com.adyen.checkout.components.extensions.copyTextToClipboard import com.adyen.checkout.components.ui.view.AdyenLinearLayout import com.adyen.checkout.core.exception.ComponentException import com.adyen.checkout.core.log.LogUtil @@ -65,6 +66,12 @@ class QRCodeView : AdyenLinearLayout() ?: return + val clipData = ClipData.newPlainText(label, text) + clipboardManager.setPrimaryClip(clipData) + if (toastText == null) return + toast(toastText) +} + +fun Context.toast(text: String, duration: Int = Toast.LENGTH_SHORT) { + Toast.makeText(this, text, duration).show() +} From 449d04b752f36fb98e0529c0cc322f1675359a22 Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 14 Apr 2021 14:21:47 +0200 Subject: [PATCH 13/63] Add timer to status polling --- build.gradle | 2 +- .../components/status/StatusRepository.java | 4 +++ config/gradle/checksums.gradle | 2 +- .../adyen/checkout/qrcode/QRCodeComponent.kt | 28 +++++++++++++++++++ .../com/adyen/checkout/qrcode/QRCodeView.kt | 16 +++++++++++ qr-code/src/main/res/layout/qrcode_view.xml | 21 +++++++++++++- qr-code/src/main/res/values/colors.xml | 12 ++++++++ qr-code/src/main/res/values/dimens.xml | 3 ++ qr-code/src/main/res/values/styles.xml | 9 ++++++ 9 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 qr-code/src/main/res/values/colors.xml diff --git a/build.gradle b/build.gradle index 23e3d1056f..a14c6a1b8d 100644 --- a/build.gradle +++ b/build.gradle @@ -69,7 +69,7 @@ allprojects { ext.fragment_version = "1.2.5" ext.appcompat_version = "1.2.0" ext.recyclerview_version = "1.1.0" - ext.material_version = "1.2.1" + ext.material_version = "1.3.0" ext.browser_version = "1.3.0" // Adyen Dependencies diff --git a/components-core/src/main/java/com/adyen/checkout/components/status/StatusRepository.java b/components-core/src/main/java/com/adyen/checkout/components/status/StatusRepository.java index 92b59a2824..9a7fc0687b 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/status/StatusRepository.java +++ b/components-core/src/main/java/com/adyen/checkout/components/status/StatusRepository.java @@ -148,4 +148,8 @@ void updatePollingDelay() { mStatusErrorLiveData.setValue(new ComponentException("Status requesting timed out with no result")); } } + + public long getMaxPollingDurationMillis() { + return POLLING_MAX_COUNT; + } } diff --git a/config/gradle/checksums.gradle b/config/gradle/checksums.gradle index 58e565063f..8e2bce592f 100644 --- a/config/gradle/checksums.gradle +++ b/config/gradle/checksums.gradle @@ -32,7 +32,7 @@ if (!hasProperty("checksums")) { "androidx.browser:browser:1.3.0:f4bd0b4782e1a25c4c3fae304aa982c2:MD5", // Google - "com.google.android.material:material:1.2.1:6411dc90c9afe66ab7f7e471d9d51311:MD5", + "com.google.android.material:material:1.3.0:5909e7762bdbf3704c7fe8a0ed71ee40:MD5", "com.google.android.gms:play-services-wallet:18.1.2:4e75fd00d8ed34fb55620d35f403ccb2:MD5", // WeChatPay diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index f4b55207c6..d59c0163a2 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -10,6 +10,7 @@ package com.adyen.checkout.qrcode import android.app.Activity import android.app.Application import android.content.Context +import android.os.CountDownTimer import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Observer @@ -29,10 +30,12 @@ import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger import org.json.JSONException import org.json.JSONObject +import java.util.concurrent.TimeUnit private val TAG = LogUtil.getTag() private val ACTION_TYPES = listOf(QrCodeAction.ACTION_TYPE) private const val PAYLOAD_DETAILS_KEY = "payload" +private val STATUS_POLLING_INTERVAL_MILLIS = TimeUnit.SECONDS.toMillis(1L) //1 second class QRCodeComponent(application: Application, configuration: QRCodeConfiguration) : BaseActionComponent(application, configuration), @@ -42,6 +45,16 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati private var paymentMethodType: String? = null private var qrCodeData: String? = null private val statusRepository: StatusRepository = StatusRepository.getInstance(configuration.environment) + private val timerLiveData = MutableLiveData() + private var statusCountDownTimer: CountDownTimer = object : CountDownTimer(statusRepository.maxPollingDurationMillis, STATUS_POLLING_INTERVAL_MILLIS) { + override fun onTick(millisUntilFinished: Long) { + onTimerTick(millisUntilFinished) + } + + override fun onFinish() { + // do nothing, StatusRepository will finish the polling automatically + } + } private val responseObserver: Observer = Observer { statusResponse -> Logger.v(TAG, "onChanged - " + if (statusResponse == null) "null" else statusResponse.resultCode) @@ -68,6 +81,7 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati createOutputData(null) val data = paymentData ?: return statusRepository.startPolling(configuration.clientKey, data) + statusCountDownTimer.start() } override fun observe(lifecycleOwner: LifecycleOwner, observer: Observer) { @@ -113,6 +127,10 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati outputLiveData.observe(lifecycleOwner, observer) } + fun observeTimer(lifecycleOwner: LifecycleOwner, observer: Observer) { + timerLiveData.observe(lifecycleOwner, observer) + } + override fun getOutputData(): QRCodeOutputData? { return outputLiveData.value } @@ -131,6 +149,11 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati return qrCodeData } + private fun onTimerTick(millisUntilFinished: Long) { + val progressPercentage = (100 * millisUntilFinished / statusRepository.maxPollingDurationMillis).toInt() + timerLiveData.postValue(TimerData(millisUntilFinished, progressPercentage)) + } + override fun getSupportedActionTypes(): List = ACTION_TYPES companion object { @@ -138,3 +161,8 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl(QRCodeComponent::class.java, QRCodeConfiguration::class.java, true) } } + +data class TimerData( + val millisUntilFinished: Long, + val progress: Int +) diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt index 1c0d9dd194..fa9b159be3 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt @@ -23,6 +23,9 @@ import com.adyen.checkout.components.ui.view.AdyenLinearLayout import com.adyen.checkout.core.exception.ComponentException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger +import com.google.android.material.progressindicator.LinearProgressIndicator +import java.util.concurrent.TimeUnit + private val TAG = LogUtil.getTag() @@ -30,6 +33,8 @@ class QRCodeView : AdyenLinearLayout + + + + + android:text="Copy code" /> \ No newline at end of file diff --git a/qr-code/src/main/res/values/colors.xml b/qr-code/src/main/res/values/colors.xml new file mode 100644 index 0000000000..77fea3469d --- /dev/null +++ b/qr-code/src/main/res/values/colors.xml @@ -0,0 +1,12 @@ + + + + #E6E9EB + #0066FF + \ No newline at end of file diff --git a/qr-code/src/main/res/values/dimens.xml b/qr-code/src/main/res/values/dimens.xml index 840dffdc28..06735ed7e4 100644 --- a/qr-code/src/main/res/values/dimens.xml +++ b/qr-code/src/main/res/values/dimens.xml @@ -9,4 +9,7 @@ 52dp + 150dp + 4dp + 2dp \ No newline at end of file diff --git a/qr-code/src/main/res/values/styles.xml b/qr-code/src/main/res/values/styles.xml index 5bc320bb05..8bcb18df1d 100644 --- a/qr-code/src/main/res/values/styles.xml +++ b/qr-code/src/main/res/values/styles.xml @@ -24,4 +24,13 @@ @style/Widget.AppCompat.Button.Borderless.Colored @color/primaryColor + + \ No newline at end of file From f0719e3afd13eb36e266676a3cf6be80ad874953 Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 14 Apr 2021 15:03:17 +0200 Subject: [PATCH 14/63] Fine tuning the UI --- .../components/util/PaymentMethodTypes.java | 1 + qr-code/build.gradle | 4 ++ .../com/adyen/checkout/qrcode/QRCodeView.kt | 46 +++++++++---------- qr-code/src/main/res/layout/qrcode_view.xml | 15 +++--- .../src/main/res/values-pt-rBR/strings.xml | 16 +++++++ qr-code/src/main/res/values/colors.xml | 1 + qr-code/src/main/res/values/dimens.xml | 1 + qr-code/src/main/res/values/strings.xml | 8 +++- qr-code/src/main/res/values/styles.xml | 5 ++ 9 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 qr-code/src/main/res/values-pt-rBR/strings.xml diff --git a/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java b/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java index af24867223..2e37a627fb 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java +++ b/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java @@ -40,6 +40,7 @@ public final class PaymentMethodTypes { public static final String WECHAT_PAY_SDK = "wechatpaySDK"; public static final String MB_WAY = "mbway"; public static final String BLIK = "blik"; + public static final String PIX = "pix"; // Voucher payment methods that are not yet supported public static final String MULTIBANCO = "multibanco"; diff --git a/qr-code/build.gradle b/qr-code/build.gradle index 9cb5e72c96..dc50069bdf 100644 --- a/qr-code/build.gradle +++ b/qr-code/build.gradle @@ -38,6 +38,10 @@ android { kotlinOptions { jvmTarget = JavaVersion.VERSION_1_8.toString() } + + buildFeatures { + viewBinding true + } } dependencies { diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt index fa9b159be3..bdc532ef88 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt @@ -11,31 +11,25 @@ package com.adyen.checkout.qrcode import android.content.Context import android.util.AttributeSet import android.view.LayoutInflater -import android.widget.Button -import android.widget.ImageView -import android.widget.TextView +import androidx.annotation.StringRes import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.Observer import com.adyen.checkout.components.ActionComponentData import com.adyen.checkout.components.api.ImageLoader import com.adyen.checkout.components.extensions.copyTextToClipboard import com.adyen.checkout.components.ui.view.AdyenLinearLayout +import com.adyen.checkout.components.util.PaymentMethodTypes import com.adyen.checkout.core.exception.ComponentException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger -import com.google.android.material.progressindicator.LinearProgressIndicator +import com.adyen.checkout.qrcode.databinding.QrcodeViewBinding import java.util.concurrent.TimeUnit - private val TAG = LogUtil.getTag() class QRCodeView : AdyenLinearLayout, Observer { - private lateinit var imageView: ImageView - private lateinit var topLabelTextView: TextView - private lateinit var timerTextView: TextView - private lateinit var progressIndicator: LinearProgressIndicator - private lateinit var copyButton: Button + private val binding: QrcodeViewBinding = QrcodeViewBinding.inflate(LayoutInflater.from(context), this) private lateinit var imageLoader: ImageLoader private var paymentMethodType: String? = null @@ -54,9 +48,6 @@ class QRCodeView : AdyenLinearLayout R.string.checkout_qr_code_pix + else -> null } } diff --git a/qr-code/src/main/res/layout/qrcode_view.xml b/qr-code/src/main/res/layout/qrcode_view.xml index 74534a7cc7..342e2aa679 100644 --- a/qr-code/src/main/res/layout/qrcode_view.xml +++ b/qr-code/src/main/res/layout/qrcode_view.xml @@ -27,23 +27,24 @@ android:layout_gravity="center_horizontal" android:layout_margin="@dimen/standard_margin" android:gravity="center" - android:text="Copy the code, then open the app with the registered PIX key, choose Pay with PIX and paste the code there." /> + tools:text="@string/checkout_qr_code_pix" /> @@ -52,6 +53,6 @@ android:id="@+id/copyButton" style="@style/AdyenCheckout.QrCode.CopyButton" android:layout_width="match_parent" - android:text="Copy code" /> + android:text="@string/checkout_qr_code_copy_button" /> \ No newline at end of file diff --git a/qr-code/src/main/res/values-pt-rBR/strings.xml b/qr-code/src/main/res/values-pt-rBR/strings.xml new file mode 100644 index 0000000000..8a91ecbff5 --- /dev/null +++ b/qr-code/src/main/res/values-pt-rBR/strings.xml @@ -0,0 +1,16 @@ + + + + + %02d:%02d + Copie o código, abra o app com a chave PIX cadastrada, escolha Pagar com Pix e cole o código. + Copiar código + Você tem %s para pagar + Código copiado + \ No newline at end of file diff --git a/qr-code/src/main/res/values/colors.xml b/qr-code/src/main/res/values/colors.xml index 77fea3469d..9b52c787f8 100644 --- a/qr-code/src/main/res/values/colors.xml +++ b/qr-code/src/main/res/values/colors.xml @@ -9,4 +9,5 @@ #E6E9EB #0066FF + #687282 \ No newline at end of file diff --git a/qr-code/src/main/res/values/dimens.xml b/qr-code/src/main/res/values/dimens.xml index 06735ed7e4..6fe968a992 100644 --- a/qr-code/src/main/res/values/dimens.xml +++ b/qr-code/src/main/res/values/dimens.xml @@ -12,4 +12,5 @@ 150dp 4dp 2dp + 12sp \ No newline at end of file diff --git a/qr-code/src/main/res/values/strings.xml b/qr-code/src/main/res/values/strings.xml index 57397b3cd0..5d3ccce197 100644 --- a/qr-code/src/main/res/values/strings.xml +++ b/qr-code/src/main/res/values/strings.xml @@ -1,5 +1,4 @@ - - + %02d:%02d + Copy the code, then open the app with the registered PIX key, choose Pay with PIX and paste the code there. + Copy code + Code copied to clipboard + You have %s to pay \ No newline at end of file diff --git a/qr-code/src/main/res/values/styles.xml b/qr-code/src/main/res/values/styles.xml index 8bcb18df1d..83782bcff0 100644 --- a/qr-code/src/main/res/values/styles.xml +++ b/qr-code/src/main/res/values/styles.xml @@ -33,4 +33,9 @@ @dimen/progress_track_height @dimen/progress_track_radius + + \ No newline at end of file From f1f18fe59d6668f79cc96f48b87aefd016a391a4 Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 14 Apr 2021 16:59:27 +0200 Subject: [PATCH 15/63] Code checks --- await/src/main/res/layout/await_view.xml | 4 ++-- .../components/status/StatusRepository.java | 3 +++ .../adyen/checkout/qrcode/QRCodeComponent.kt | 20 ++++++++++++++----- .../com/adyen/checkout/qrcode/QRCodeView.kt | 5 +++-- qr-code/src/main/res/layout/qrcode_view.xml | 5 ++++- .../src/main/res/values-pt-rBR/strings.xml | 1 - 6 files changed, 27 insertions(+), 11 deletions(-) diff --git a/await/src/main/res/layout/await_view.xml b/await/src/main/res/layout/await_view.xml index 743f1e3060..a9368152c2 100644 --- a/await/src/main/res/layout/await_view.xml +++ b/await/src/main/res/layout/await_view.xml @@ -21,8 +21,8 @@ android:id="@+id/imageView_logo" style="@style/AdyenCheckout.Image.Logo.Large" android:layout_gravity="center_horizontal" - - android:contentDescription="@null" /> + android:contentDescription="@null" + tools:ignore="RequiredSize" /> getStatusResponseLiveData() { return mStatusResponseLiveData; } + @NonNull public LiveData getErrorLiveData() { return mStatusErrorLiveData; } diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index d59c0163a2..c47e5b3ce2 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -35,8 +35,10 @@ import java.util.concurrent.TimeUnit private val TAG = LogUtil.getTag() private val ACTION_TYPES = listOf(QrCodeAction.ACTION_TYPE) private const val PAYLOAD_DETAILS_KEY = "payload" -private val STATUS_POLLING_INTERVAL_MILLIS = TimeUnit.SECONDS.toMillis(1L) //1 second +private val STATUS_POLLING_INTERVAL_MILLIS = TimeUnit.SECONDS.toMillis(1L) // 1 second +private const val HUNDRED = 100 +@Suppress("TooManyFunctions") class QRCodeComponent(application: Application, configuration: QRCodeConfiguration) : BaseActionComponent(application, configuration), ViewableComponent { @@ -46,7 +48,10 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati private var qrCodeData: String? = null private val statusRepository: StatusRepository = StatusRepository.getInstance(configuration.environment) private val timerLiveData = MutableLiveData() - private var statusCountDownTimer: CountDownTimer = object : CountDownTimer(statusRepository.maxPollingDurationMillis, STATUS_POLLING_INTERVAL_MILLIS) { + private var statusCountDownTimer: CountDownTimer = object : CountDownTimer( + statusRepository.maxPollingDurationMillis, + STATUS_POLLING_INTERVAL_MILLIS + ) { override fun onTick(millisUntilFinished: Long) { onTimerTick(millisUntilFinished) } @@ -63,7 +68,8 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati onPollingSuccessful(statusResponse) } } - private val mErrorObserver: Observer = Observer { e -> // StatusRepository will post null errors to reset it's status. We can ignore. + private val mErrorObserver: Observer = Observer { e -> + // StatusRepository will post null errors to reset it's status. We can ignore. if (e != null) { Logger.e(TAG, "onError") notifyException(e) @@ -150,7 +156,7 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati } private fun onTimerTick(millisUntilFinished: Long) { - val progressPercentage = (100 * millisUntilFinished / statusRepository.maxPollingDurationMillis).toInt() + val progressPercentage = (HUNDRED * millisUntilFinished / statusRepository.maxPollingDurationMillis).toInt() timerLiveData.postValue(TimerData(millisUntilFinished, progressPercentage)) } @@ -158,7 +164,11 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati companion object { @JvmField - val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl(QRCodeComponent::class.java, QRCodeConfiguration::class.java, true) + val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl( + QRCodeComponent::class.java, + QRCodeConfiguration::class.java, + true + ) } } diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt index bdc532ef88..834e26c006 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt @@ -27,6 +27,7 @@ import java.util.concurrent.TimeUnit private val TAG = LogUtil.getTag() +@Suppress("TooManyFunctions") class QRCodeView : AdyenLinearLayout, Observer { private val binding: QrcodeViewBinding = QrcodeViewBinding.inflate(LayoutInflater.from(context), this) @@ -74,6 +75,7 @@ class QRCodeView : AdyenLinearLayout null } } - -} \ No newline at end of file +} diff --git a/qr-code/src/main/res/layout/qrcode_view.xml b/qr-code/src/main/res/layout/qrcode_view.xml index 342e2aa679..74cfcaeb1e 100644 --- a/qr-code/src/main/res/layout/qrcode_view.xml +++ b/qr-code/src/main/res/layout/qrcode_view.xml @@ -17,7 +17,8 @@ android:id="@+id/imageView_logo" style="@style/AdyenCheckout.Image.Logo.Large" android:layout_gravity="center_horizontal" - android:contentDescription="@null" /> + android:contentDescription="@null" + tools:ignore="RequiredSize" /> - %02d:%02d Copie o código, abra o app com a chave PIX cadastrada, escolha Pagar com Pix e cole o código. Copiar código Você tem %s para pagar From 1381f2a7c87fd8e396d6d9b8bb5cd5177f53aa01 Mon Sep 17 00:00:00 2001 From: jreij Date: Mon, 19 Apr 2021 13:01:54 +0200 Subject: [PATCH 16/63] Minor fixes --- .../adyen/checkout/await/AwaitComponent.java | 2 +- drop-in/src/main/res/values/dimens.xml | 2 -- drop-in/src/main/res/values/styles.xml | 18 ------------------ qr-code/build.gradle | 4 +++- .../adyen/checkout/qrcode/QRCodeComponent.kt | 2 +- qr-code/src/main/res/values/styles.xml | 12 +----------- ui-core/src/main/res/values/dimens.xml | 2 ++ ui-core/src/main/res/values/styles.xml | 18 ++++++++++++++++++ 8 files changed, 26 insertions(+), 34 deletions(-) diff --git a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java index 25f4ca6e89..6b848c6267 100644 --- a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java +++ b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java @@ -162,7 +162,7 @@ public AwaitOutputData getOutputData() { @Override public void sendAnalyticsEvent(@NonNull Context context) { - // TODO: 28/08/2020 Do we have an event for this? + // noop } diff --git a/drop-in/src/main/res/values/dimens.xml b/drop-in/src/main/res/values/dimens.xml index f6ed5dbc95..8fece0432e 100644 --- a/drop-in/src/main/res/values/dimens.xml +++ b/drop-in/src/main/res/values/dimens.xml @@ -8,8 +8,6 @@ --> - 60dp - 16dp 8dp 26dp diff --git a/drop-in/src/main/res/values/styles.xml b/drop-in/src/main/res/values/styles.xml index 9780ae4a96..14cf402ca7 100644 --- a/drop-in/src/main/res/values/styles.xml +++ b/drop-in/src/main/res/values/styles.xml @@ -11,24 +11,6 @@ - - - - - diff --git a/qr-code/build.gradle b/qr-code/build.gradle index dc50069bdf..9fac650953 100644 --- a/qr-code/build.gradle +++ b/qr-code/build.gradle @@ -45,7 +45,6 @@ android { } dependencies { - implementation "com.google.android.material:material:$material_version" //Tests testImplementation "junit:junit:$junit_version" androidTestImplementation "androidx.test.ext:junit:$test_ext_version" @@ -54,4 +53,7 @@ dependencies { // Checkout api project(':components-core') api project(':ui-core') + + // Dependencies + implementation "com.google.android.material:material:$material_version" } diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index c47e5b3ce2..cc3672adb9 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -142,7 +142,7 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati } override fun sendAnalyticsEvent(context: Context) { - // TODO: 28/08/2020 Do we have an event for this? + // noop } private fun createOutputData(statusResponse: StatusResponse?) { diff --git a/qr-code/src/main/res/values/styles.xml b/qr-code/src/main/res/values/styles.xml index 83782bcff0..b6de810278 100644 --- a/qr-code/src/main/res/values/styles.xml +++ b/qr-code/src/main/res/values/styles.xml @@ -10,21 +10,11 @@ - - + + + + + + \ No newline at end of file From 34a39ea1e7b36540791a52c61975417828032305 Mon Sep 17 00:00:00 2001 From: jreij Date: Mon, 19 Apr 2021 16:12:53 +0200 Subject: [PATCH 17/63] Fix styles --- ui-core/src/main/res/values/styles.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-core/src/main/res/values/styles.xml b/ui-core/src/main/res/values/styles.xml index 5de9a26617..42cbecf56f 100644 --- a/ui-core/src/main/res/values/styles.xml +++ b/ui-core/src/main/res/values/styles.xml @@ -140,7 +140,7 @@ @style/AdyenCheckout.PrimaryFlatButton - From 6b625ebf1ac45bae618f89735480a6dabbebf0d0 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 20 Apr 2021 11:02:38 +0200 Subject: [PATCH 18/63] Split getConfigurationFor in 2 methods: payment method and action --- .../adyen/checkout/dropin/ActionHandler.kt | 4 +- .../dropin/ComponentParsingProvider.kt | 154 +++++++++--------- .../checkout/dropin/DropInConfiguration.kt | 23 ++- .../action/ActionComponentDialogFragment.kt | 4 +- .../PaymentMethodListDialogFragment.kt | 2 +- 5 files changed, 96 insertions(+), 91 deletions(-) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt index 35dab56914..7fef5e949d 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt @@ -39,12 +39,12 @@ class ActionHandler( private val redirectComponent = RedirectComponent.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationFor(ActionTypes.REDIRECT, activity) + dropInConfiguration.getConfigurationForAction(ActionTypes.REDIRECT, activity) ) private val adyen3DS2Component = Adyen3DS2Component.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationFor(ActionTypes.THREEDS2, activity) + dropInConfiguration.getConfigurationForAction(ActionTypes.THREEDS2, activity) ) // get config from Drop-in when available private val weChatPayActionComponent = WeChatPayActionComponent.PROVIDER.get(activity, activity.application, null) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index 57f5b11977..dbf3d53a90 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -14,6 +14,15 @@ import androidx.fragment.app.Fragment import com.adyen.checkout.adyen3ds2.Adyen3DS2Configuration import com.adyen.checkout.await.AwaitConfiguration import com.adyen.checkout.await.AwaitView +import com.adyen.checkout.bcmc.BcmcComponent +import com.adyen.checkout.bcmc.BcmcConfiguration +import com.adyen.checkout.bcmc.BcmcView +import com.adyen.checkout.blik.BlikComponent +import com.adyen.checkout.blik.BlikConfiguration +import com.adyen.checkout.blik.BlikView +import com.adyen.checkout.card.CardComponent +import com.adyen.checkout.card.CardConfiguration +import com.adyen.checkout.card.CardView import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.ComponentView import com.adyen.checkout.components.PaymentComponent @@ -28,15 +37,6 @@ import com.adyen.checkout.components.model.paymentmethods.StoredPaymentMethod import com.adyen.checkout.components.model.payments.request.PaymentMethodDetails import com.adyen.checkout.components.util.ActionTypes import com.adyen.checkout.components.util.PaymentMethodTypes -import com.adyen.checkout.bcmc.BcmcComponent -import com.adyen.checkout.bcmc.BcmcConfiguration -import com.adyen.checkout.bcmc.BcmcView -import com.adyen.checkout.blik.BlikComponent -import com.adyen.checkout.blik.BlikConfiguration -import com.adyen.checkout.blik.BlikView -import com.adyen.checkout.card.CardComponent -import com.adyen.checkout.card.CardConfiguration -import com.adyen.checkout.card.CardView import com.adyen.checkout.core.exception.CheckoutException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger @@ -77,8 +77,8 @@ object ComponentParsingProvider { } @Suppress("ComplexMethod", "LongMethod") -internal fun getDefaultConfigFor( - componentType: String, +internal fun getDefaultConfigForPaymentMethod( + paymentMethod: String, context: Context, dropInConfiguration: DropInConfiguration ): T { @@ -86,65 +86,54 @@ internal fun getDefaultConfigFor( // TODO after fetching public key is enabled, build scheme if client key is present val specificRequirementConfigs = listOf(PaymentMethodTypes.SCHEME, PaymentMethodTypes.GOOGLE_PAY) - if (specificRequirementConfigs.contains(componentType)) { - throw CheckoutException("Cannot provide default config for $componentType. Please add it to the DropInConfiguration with required fields.") + if (specificRequirementConfigs.contains(paymentMethod)) { + throw CheckoutException("Cannot provide default config for $paymentMethod. Please add it to the DropInConfiguration with required fields.") } val clientKey = dropInConfiguration.clientKey // get default builder for Configuration type - val builder: BaseConfigurationBuilder = when (componentType) { - PaymentMethodTypes.BLIK -> { - BlikConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.DOTPAY -> { - DotpayConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.ENTERCASH -> { - EntercashConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.EPS -> { - EPSConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.IDEAL -> { - IdealConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.MB_WAY -> { - MBWayConfiguration.Builder(context, clientKey) - } + val builder: BaseConfigurationBuilder = when (paymentMethod) { + PaymentMethodTypes.BLIK -> BlikConfiguration.Builder(context, clientKey) + PaymentMethodTypes.DOTPAY -> DotpayConfiguration.Builder(context, clientKey) + PaymentMethodTypes.ENTERCASH -> EntercashConfiguration.Builder(context, clientKey) + PaymentMethodTypes.EPS -> EPSConfiguration.Builder(context, clientKey) + PaymentMethodTypes.IDEAL -> IdealConfiguration.Builder(context, clientKey) + PaymentMethodTypes.MB_WAY -> MBWayConfiguration.Builder(context, clientKey) PaymentMethodTypes.MOLPAY_THAILAND, PaymentMethodTypes.MOLPAY_MALAYSIA, - PaymentMethodTypes.MOLPAY_VIETNAM -> { - MolpayConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.OPEN_BANKING -> { - OpenBankingConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.SEPA -> { - SepaConfiguration.Builder(context, clientKey) - } - PaymentMethodTypes.WECHAT_PAY_SDK -> { - WeChatPayConfiguration.Builder(context, clientKey) - } - ActionTypes.AWAIT -> { - AwaitConfiguration.Builder(context, clientKey) - } - ActionTypes.REDIRECT -> { - RedirectConfiguration.Builder(context, clientKey) - } - ActionTypes.QR_CODE -> { - QRCodeConfiguration.Builder(context, clientKey) - } + PaymentMethodTypes.MOLPAY_VIETNAM -> MolpayConfiguration.Builder(context, clientKey) + PaymentMethodTypes.OPEN_BANKING -> OpenBankingConfiguration.Builder(context, clientKey) + PaymentMethodTypes.SEPA -> SepaConfiguration.Builder(context, clientKey) + PaymentMethodTypes.WECHAT_PAY_SDK -> WeChatPayConfiguration.Builder(context, clientKey) + else -> throw CheckoutException("Unable to find component configuration for paymentMethod - $paymentMethod") + } + + builder.setShopperLocale(dropInConfiguration.shopperLocale) + builder.setEnvironment(dropInConfiguration.environment) + + @Suppress("UNCHECKED_CAST") + return builder.build() as T +} + +@Suppress("ComplexMethod", "LongMethod") +internal fun getDefaultConfigForAction( + action: String, + context: Context, + dropInConfiguration: DropInConfiguration +): T { + val clientKey = dropInConfiguration.clientKey + + // get default builder for Configuration type + val builder: BaseConfigurationBuilder = when (action) { + ActionTypes.AWAIT -> AwaitConfiguration.Builder(context, clientKey) + ActionTypes.REDIRECT -> RedirectConfiguration.Builder(context, clientKey) + ActionTypes.QR_CODE -> QRCodeConfiguration.Builder(context, clientKey) ActionTypes.THREEDS2_FINGERPRINT, ActionTypes.THREEDS2_CHALLENGE, - ActionTypes.THREEDS2 -> { - Adyen3DS2Configuration.Builder(context, clientKey) - } + ActionTypes.THREEDS2 -> Adyen3DS2Configuration.Builder(context, clientKey) // ActionTypes.SDK is not distinguishable only by the type since we need the payment method too - - else -> { - throw CheckoutException("Unable to find component configuration for type - $componentType") - } + else -> throw CheckoutException("Unable to find component configuration for action - $action") } builder.setShopperLocale(dropInConfiguration.shopperLocale) @@ -166,7 +155,7 @@ internal fun checkComponentAvailability( val type = paymentMethod.type ?: throw CheckoutException("PaymentMethod type is null") val provider = getProviderForType(type) - val configuration = dropInConfiguration.getConfigurationFor(type, application) + val configuration = dropInConfiguration.getConfigurationForPaymentMethod(type, application) provider.isAvailable(application, paymentMethod, configuration, callback) } catch (e: CheckoutException) { @@ -216,11 +205,11 @@ internal fun getComponentFor( val component = when (storedPaymentMethod.type) { PaymentMethodTypes.SCHEME -> { - val cardConfig: CardConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.SCHEME, context) + val cardConfig: CardConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.SCHEME, context) CardComponent.PROVIDER.get(fragment, storedPaymentMethod, cardConfig) } PaymentMethodTypes.BLIK -> { - val blikConfig: BlikConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.BLIK, context) + val blikConfig: BlikConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.BLIK, context) BlikComponent.PROVIDER.get(fragment, storedPaymentMethod, blikConfig) } else -> { @@ -248,63 +237,72 @@ internal fun getComponentFor( val component = when (paymentMethod.type) { PaymentMethodTypes.BCMC -> { - val bcmcConfiguration: BcmcConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.BCMC, context) + val bcmcConfiguration: BcmcConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.BCMC, context) BcmcComponent.PROVIDER.get(fragment, paymentMethod, bcmcConfiguration) } PaymentMethodTypes.BLIK -> { - val blikConfiguration: BlikConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.BLIK, context) + val blikConfiguration: BlikConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.BLIK, context) BlikComponent.PROVIDER.get(fragment, paymentMethod, blikConfiguration) } PaymentMethodTypes.DOTPAY -> { - val dotpayConfig: DotpayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.DOTPAY, context) + val dotpayConfig: DotpayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.DOTPAY, context) DotpayComponent.PROVIDER.get(fragment, paymentMethod, dotpayConfig) } PaymentMethodTypes.ENTERCASH -> { - val entercashConfig: EntercashConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.ENTERCASH, context) + val entercashConfig: EntercashConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.ENTERCASH, context) EntercashComponent.PROVIDER.get(fragment, paymentMethod, entercashConfig) } PaymentMethodTypes.EPS -> { - val epsConfig: EPSConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.EPS, context) + val epsConfig: EPSConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.EPS, context) EPSComponent.PROVIDER.get(fragment, paymentMethod, epsConfig) } PaymentMethodTypes.GOOGLE_PAY -> { - val googlePayConfiguration: GooglePayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.GOOGLE_PAY, context) + val googlePayConfiguration: GooglePayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod( + PaymentMethodTypes.GOOGLE_PAY, + context + ) GooglePayComponent.PROVIDER.get(fragment, paymentMethod, googlePayConfiguration) } PaymentMethodTypes.IDEAL -> { - val idealConfig: IdealConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.IDEAL, context) + val idealConfig: IdealConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.IDEAL, context) IdealComponent.PROVIDER.get(fragment, paymentMethod, idealConfig) } PaymentMethodTypes.MB_WAY -> { - val mbWayConfiguration: MBWayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.MB_WAY, context) + val mbWayConfiguration: MBWayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.MB_WAY, context) MBWayComponent.PROVIDER.get(fragment, paymentMethod, mbWayConfiguration) } PaymentMethodTypes.MOLPAY_THAILAND -> { - val molpayConfig: MolpayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.MOLPAY_THAILAND, context) + val molpayConfig: MolpayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.MOLPAY_THAILAND, context) MolpayComponent.PROVIDER.get(fragment, paymentMethod, molpayConfig) } PaymentMethodTypes.MOLPAY_MALAYSIA -> { - val molpayConfig: MolpayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.MOLPAY_MALAYSIA, context) + val molpayConfig: MolpayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.MOLPAY_MALAYSIA, context) MolpayComponent.PROVIDER.get(fragment, paymentMethod, molpayConfig) } PaymentMethodTypes.MOLPAY_VIETNAM -> { - val molpayConfig: MolpayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.MOLPAY_VIETNAM, context) + val molpayConfig: MolpayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod( + PaymentMethodTypes.MOLPAY_VIETNAM, + context + ) MolpayComponent.PROVIDER.get(fragment, paymentMethod, molpayConfig) } PaymentMethodTypes.OPEN_BANKING -> { - val openBankingConfig: OpenBankingConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.OPEN_BANKING, context) + val openBankingConfig: OpenBankingConfiguration = dropInConfiguration.getConfigurationForPaymentMethod( + PaymentMethodTypes.OPEN_BANKING, + context + ) OpenBankingComponent.PROVIDER.get(fragment, paymentMethod, openBankingConfig) } PaymentMethodTypes.SCHEME -> { - val cardConfig: CardConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.SCHEME, context) + val cardConfig: CardConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.SCHEME, context) CardComponent.PROVIDER.get(fragment, paymentMethod, cardConfig) } PaymentMethodTypes.SEPA -> { - val sepaConfiguration: SepaConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.SEPA, context) + val sepaConfiguration: SepaConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.SEPA, context) SepaComponent.PROVIDER.get(fragment, paymentMethod, sepaConfiguration) } PaymentMethodTypes.WECHAT_PAY_SDK -> { - val weChatPayConfiguration: WeChatPayConfiguration = dropInConfiguration.getConfigurationFor(PaymentMethodTypes.WECHAT_PAY_SDK, context) + val weChatPayConfiguration: WeChatPayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.WECHAT_PAY_SDK, context) WeChatPayComponent.PROVIDER.get(fragment, paymentMethod, weChatPayConfiguration) } diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt index ac1d310709..d2809440f7 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt @@ -12,14 +12,14 @@ import android.content.ComponentName import android.content.Context import android.os.Parcel import android.os.Parcelable +import com.adyen.checkout.bcmc.BcmcConfiguration +import com.adyen.checkout.blik.BlikConfiguration +import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.components.base.Configuration import com.adyen.checkout.components.model.payments.Amount import com.adyen.checkout.components.util.CheckoutCurrency import com.adyen.checkout.components.util.PaymentMethodTypes import com.adyen.checkout.components.util.ValidationUtils -import com.adyen.checkout.bcmc.BcmcConfiguration -import com.adyen.checkout.blik.BlikConfiguration -import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.core.api.Environment import com.adyen.checkout.core.exception.CheckoutException import com.adyen.checkout.core.log.LogUtil @@ -36,7 +36,9 @@ import com.adyen.checkout.mbway.MBWayConfiguration import com.adyen.checkout.molpay.MolpayConfiguration import com.adyen.checkout.openbanking.OpenBankingConfiguration import com.adyen.checkout.sepa.SepaConfiguration -import java.util.Locale +import java.util.* +import kotlin.collections.HashMap +import kotlin.collections.set /** * This is the base configuration for the Drop-In solution. You need to use the [Builder] to instantiate this class. @@ -90,15 +92,20 @@ class DropInConfiguration : Configuration, Parcelable { return ParcelUtils.NO_FILE_DESCRIPTOR } - fun getConfigurationFor(componentType: String, context: Context): T { - return if (availableConfigs.containsKey(componentType)) { + internal fun getConfigurationForPaymentMethod(paymentMethod: String, context: Context): T { + return if (availableConfigs.containsKey(paymentMethod)) { @Suppress("UNCHECKED_CAST") - availableConfigs[componentType] as T + availableConfigs[paymentMethod] as T } else { - getDefaultConfigFor(componentType, context, this) + getDefaultConfigForPaymentMethod(paymentMethod, context, this) } } + internal fun getConfigurationForAction(action: String, context: Context): T { + // TODO fetch from availableConfigs after we support action configs + return getDefaultConfigForAction(action, context, this) + } + /** * Builder for creating a [DropInConfiguration] where you can set specific Configurations for a Payment Method */ diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt index 95d63dbcdc..104ad94895 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt @@ -126,14 +126,14 @@ class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observe AwaitComponent.PROVIDER.get( this, requireActivity().application, - dropInViewModel.dropInConfiguration.getConfigurationFor(ActionTypes.AWAIT, requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForAction(ActionTypes.AWAIT, requireContext()) ) } ActionTypes.QR_CODE -> { QRCodeComponent.PROVIDER.get( this, requireActivity().application, - dropInViewModel.dropInConfiguration.getConfigurationFor(ActionTypes.QR_CODE, requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForAction(ActionTypes.QR_CODE, requireContext()) ) } else -> { diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt index 61fb315a5a..2045457efa 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt @@ -115,7 +115,7 @@ class PaymentMethodListDialogFragment : DropInBottomSheetDialogFragment(), Payme PaymentMethodTypes.GOOGLE_PAY -> { protocol.startGooglePay( dropInViewModel.getPaymentMethod(paymentMethod.type), - dropInViewModel.dropInConfiguration.getConfigurationFor(PaymentMethodTypes.GOOGLE_PAY, requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.GOOGLE_PAY, requireContext()) ) } PaymentMethodTypes.WECHAT_PAY_SDK -> { From 144d0a9dac9cb01e8365766586102e37d61a1faa Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 20 Apr 2021 14:21:49 +0200 Subject: [PATCH 19/63] Get default action config based on configuration class type --- .../adyen/checkout/dropin/ActionHandler.kt | 14 +++++++++---- .../dropin/ComponentParsingProvider.kt | 20 +++++++++---------- .../checkout/dropin/DropInConfiguration.kt | 4 ++-- .../action/ActionComponentDialogFragment.kt | 6 ++++-- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt index 7fef5e949d..ba6cc64859 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt @@ -14,13 +14,16 @@ import android.os.Bundle import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Observer import com.adyen.checkout.adyen3ds2.Adyen3DS2Component +import com.adyen.checkout.adyen3ds2.Adyen3DS2Configuration import com.adyen.checkout.components.ActionComponentData import com.adyen.checkout.components.model.payments.response.Action import com.adyen.checkout.components.util.ActionTypes import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger import com.adyen.checkout.redirect.RedirectComponent +import com.adyen.checkout.redirect.RedirectConfiguration import com.adyen.checkout.wechatpay.WeChatPayActionComponent +import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration class ActionHandler( activity: FragmentActivity, @@ -39,15 +42,18 @@ class ActionHandler( private val redirectComponent = RedirectComponent.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationForAction(ActionTypes.REDIRECT, activity) + dropInConfiguration.getConfigurationForAction(activity) ) private val adyen3DS2Component = Adyen3DS2Component.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationForAction(ActionTypes.THREEDS2, activity) + dropInConfiguration.getConfigurationForAction(activity) + ) + private val weChatPayActionComponent = WeChatPayActionComponent.PROVIDER.get( + activity, + activity.application, + dropInConfiguration.getConfigurationForAction(activity) ) - // get config from Drop-in when available - private val weChatPayActionComponent = WeChatPayActionComponent.PROVIDER.get(activity, activity.application, null) init { redirectComponent.observe(activity, this) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index dbf3d53a90..bd0f9b0a9f 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -69,6 +69,7 @@ import com.adyen.checkout.redirect.RedirectConfiguration import com.adyen.checkout.sepa.SepaComponent import com.adyen.checkout.sepa.SepaConfiguration import com.adyen.checkout.sepa.SepaView +import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration import com.adyen.checkout.wechatpay.WeChatPayComponent import com.adyen.checkout.wechatpay.WeChatPayConfiguration @@ -117,23 +118,20 @@ internal fun getDefaultConfigForPaymentMethod( } @Suppress("ComplexMethod", "LongMethod") -internal fun getDefaultConfigForAction( - action: String, +internal inline fun getDefaultConfigForAction( context: Context, dropInConfiguration: DropInConfiguration ): T { val clientKey = dropInConfiguration.clientKey // get default builder for Configuration type - val builder: BaseConfigurationBuilder = when (action) { - ActionTypes.AWAIT -> AwaitConfiguration.Builder(context, clientKey) - ActionTypes.REDIRECT -> RedirectConfiguration.Builder(context, clientKey) - ActionTypes.QR_CODE -> QRCodeConfiguration.Builder(context, clientKey) - ActionTypes.THREEDS2_FINGERPRINT, - ActionTypes.THREEDS2_CHALLENGE, - ActionTypes.THREEDS2 -> Adyen3DS2Configuration.Builder(context, clientKey) - // ActionTypes.SDK is not distinguishable only by the type since we need the payment method too - else -> throw CheckoutException("Unable to find component configuration for action - $action") + val builder: BaseConfigurationBuilder = when (T::class) { + AwaitConfiguration::class -> AwaitConfiguration.Builder(context, clientKey) + RedirectConfiguration::class -> RedirectConfiguration.Builder(context, clientKey) + QRCodeConfiguration::class -> QRCodeConfiguration.Builder(context, clientKey) + Adyen3DS2Configuration::class -> Adyen3DS2Configuration.Builder(context, clientKey) + WeChatPayActionConfiguration::class -> WeChatPayActionConfiguration.Builder(context, clientKey) + else -> throw CheckoutException("Unable to find component configuration for class - ${T::class}") } builder.setShopperLocale(dropInConfiguration.shopperLocale) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt index d2809440f7..34266bdac6 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt @@ -101,9 +101,9 @@ class DropInConfiguration : Configuration, Parcelable { } } - internal fun getConfigurationForAction(action: String, context: Context): T { + internal inline fun getConfigurationForAction(context: Context): T { // TODO fetch from availableConfigs after we support action configs - return getDefaultConfigForAction(action, context, this) + return getDefaultConfigForAction(context, this) } /** diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt index 104ad94895..00fe19d7c3 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt @@ -15,6 +15,7 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.Observer import com.adyen.checkout.await.AwaitComponent +import com.adyen.checkout.await.AwaitConfiguration import com.adyen.checkout.components.ActionComponent import com.adyen.checkout.components.ActionComponentData import com.adyen.checkout.components.ComponentError @@ -32,6 +33,7 @@ import com.adyen.checkout.dropin.databinding.FragmentActionComponentBinding import com.adyen.checkout.dropin.getViewFor import com.adyen.checkout.dropin.ui.base.DropInBottomSheetDialogFragment import com.adyen.checkout.qrcode.QRCodeComponent +import com.adyen.checkout.qrcode.QRCodeConfiguration @SuppressWarnings("TooManyFunctions") class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observer { @@ -126,14 +128,14 @@ class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observe AwaitComponent.PROVIDER.get( this, requireActivity().application, - dropInViewModel.dropInConfiguration.getConfigurationForAction(ActionTypes.AWAIT, requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForAction(requireContext()) ) } ActionTypes.QR_CODE -> { QRCodeComponent.PROVIDER.get( this, requireActivity().application, - dropInViewModel.dropInConfiguration.getConfigurationForAction(ActionTypes.QR_CODE, requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForAction(requireContext()) ) } else -> { From 272f4003a830d5a65750a8f171ea67086b98ac6d Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 20 Apr 2021 14:24:32 +0200 Subject: [PATCH 20/63] Make action providers return generic config type for better handling in getConfigurationForAction --- .../com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt | 2 +- .../java/com/adyen/checkout/await/AwaitComponent.java | 2 +- .../checkout/components/ActionComponentProvider.java | 7 +++---- .../components/base/ActionComponentProviderImpl.java | 2 +- .../main/java/com/adyen/checkout/dropin/ActionHandler.kt | 9 +++------ .../dropin/ui/action/ActionComponentDialogFragment.kt | 6 ++---- .../java/com/adyen/checkout/qrcode/QRCodeComponent.kt | 2 +- .../com/adyen/checkout/redirect/RedirectComponent.java | 2 +- .../checkout/wechatpay/WeChatPayActionComponent.java | 2 +- 9 files changed, 14 insertions(+), 20 deletions(-) diff --git a/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt b/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt index f9621088ab..2fc901b852 100644 --- a/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt +++ b/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt @@ -310,7 +310,7 @@ class Adyen3DS2Component(application: Application, configuration: Adyen3DS2Confi val TAG = LogUtil.getTag() @JvmField - val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl( + val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl( Adyen3DS2Component::class.java, Adyen3DS2Configuration::class.java ) diff --git a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java index 6b848c6267..59f0fd9bb1 100644 --- a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java +++ b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java @@ -50,7 +50,7 @@ public class AwaitComponent extends BaseActionComponent private static final String PAYLOAD_DETAILS_KEY = "payload"; - public static final ActionComponentProvider PROVIDER + public static final ActionComponentProvider PROVIDER = new ActionComponentProviderImpl<>(AwaitComponent.class, AwaitConfiguration.class, true); final StatusRepository mStatusRepository; diff --git a/components-core/src/main/java/com/adyen/checkout/components/ActionComponentProvider.java b/components-core/src/main/java/com/adyen/checkout/components/ActionComponentProvider.java index 271fe2abce..12f2bd5673 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/ActionComponentProvider.java +++ b/components-core/src/main/java/com/adyen/checkout/components/ActionComponentProvider.java @@ -11,13 +11,12 @@ import android.app.Application; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.lifecycle.ViewModelStoreOwner; import com.adyen.checkout.components.base.Configuration; -public interface ActionComponentProvider extends ComponentProvider { - +public interface ActionComponentProvider + extends ComponentProvider { /** * Get an {@link ActionComponent}. * @@ -27,7 +26,7 @@ public interface ActionComponentProvider ext */ @SuppressWarnings("LambdaLast") @NonNull - ComponentT get(@NonNull ViewModelStoreOwner viewModelStoreOwner, @NonNull Application application, @Nullable Configuration configuration); + ComponentT get(@NonNull ViewModelStoreOwner viewModelStoreOwner, @NonNull Application application, @NonNull ConfigurationT configuration); /** * @return If the Configuration is required for this Component. diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/ActionComponentProviderImpl.java b/components-core/src/main/java/com/adyen/checkout/components/base/ActionComponentProviderImpl.java index 1029b9b31e..bc59459ea0 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/base/ActionComponentProviderImpl.java +++ b/components-core/src/main/java/com/adyen/checkout/components/base/ActionComponentProviderImpl.java @@ -20,7 +20,7 @@ import com.adyen.checkout.components.base.lifecycle.ActionComponentViewModelFactory; public class ActionComponentProviderImpl> - implements ActionComponentProvider { + implements ActionComponentProvider { private final Class mComponentClass; private final Class mConfigurationClass; diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt index ba6cc64859..a34d09099f 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ActionHandler.kt @@ -14,16 +14,13 @@ import android.os.Bundle import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Observer import com.adyen.checkout.adyen3ds2.Adyen3DS2Component -import com.adyen.checkout.adyen3ds2.Adyen3DS2Configuration import com.adyen.checkout.components.ActionComponentData import com.adyen.checkout.components.model.payments.response.Action import com.adyen.checkout.components.util.ActionTypes import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger import com.adyen.checkout.redirect.RedirectComponent -import com.adyen.checkout.redirect.RedirectConfiguration import com.adyen.checkout.wechatpay.WeChatPayActionComponent -import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration class ActionHandler( activity: FragmentActivity, @@ -42,17 +39,17 @@ class ActionHandler( private val redirectComponent = RedirectComponent.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationForAction(activity) + dropInConfiguration.getConfigurationForAction(activity) ) private val adyen3DS2Component = Adyen3DS2Component.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationForAction(activity) + dropInConfiguration.getConfigurationForAction(activity) ) private val weChatPayActionComponent = WeChatPayActionComponent.PROVIDER.get( activity, activity.application, - dropInConfiguration.getConfigurationForAction(activity) + dropInConfiguration.getConfigurationForAction(activity) ) init { diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt index 00fe19d7c3..e834482c7d 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt @@ -15,7 +15,6 @@ import android.view.View import android.view.ViewGroup import androidx.lifecycle.Observer import com.adyen.checkout.await.AwaitComponent -import com.adyen.checkout.await.AwaitConfiguration import com.adyen.checkout.components.ActionComponent import com.adyen.checkout.components.ActionComponentData import com.adyen.checkout.components.ComponentError @@ -33,7 +32,6 @@ import com.adyen.checkout.dropin.databinding.FragmentActionComponentBinding import com.adyen.checkout.dropin.getViewFor import com.adyen.checkout.dropin.ui.base.DropInBottomSheetDialogFragment import com.adyen.checkout.qrcode.QRCodeComponent -import com.adyen.checkout.qrcode.QRCodeConfiguration @SuppressWarnings("TooManyFunctions") class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observer { @@ -128,14 +126,14 @@ class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observe AwaitComponent.PROVIDER.get( this, requireActivity().application, - dropInViewModel.dropInConfiguration.getConfigurationForAction(requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForAction(requireContext()) ) } ActionTypes.QR_CODE -> { QRCodeComponent.PROVIDER.get( this, requireActivity().application, - dropInViewModel.dropInConfiguration.getConfigurationForAction(requireContext()) + dropInViewModel.dropInConfiguration.getConfigurationForAction(requireContext()) ) } else -> { diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index cc3672adb9..6456d683f7 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -164,7 +164,7 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati companion object { @JvmField - val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl( + val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl( QRCodeComponent::class.java, QRCodeConfiguration::class.java, true diff --git a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java index 6da8449ce4..45f0101bbe 100644 --- a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java +++ b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java @@ -39,7 +39,7 @@ public final class RedirectComponent extends BaseActionComponent { private static final String TAG = LogUtil.getTag(); - public static final ActionComponentProvider PROVIDER = + public static final ActionComponentProvider PROVIDER = new ActionComponentProviderImpl<>(RedirectComponent.class, RedirectConfiguration.class); public RedirectComponent(@NonNull Application application, @Nullable RedirectConfiguration configuration) { diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java index 94eca72132..9cd7453838 100644 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java +++ b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java @@ -38,7 +38,7 @@ public class WeChatPayActionComponent extends BaseActionComponent { private static final String TAG = LogUtil.getTag(); - public static final ActionComponentProvider PROVIDER = + public static final ActionComponentProvider PROVIDER = new ActionComponentProviderImpl<>(WeChatPayActionComponent.class, WeChatPayActionConfiguration.class); private final IWXAPI mApi; From aa538fb5439468724a3dff3849f7df948f6bedf7 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 20 Apr 2021 16:01:33 +0200 Subject: [PATCH 21/63] Validate payment method types inside action components --- .../adyen/checkout/adyen3ds2/Adyen3DS2Component.kt | 2 ++ .../com/adyen/checkout/await/AwaitComponent.java | 8 ++++++++ .../java/com/adyen/checkout/await/AwaitView.java | 3 ++- .../components/base/BaseActionComponent.java | 11 ++++++++++- .../ui/action/ActionComponentDialogFragment.kt | 12 +++++++++--- .../com/adyen/checkout/qrcode/QRCodeComponent.kt | 4 ++++ .../adyen/checkout/redirect/RedirectComponent.java | 6 ++++++ .../checkout/wechatpay/WeChatPayActionComponent.java | 12 +++++++----- 8 files changed, 48 insertions(+), 10 deletions(-) diff --git a/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt b/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt index 2fc901b852..be762dc2a8 100644 --- a/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt +++ b/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt @@ -94,6 +94,8 @@ class Adyen3DS2Component(application: Application, configuration: Adyen3DS2Confi ) } + override fun getSupportedPaymentMethodTypes(): List? = null + @Throws(ComponentException::class) override fun handleActionInternal(activity: Activity, action: Action) { when (action.type) { diff --git a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java index 59f0fd9bb1..1d7ba2b8ce 100644 --- a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java +++ b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java @@ -31,6 +31,7 @@ import com.adyen.checkout.components.model.payments.response.Action; import com.adyen.checkout.components.model.payments.response.AwaitAction; import com.adyen.checkout.components.status.StatusRepository; +import com.adyen.checkout.components.util.PaymentMethodTypes; import com.adyen.checkout.core.exception.CheckoutException; import com.adyen.checkout.core.exception.ComponentException; import com.adyen.checkout.core.log.LogUtil; @@ -95,6 +96,13 @@ protected List getSupportedActionTypes() { return Collections.unmodifiableList(Arrays.asList(supportedCodes)); } + @NonNull + @Override + protected List getSupportedPaymentMethodTypes() { + final String[] supportedPaymentMethods = {PaymentMethodTypes.BLIK, PaymentMethodTypes.MB_WAY}; + return Collections.unmodifiableList(Arrays.asList(supportedPaymentMethods)); + } + @Override protected void handleActionInternal(@NonNull Activity activity, @NonNull Action action) throws ComponentException { final Configuration configuration = getConfiguration(); diff --git a/await/src/main/java/com/adyen/checkout/await/AwaitView.java b/await/src/main/java/com/adyen/checkout/await/AwaitView.java index 6bb7045067..58fcb37d0b 100644 --- a/await/src/main/java/com/adyen/checkout/await/AwaitView.java +++ b/await/src/main/java/com/adyen/checkout/await/AwaitView.java @@ -115,6 +115,7 @@ private void updateLogo() { } private void updateMessageText() { + if(getMessageTextResource() == null) return; mTextViewOpenApp.setText(getMessageTextResource()); } @@ -126,7 +127,7 @@ private Integer getMessageTextResource() { case PaymentMethodTypes.MB_WAY: return R.string.checkout_await_message_mbway; default: - return R.string.checkout_await_message_blik; + return null; } } } diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/BaseActionComponent.java b/components-core/src/main/java/com/adyen/checkout/components/base/BaseActionComponent.java index 2f623154d6..93ccbc14b1 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/base/BaseActionComponent.java +++ b/components-core/src/main/java/com/adyen/checkout/components/base/BaseActionComponent.java @@ -49,12 +49,21 @@ public BaseActionComponent(@NonNull Application application, @Nullable Configura @Override public boolean canHandleAction(@NonNull Action action) { - return getSupportedActionTypes().contains(action.getType()); + return getSupportedActionTypes().contains(action.getType()) + && (getSupportedPaymentMethodTypes() == null || getSupportedPaymentMethodTypes().contains(action.getPaymentMethodType())); } @NonNull protected abstract List getSupportedActionTypes(); + /** + * Indicates which payment methods can be handled by this action component. + * + * @return the list of supported payment method types, or null if all types are supported. + */ + @Nullable + protected abstract List getSupportedPaymentMethodTypes(); + @Override public void handleAction(@NonNull Activity activity, @NonNull Action action) { if (!canHandleAction(action)) { diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt index e834482c7d..aaf8280bf6 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/action/ActionComponentDialogFragment.kt @@ -79,7 +79,7 @@ class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observe try { @Suppress("UNCHECKED_CAST") componentView = getViewFor(requireContext(), actionType) as ComponentView> - actionComponent = getComponent(actionType) + actionComponent = getComponent(action) attachComponent(actionComponent, componentView) if (!isHandled) { @@ -120,8 +120,8 @@ class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observe /** * Return the possible viewable action components */ - private fun getComponent(actionType: String): ViewableComponent<*, *, ActionComponentData> { - return when (actionType) { + private fun getComponent(action: Action): ViewableComponent<*, *, ActionComponentData> { + val component = when (action.type) { ActionTypes.AWAIT -> { AwaitComponent.PROVIDER.get( this, @@ -140,6 +140,12 @@ class ActionComponentDialogFragment : DropInBottomSheetDialogFragment(), Observe throw ComponentException("Unexpected Action component type - $actionType") } } + + if (!component.canHandleAction(action)) { + throw ComponentException("Unexpected Action component type - action: ${action.type} - paymentMethod: ${action.paymentMethodType}") + } + + return component } private fun attachComponent( diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index 6456d683f7..8283410344 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -25,6 +25,7 @@ import com.adyen.checkout.components.model.payments.response.QrCodeAction import com.adyen.checkout.components.status.StatusRepository import com.adyen.checkout.components.status.api.StatusResponseUtils import com.adyen.checkout.components.status.model.StatusResponse +import com.adyen.checkout.components.util.PaymentMethodTypes import com.adyen.checkout.core.exception.ComponentException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger @@ -34,6 +35,7 @@ import java.util.concurrent.TimeUnit private val TAG = LogUtil.getTag() private val ACTION_TYPES = listOf(QrCodeAction.ACTION_TYPE) +private val PAYMENT_METHODS = listOf(PaymentMethodTypes.PIX) private const val PAYLOAD_DETAILS_KEY = "payload" private val STATUS_POLLING_INTERVAL_MILLIS = TimeUnit.SECONDS.toMillis(1L) // 1 second private const val HUNDRED = 100 @@ -162,6 +164,8 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati override fun getSupportedActionTypes(): List = ACTION_TYPES + override fun getSupportedPaymentMethodTypes(): List = PAYMENT_METHODS + companion object { @JvmField val PROVIDER: ActionComponentProvider = ActionComponentProviderImpl( diff --git a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java index 45f0101bbe..ae10d405ee 100644 --- a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java +++ b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectComponent.java @@ -85,6 +85,12 @@ protected List getSupportedActionTypes() { return Collections.unmodifiableList(Arrays.asList(supportedCodes)); } + @Nullable + @Override + protected List getSupportedPaymentMethodTypes() { + return null; + } + @Override protected void handleActionInternal(@NonNull Activity activity, @NonNull Action action) throws ComponentException { final RedirectAction redirectAction = (RedirectAction) action; diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java index 9cd7453838..9719a8620b 100644 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java +++ b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java @@ -79,11 +79,6 @@ public void handleResultIntent(@Nullable Intent intent) { } } - @Override - public boolean canHandleAction(@NonNull Action action) { - return getSupportedActionTypes().contains(action.getType()) && action.getPaymentMethodType().equals(PaymentMethodTypes.WECHAT_PAY_SDK); - } - @NonNull @Override protected List getSupportedActionTypes() { @@ -91,6 +86,13 @@ protected List getSupportedActionTypes() { return Collections.unmodifiableList(Arrays.asList(supportedCodes)); } + @NonNull + @Override + protected List getSupportedPaymentMethodTypes() { + final String[] supportedPaymentMethods = {PaymentMethodTypes.WECHAT_PAY_SDK}; + return Collections.unmodifiableList(Arrays.asList(supportedPaymentMethods)); + } + @Override protected void handleActionInternal(@NonNull Activity activity, @NonNull Action action) throws ComponentException { Logger.d(TAG, "handleActionInternal: activity - " + activity.getLocalClassName()); From b305be90ff8dda6d73009a635ee8cc664c42cf8b Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 20 Apr 2021 16:24:06 +0200 Subject: [PATCH 22/63] Add handling for payment methods that do not require a payment component --- .../components/util/PaymentMethodTypes.java | 137 +++++++++--------- .../PaymentMethodListDialogFragment.kt | 19 ++- .../PaymentMethodsListViewModel.kt | 3 +- 3 files changed, 83 insertions(+), 76 deletions(-) diff --git a/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java b/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java index 2e37a627fb..788e1684d4 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java +++ b/components-core/src/main/java/com/adyen/checkout/components/util/PaymentMethodTypes.java @@ -10,7 +10,7 @@ import com.adyen.checkout.core.exception.NoConstructorException; -import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -35,11 +35,12 @@ public final class PaymentMethodTypes { public static final String SCHEME = "scheme"; public static final String GOOGLE_PAY = "paywithgoogle"; public static final String SEPA = "sepadirectdebit"; - public static final String AFTER_PAY = "afterpay_default"; public static final String BCMC = "bcmc"; - public static final String WECHAT_PAY_SDK = "wechatpaySDK"; public static final String MB_WAY = "mbway"; public static final String BLIK = "blik"; + + // Payment methods that do not need a payment component, but only an action component + public static final String WECHAT_PAY_SDK = "wechatpaySDK"; public static final String PIX = "pix"; // Voucher payment methods that are not yet supported @@ -79,79 +80,81 @@ public final class PaymentMethodTypes { // Payment methods that might be interpreted as redirect, but are actually not supported public static final String BCMC_QR = "bcmc_mobile_QR"; + public static final String AFTER_PAY = "afterpay_default"; public static final String WECHAT_PAY_MINI_PROGRAM = "wechatpayMiniProgram"; public static final String WECHAT_PAY_QR = "wechatpayQR"; public static final String WECHAT_PAY_WEB = "wechatpayWeb"; // List of all payment method types. public static final List SUPPORTED_PAYMENT_METHODS; + public static final List SUPPORTED_ACTION_ONLY_PAYMENT_METHODS; public static final List UNSUPPORTED_PAYMENT_METHODS; static { - final ArrayList supportedPaymentMethods = new ArrayList<>(); - - // Populate supported list - supportedPaymentMethods.add(BCMC); - supportedPaymentMethods.add(DOTPAY); - supportedPaymentMethods.add(ENTERCASH); - supportedPaymentMethods.add(EPS); - supportedPaymentMethods.add(GOOGLE_PAY); - supportedPaymentMethods.add(IDEAL); - supportedPaymentMethods.add(MB_WAY); - supportedPaymentMethods.add(MOLPAY_MALAYSIA); - supportedPaymentMethods.add(MOLPAY_THAILAND); - supportedPaymentMethods.add(MOLPAY_VIETNAM); - supportedPaymentMethods.add(OPEN_BANKING); - supportedPaymentMethods.add(SEPA); - supportedPaymentMethods.add(SCHEME); - supportedPaymentMethods.add(WECHAT_PAY_SDK); - supportedPaymentMethods.add(BLIK); - - SUPPORTED_PAYMENT_METHODS = Collections.unmodifiableList(supportedPaymentMethods); - - final ArrayList unsupportedPaymentMethods = new ArrayList<>(); - - // Populate unsupported list - unsupportedPaymentMethods.add(BCMC_QR); - unsupportedPaymentMethods.add(AFTER_PAY); - unsupportedPaymentMethods.add(WECHAT_PAY_MINI_PROGRAM); - unsupportedPaymentMethods.add(WECHAT_PAY_QR); - unsupportedPaymentMethods.add(WECHAT_PAY_WEB); - - unsupportedPaymentMethods.add(MULTIBANCO); - unsupportedPaymentMethods.add(OXXO); - unsupportedPaymentMethods.add(DOKU); - unsupportedPaymentMethods.add(DOKU_ALFMART); - unsupportedPaymentMethods.add(DOKU_PERMATA_LITE_ATM); - unsupportedPaymentMethods.add(DOKU_INDOMARET); - unsupportedPaymentMethods.add(DOKU_ATM_MANDIRI_VA); - unsupportedPaymentMethods.add(DOKU_SINARMAS_VA); - unsupportedPaymentMethods.add(DOKU_MANDIRI_VA); - unsupportedPaymentMethods.add(DOKU_CIMB_VA); - unsupportedPaymentMethods.add(DOKU_DANAMON_VA); - unsupportedPaymentMethods.add(DOKU_BRI_VA); - unsupportedPaymentMethods.add(DOKU_BNI_VA); - unsupportedPaymentMethods.add(DOKU_BCA_VA); - unsupportedPaymentMethods.add(DOKU_WALLET); - - unsupportedPaymentMethods.add(BOLETOBANCARIO); - unsupportedPaymentMethods.add(BOLETOBANCARIO_BANCODOBRASIL); - unsupportedPaymentMethods.add(BOLETOBANCARIO_BRADESCO); - unsupportedPaymentMethods.add(BOLETOBANCARIO_HSBC); - unsupportedPaymentMethods.add(BOLETOBANCARIO_ITAU); - unsupportedPaymentMethods.add(BOLETOBANCARIO_SANTANDER); - - unsupportedPaymentMethods.add(DRAGONPAY_EBANKING); - unsupportedPaymentMethods.add(DRAGONPAY_OTC_BANKING); - unsupportedPaymentMethods.add(DRAGONPAY_OTC_NON_BANKING); - unsupportedPaymentMethods.add(DRAGONPAY_OTC_PHILIPPINES); - - unsupportedPaymentMethods.add(ECONTEXT_SEVEN_ELEVEN); - unsupportedPaymentMethods.add(ECONTEXT_ATM); - unsupportedPaymentMethods.add(ECONTEXT_STORES); - unsupportedPaymentMethods.add(ECONTEXT_ONLINE); - - UNSUPPORTED_PAYMENT_METHODS = Collections.unmodifiableList(unsupportedPaymentMethods); + SUPPORTED_PAYMENT_METHODS = Collections.unmodifiableList(Arrays.asList( + BCMC, + DOTPAY, + ENTERCASH, + EPS, + GOOGLE_PAY, + IDEAL, + MB_WAY, + MOLPAY_MALAYSIA, + MOLPAY_THAILAND, + MOLPAY_VIETNAM, + OPEN_BANKING, + SEPA, + SCHEME, + BLIK, + WECHAT_PAY_SDK, + PIX + )); + + SUPPORTED_ACTION_ONLY_PAYMENT_METHODS = Collections.unmodifiableList(Arrays.asList( + WECHAT_PAY_SDK, + PIX + )); + + UNSUPPORTED_PAYMENT_METHODS = Collections.unmodifiableList(Arrays.asList( + BCMC_QR, + AFTER_PAY, + WECHAT_PAY_MINI_PROGRAM, + WECHAT_PAY_QR, + WECHAT_PAY_WEB, + + MULTIBANCO, + OXXO, + DOKU, + DOKU_ALFMART, + DOKU_PERMATA_LITE_ATM, + DOKU_INDOMARET, + DOKU_ATM_MANDIRI_VA, + DOKU_SINARMAS_VA, + DOKU_MANDIRI_VA, + DOKU_CIMB_VA, + DOKU_DANAMON_VA, + DOKU_BRI_VA, + DOKU_BNI_VA, + DOKU_BCA_VA, + DOKU_WALLET, + + BOLETOBANCARIO, + BOLETOBANCARIO_BANCODOBRASIL, + BOLETOBANCARIO_BRADESCO, + BOLETOBANCARIO_HSBC, + BOLETOBANCARIO_ITAU, + BOLETOBANCARIO_SANTANDER, + + DRAGONPAY_EBANKING, + DRAGONPAY_OTC_BANKING, + DRAGONPAY_OTC_NON_BANKING, + DRAGONPAY_OTC_PHILIPPINES, + + ECONTEXT_SEVEN_ELEVEN, + ECONTEXT_ATM, + ECONTEXT_STORES, + ECONTEXT_ONLINE + )); } private PaymentMethodTypes() { diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt index 2045457efa..322fbc473c 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodListDialogFragment.kt @@ -111,22 +111,25 @@ class PaymentMethodListDialogFragment : DropInBottomSheetDialogFragment(), Payme Logger.d(TAG, "onPaymentMethodSelected - ${paymentMethod.type}") // Check some specific payment methods that don't need to show a view - when (paymentMethod.type) { - PaymentMethodTypes.GOOGLE_PAY -> { + when { + paymentMethod.type == PaymentMethodTypes.GOOGLE_PAY -> { + Logger.d(TAG, "onPaymentMethodSelected: starting Google Pay") protocol.startGooglePay( dropInViewModel.getPaymentMethod(paymentMethod.type), dropInViewModel.dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.GOOGLE_PAY, requireContext()) ) } - PaymentMethodTypes.WECHAT_PAY_SDK -> { + PaymentMethodTypes.SUPPORTED_ACTION_ONLY_PAYMENT_METHODS.contains(paymentMethod.type) -> { + Logger.d(TAG, "onPaymentMethodSelected: payment method does not need a component, sending payment") sendPayment(paymentMethod.type) } + PaymentMethodTypes.SUPPORTED_PAYMENT_METHODS.contains(paymentMethod.type) -> { + Logger.d(TAG, "onPaymentMethodSelected: payment method is supported") + protocol.showComponentDialog(dropInViewModel.getPaymentMethod(paymentMethod.type)) + } else -> { - if (PaymentMethodTypes.SUPPORTED_PAYMENT_METHODS.contains(paymentMethod.type)) { - protocol.showComponentDialog(dropInViewModel.getPaymentMethod(paymentMethod.type)) - } else { - sendPayment(paymentMethod.type) - } + Logger.d(TAG, "onPaymentMethodSelected: unidentified payment method, sending payment in case of redirect") + sendPayment(paymentMethod.type) } } } diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt index 0ad5d954fa..0d6df4aa27 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt @@ -84,7 +84,8 @@ class PaymentMethodsListViewModel( type == null -> { throw CheckoutException("PaymentMethod type is null") } - PaymentMethodTypes.SUPPORTED_PAYMENT_METHODS.contains(type) -> { + PaymentMethodTypes.SUPPORTED_PAYMENT_METHODS.contains(type) + && !PaymentMethodTypes.SUPPORTED_ACTION_ONLY_PAYMENT_METHODS.contains(type) -> { Logger.v(TAG, "Supported payment method: $type") // We assume payment method is available and remove it later when the callback comes // this is the overwhelming majority of cases, and we keep the list ordered this way. From b76b9e9828afbc0dbd5a6d499f7ba269e491aee0 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 20 Apr 2021 16:36:18 +0200 Subject: [PATCH 23/63] Code checks --- await/src/main/java/com/adyen/checkout/await/AwaitView.java | 4 +++- .../com/adyen/checkout/dropin/ComponentParsingProvider.kt | 5 ++++- .../main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/await/src/main/java/com/adyen/checkout/await/AwaitView.java b/await/src/main/java/com/adyen/checkout/await/AwaitView.java index 58fcb37d0b..9c305fc261 100644 --- a/await/src/main/java/com/adyen/checkout/await/AwaitView.java +++ b/await/src/main/java/com/adyen/checkout/await/AwaitView.java @@ -115,7 +115,9 @@ private void updateLogo() { } private void updateMessageText() { - if(getMessageTextResource() == null) return; + if (getMessageTextResource() == null) { + return; + } mTextViewOpenApp.setText(getMessageTextResource()); } diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index bd0f9b0a9f..57ebb13d0d 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -300,7 +300,10 @@ internal fun getComponentFor( SepaComponent.PROVIDER.get(fragment, paymentMethod, sepaConfiguration) } PaymentMethodTypes.WECHAT_PAY_SDK -> { - val weChatPayConfiguration: WeChatPayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.WECHAT_PAY_SDK, context) + val weChatPayConfiguration: WeChatPayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod( + PaymentMethodTypes.WECHAT_PAY_SDK, + context + ) WeChatPayComponent.PROVIDER.get(fragment, paymentMethod, weChatPayConfiguration) } diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index 8283410344..a90763146a 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -164,7 +164,7 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati override fun getSupportedActionTypes(): List = ACTION_TYPES - override fun getSupportedPaymentMethodTypes(): List = PAYMENT_METHODS + override fun getSupportedPaymentMethodTypes(): List = PAYMENT_METHODS companion object { @JvmField From 39f2ef9877fd574022a433097cc872e53ff6a01b Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Tue, 9 Mar 2021 10:52:16 +0100 Subject: [PATCH 24/63] Create Maven Central publication and repository in place of Bintray. --- build.gradle | 1 - config/gradle/artifacts.gradle | 1 + config/gradle/dokka.gradle | 8 +++- config/gradle/release.gradle | 75 +++++++++++++++++++--------------- config/gradle/sources.gradle | 9 ++-- 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/build.gradle b/build.gradle index a14c6a1b8d..7009139075 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,6 @@ buildscript { dependencies { classpath "com.android.tools.build:gradle:$android_gradle_plugin_version" - classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$bintray_gradle_plugin_version" classpath "io.gitlab.arturbosch.detekt:detekt-gradle-plugin:$detekt_gradle_plugin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:$spotbugs_gradle_plugin_version" diff --git a/config/gradle/artifacts.gradle b/config/gradle/artifacts.gradle index ce8e5561d8..6dcc8529ad 100644 --- a/config/gradle/artifacts.gradle +++ b/config/gradle/artifacts.gradle @@ -11,4 +11,5 @@ apply from: "../config/gradle/sources.gradle" artifacts { archives androidSourcesJar + archives javadocJar } diff --git a/config/gradle/dokka.gradle b/config/gradle/dokka.gradle index 6abd36eaf3..e74946e12f 100644 --- a/config/gradle/dokka.gradle +++ b/config/gradle/dokka.gradle @@ -9,4 +9,10 @@ // only apply dokka if module supports kotlin project.plugins.withId("kotlin-android") { apply plugin: "org.jetbrains.dokka" -} \ No newline at end of file + + task javadocJar(type: Jar, dependsOn: dokkaJavadoc) { + archiveClassifier.set('javadoc') + from dokkaJavadoc.outputDirectory + } +} + diff --git a/config/gradle/release.gradle b/config/gradle/release.gradle index a5c6b9b02b..65b6ebae20 100644 --- a/config/gradle/release.gradle +++ b/config/gradle/release.gradle @@ -6,12 +6,34 @@ * Created by ran on 6/2/2019. */ apply plugin: "maven-publish" -// https://github.com/bintray/gradle-bintray-plugin -apply plugin: "com.jfrog.bintray" +apply plugin: "signing" apply from: "../config/gradle/artifacts.gradle" -// TODO: 03/01/2019 add support for signing of artifacts. +ext["signing.keyId"] = '' +ext["signing.password"] = '' +ext["signing.secretKeyRingFile"] = '' +ext["ossrhUsername"] = '' +ext["ossrhPassword"] = '' +ext["sonatypeStagingProfileId"] = '' + +File secretPropsFile = project.rootProject.file('local.properties') +if (secretPropsFile.exists()) { + logger.lifecycle("\n-- Getting Secrets from local.properties --\n") + Properties p = new Properties() + p.load(new FileInputStream(secretPropsFile)) + p.each { name, value -> + ext[name] = value + } +} else { + logger.lifecycle("\n-- Getting Secrets from System Env --\n") + ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID') + ext["signing.password"] = System.getenv('SIGNING_PASSWORD') + ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE') + ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME') + ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD') + ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID') +} final theGroupId = "com.adyen.checkout" final theArtifactId = project.mavenArtifactId @@ -33,12 +55,13 @@ final theScmUrl = "https://github.com/Adyen/adyen-android" project.afterEvaluate { publishing { publications { - bintrayMavenPublication(MavenPublication) { + release(MavenPublication) { groupId theGroupId artifactId theArtifactId version theVersion artifact androidSourcesJar + artifact javadocJar artifact bundleReleaseAar pom { @@ -101,37 +124,23 @@ project.afterEvaluate { } } } - } -} - -bintray { - user = System.env.BINTRAY_USER - key = System.env.BINTRAY_KEY - - publications = ["bintrayMavenPublication"] - - dryRun = false - publish = false - override = true - pkg { - repo = "adyen-checkout-v3" - name = theArtifactId - - websiteUrl = "https://github.com/Adyen/adyen-android" - issueTrackerUrl = "https://github.com/adyen-android/issues" - vcsUrl = "https://github.com/Adyen/adyen-android.git" - licenses = ["MIT"] - - version { - name = theVersion - released = new Date() - vcsTag = theVersion - - gpg { - sign = false -// passphrase = System.env.BINTRAY_GPG_PASSPHRASE + // The repository to publish to, Sonatype/MavenCentral + repositories { + maven { + // This is an arbitrary name, you may also use "mavencentral" or + // any other name that's descriptive for you + name = "sonatype" + url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" + credentials { + username ossrhUsername + password ossrhPassword + } } } } + + signing { + sign publishing.publications + } } \ No newline at end of file diff --git a/config/gradle/sources.gradle b/config/gradle/sources.gradle index ada5c61cc7..b7eada6e03 100644 --- a/config/gradle/sources.gradle +++ b/config/gradle/sources.gradle @@ -7,7 +7,10 @@ */ task androidSourcesJar(type: Jar) { - classifier = "sources" - from android.sourceSets.main.java.srcDirs - exclude("**/internal/**") + archiveClassifier.set('sources') + if (project.plugins.findPlugin("com.android.library")) { + from android.sourceSets.main.java.srcDirs + } else { + from sourceSets.main.java.srcDirs + } } \ No newline at end of file From 252e3eec954adb90edc6c337cb4cb55e1b8ac02d Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Mon, 19 Apr 2021 12:25:58 +0200 Subject: [PATCH 25/63] Add Kotlin to CSE module to allow Dokka to generate Javadocs. We can add Kotlin classes later if needed. --- cse/build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/cse/build.gradle b/cse/build.gradle index b7d8513497..2d7ef9e98d 100644 --- a/cse/build.gradle +++ b/cse/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.android.library' + id 'kotlin-android' } // Maven artifact From b0191f3fcfb800ebc96108588156a986455c48cb Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Wed, 21 Apr 2021 14:04:23 +0200 Subject: [PATCH 26/63] Remove bintray plugin --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7009139075..7583b4a598 100644 --- a/build.gradle +++ b/build.gradle @@ -13,7 +13,6 @@ buildscript { ext.android_gradle_plugin_version = '4.0.0' ext.kotlin_version = '1.4.21' ext.detekt_gradle_plugin_version = "1.13.1" - ext.bintray_gradle_plugin_version = "1.8.5" ext.spotbugs_gradle_plugin_version = "4.5.1" ext.dokka_version = "1.4.20" From 8abd93b80562017da603b6d36d37f140a5fbac53 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Wed, 21 Apr 2021 14:04:45 +0200 Subject: [PATCH 27/63] Add developers tag to POM file. --- config/gradle/release.gradle | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/config/gradle/release.gradle b/config/gradle/release.gradle index 65b6ebae20..757e93bd73 100644 --- a/config/gradle/release.gradle +++ b/config/gradle/release.gradle @@ -49,6 +49,8 @@ final theLicenseUrl = "https://opensource.org/licenses/MIT" final theOrganizationName = "Adyen N.V." final theOrganizationUrl = "https://www.adyen.com/" +final theTeamName = "Checkout" + final theScmConnection = "scm:git:git://github.com/Adyen/adyen-android.git" final theScmUrl = "https://github.com/Adyen/adyen-android" @@ -78,6 +80,13 @@ project.afterEvaluate { name = theOrganizationName url = theOrganizationUrl } + developers { + developer { + name = theTeamName + organization = theOrganizationName + organizationUrl = theOrganizationUrl + } + } scm { connection = theScmConnection developerConnection = theScmConnection @@ -125,11 +134,8 @@ project.afterEvaluate { } } - // The repository to publish to, Sonatype/MavenCentral repositories { maven { - // This is an arbitrary name, you may also use "mavencentral" or - // any other name that's descriptive for you name = "sonatype" url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" credentials { From 82d52cc90b228d63def8ffc9783b14f4ae4bdea6 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Wed, 21 Apr 2021 14:11:48 +0200 Subject: [PATCH 28/63] Update release workflow to call Maven Central publish task. --- .github/workflows/publish_release.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 2fc9c73aa3..070380ac62 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -29,13 +29,25 @@ jobs: # TODO: add more tests or rely on check_release workflow? + # Base64 decodes and pipes the GPG key content into the secret file + - name: Prepare environment + env: + GPG_KEY_CONTENTS: ${{ secrets.GPG_KEY_CONTENTS }} + SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} + run: | + git fetch --unshallow + sudo bash -c "echo '$GPG_KEY_CONTENTS' | base64 -d > '$SIGNING_SECRET_KEY_RING_FILE'" + # Packages and publishes the AARs to Bintray - - name: Publish to Bintray - run: ./gradlew bintrayUpload --stacktrace + - name: Publish to Maven Central + run: ./gradlew publishReleasePublicationToSonatypeRepository --max-workers 1 --stacktrace env: - BINTRAY_USER: ${{secrets.BINTRAY_USER}} - BINTRAY_KEY: ${{secrets.BINTRAY_KEY}} -# BINTRAY_GPG_PASSPHRASE: ${{secrets.BINTRAY_GPG_PASSPHRASE}} + OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} + OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + SIGNING_SECRET_KEY_RING_FILE: ${{ secrets.SIGNING_SECRET_KEY_RING_FILE }} + SONATYPE_STAGING_PROFILE_ID: ${{ secrets.SONATYPE_STAGING_PROFILE_ID }} # Get the version name from a script and save to environment variable. - name: Set PROJECT_VERSION From 93bbd8531b7dc5c7254d56b1c04a5044fb1bd020 Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 21 Apr 2021 15:07:31 +0200 Subject: [PATCH 29/63] Add action configurations to drop in configuration --- .../checkout/dropin/DropInConfiguration.kt | 108 ++++++++++++++---- .../checkout/example/ui/main/MainActivity.kt | 7 ++ 2 files changed, 90 insertions(+), 25 deletions(-) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt index 34266bdac6..89346872fb 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt @@ -12,6 +12,8 @@ import android.content.ComponentName import android.content.Context import android.os.Parcel import android.os.Parcelable +import com.adyen.checkout.adyen3ds2.Adyen3DS2Configuration +import com.adyen.checkout.await.AwaitConfiguration import com.adyen.checkout.bcmc.BcmcConfiguration import com.adyen.checkout.blik.BlikConfiguration import com.adyen.checkout.card.CardConfiguration @@ -35,7 +37,10 @@ import com.adyen.checkout.ideal.IdealConfiguration import com.adyen.checkout.mbway.MBWayConfiguration import com.adyen.checkout.molpay.MolpayConfiguration import com.adyen.checkout.openbanking.OpenBankingConfiguration +import com.adyen.checkout.qrcode.QRCodeConfiguration +import com.adyen.checkout.redirect.RedirectConfiguration import com.adyen.checkout.sepa.SepaConfiguration +import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration import java.util.* import kotlin.collections.HashMap import kotlin.collections.set @@ -48,7 +53,8 @@ import kotlin.collections.set @SuppressWarnings("TooManyFunctions") class DropInConfiguration : Configuration, Parcelable { - private val availableConfigs: HashMap + private val availablePaymentConfigs: HashMap + private val availableActionConfigs: HashMap, Configuration> val serviceComponentName: ComponentName val amount: Amount @@ -65,25 +71,30 @@ class DropInConfiguration : Configuration, Parcelable { shopperLocale: Locale, environment: Environment, clientKey: String, - availableConfigs: HashMap, + availablePaymentConfigs: HashMap, + availableActionConfigs: HashMap, Configuration>, serviceComponentName: ComponentName, amount: Amount ) : super(shopperLocale, environment, clientKey) { - this.availableConfigs = availableConfigs + this.availablePaymentConfigs = availablePaymentConfigs + this.availableActionConfigs = availableActionConfigs this.serviceComponentName = serviceComponentName this.amount = amount } constructor(parcel: Parcel) : super(parcel) { @Suppress("UNCHECKED_CAST") - availableConfigs = parcel.readHashMap(Configuration::class.java.classLoader) as HashMap + availablePaymentConfigs = parcel.readHashMap(Configuration::class.java.classLoader) as HashMap + @Suppress("UNCHECKED_CAST") + availableActionConfigs = parcel.readHashMap(Configuration::class.java.classLoader) as HashMap, Configuration> serviceComponentName = parcel.readParcelable(ComponentName::class.java.classLoader)!! amount = Amount.CREATOR.createFromParcel(parcel) } override fun writeToParcel(dest: Parcel, flags: Int) { super.writeToParcel(dest, flags) - dest.writeMap(availableConfigs) + dest.writeMap(availablePaymentConfigs) + dest.writeMap(availableActionConfigs) dest.writeParcelable(serviceComponentName, flags) JsonUtils.writeToParcel(dest, Amount.SERIALIZER.serialize(amount)) } @@ -93,17 +104,22 @@ class DropInConfiguration : Configuration, Parcelable { } internal fun getConfigurationForPaymentMethod(paymentMethod: String, context: Context): T { - return if (availableConfigs.containsKey(paymentMethod)) { + return if (availablePaymentConfigs.containsKey(paymentMethod)) { @Suppress("UNCHECKED_CAST") - availableConfigs[paymentMethod] as T + availablePaymentConfigs[paymentMethod] as T } else { getDefaultConfigForPaymentMethod(paymentMethod, context, this) } } internal inline fun getConfigurationForAction(context: Context): T { - // TODO fetch from availableConfigs after we support action configs - return getDefaultConfigForAction(context, this) + val actionClass = T::class.java + return if (availableActionConfigs.containsKey(actionClass)) { + @Suppress("UNCHECKED_CAST") + availableActionConfigs[actionClass] as T + } else { + getDefaultConfigForAction(context, this) + } } /** @@ -115,7 +131,8 @@ class DropInConfiguration : Configuration, Parcelable { val TAG = LogUtil.getTag() } - private val availableConfigs = HashMap() + private val availablePaymentConfigs = HashMap() + private val availableActionConfigs = HashMap, Configuration>() private var shopperLocale: Locale private var environment: Environment = Environment.EUROPE @@ -193,7 +210,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for Credit Card payment method. */ fun addCardConfiguration(cardConfiguration: CardConfiguration): Builder { - availableConfigs[PaymentMethodTypes.SCHEME] = cardConfiguration + availablePaymentConfigs[PaymentMethodTypes.SCHEME] = cardConfiguration return this } @@ -201,7 +218,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for iDeal payment method. */ fun addIdealConfiguration(idealConfiguration: IdealConfiguration): Builder { - availableConfigs[PaymentMethodTypes.IDEAL] = idealConfiguration + availablePaymentConfigs[PaymentMethodTypes.IDEAL] = idealConfiguration return this } @@ -209,7 +226,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for MolPay Thailand payment method. */ fun addMolpayThailandConfiguration(molpayConfiguration: MolpayConfiguration): Builder { - availableConfigs[PaymentMethodTypes.MOLPAY_THAILAND] = molpayConfiguration + availablePaymentConfigs[PaymentMethodTypes.MOLPAY_THAILAND] = molpayConfiguration return this } @@ -217,7 +234,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for MolPay Malasya payment method. */ fun addMolpayMalasyaConfiguration(molpayConfiguration: MolpayConfiguration): Builder { - availableConfigs[PaymentMethodTypes.MOLPAY_MALAYSIA] = molpayConfiguration + availablePaymentConfigs[PaymentMethodTypes.MOLPAY_MALAYSIA] = molpayConfiguration return this } @@ -225,7 +242,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for MolPay Vietnam payment method. */ fun addMolpayVietnamConfiguration(molpayConfiguration: MolpayConfiguration): Builder { - availableConfigs[PaymentMethodTypes.MOLPAY_VIETNAM] = molpayConfiguration + availablePaymentConfigs[PaymentMethodTypes.MOLPAY_VIETNAM] = molpayConfiguration return this } @@ -233,7 +250,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for DotPay payment method. */ fun addDotpayConfiguration(dotpayConfiguration: DotpayConfiguration): Builder { - availableConfigs[PaymentMethodTypes.DOTPAY] = dotpayConfiguration + availablePaymentConfigs[PaymentMethodTypes.DOTPAY] = dotpayConfiguration return this } @@ -241,7 +258,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for EPS payment method. */ fun addEpsConfiguration(epsConfiguration: EPSConfiguration): Builder { - availableConfigs[PaymentMethodTypes.EPS] = epsConfiguration + availablePaymentConfigs[PaymentMethodTypes.EPS] = epsConfiguration return this } @@ -249,7 +266,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for EnterCash payment method. */ fun addEntercashConfiguration(entercashConfiguration: EntercashConfiguration): Builder { - availableConfigs[PaymentMethodTypes.ENTERCASH] = entercashConfiguration + availablePaymentConfigs[PaymentMethodTypes.ENTERCASH] = entercashConfiguration return this } @@ -257,7 +274,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for Open Banking payment method. */ fun addOpenBankingConfiguration(openBankingConfiguration: OpenBankingConfiguration): Builder { - availableConfigs[PaymentMethodTypes.OPEN_BANKING] = openBankingConfiguration + availablePaymentConfigs[PaymentMethodTypes.OPEN_BANKING] = openBankingConfiguration return this } @@ -265,7 +282,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for Google Pay payment method. */ fun addGooglePayConfiguration(googlePayConfiguration: GooglePayConfiguration): Builder { - availableConfigs[PaymentMethodTypes.GOOGLE_PAY] = googlePayConfiguration + availablePaymentConfigs[PaymentMethodTypes.GOOGLE_PAY] = googlePayConfiguration return this } @@ -273,7 +290,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for Sepa payment method. */ fun addSepaConfiguration(sepaConfiguration: SepaConfiguration): Builder { - availableConfigs[PaymentMethodTypes.SEPA] = sepaConfiguration + availablePaymentConfigs[PaymentMethodTypes.SEPA] = sepaConfiguration return this } @@ -281,7 +298,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for BCMC payment method. */ fun addBcmcConfiguration(bcmcConfiguration: BcmcConfiguration): Builder { - availableConfigs[PaymentMethodTypes.BCMC] = bcmcConfiguration + availablePaymentConfigs[PaymentMethodTypes.BCMC] = bcmcConfiguration return this } @@ -289,7 +306,7 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for MB WAY payment method. */ fun addMBWayConfiguration(mbwayConfiguration: MBWayConfiguration): Builder { - availableConfigs[PaymentMethodTypes.MB_WAY] = mbwayConfiguration + availablePaymentConfigs[PaymentMethodTypes.MB_WAY] = mbwayConfiguration return this } @@ -297,7 +314,47 @@ class DropInConfiguration : Configuration, Parcelable { * Add configuration for Blik payment method. */ fun addBlikConfiguration(blikConfiguration: BlikConfiguration): Builder { - availableConfigs[PaymentMethodTypes.BLIK] = blikConfiguration + availablePaymentConfigs[PaymentMethodTypes.BLIK] = blikConfiguration + return this + } + + /** + * Add configuration for 3DS2 action. + */ + fun add3ds2ActionConfiguration(configuration: Adyen3DS2Configuration): Builder { + availableActionConfigs[configuration::class.java] = configuration + return this + } + + /** + * Add configuration for Await action. + */ + fun addAwaitActionConfiguration(configuration: AwaitConfiguration): Builder { + availableActionConfigs[configuration::class.java] = configuration + return this + } + + /** + * Add configuration for QR code action. + */ + fun addQRCodeActionConfiguration(configuration: QRCodeConfiguration): Builder { + availableActionConfigs[configuration::class.java] = configuration + return this + } + + /** + * Add configuration for Redirect action. + */ + fun addRedirectActionConfiguration(configuration: RedirectConfiguration): Builder { + availableActionConfigs[configuration::class.java] = configuration + return this + } + + /** + * Add configuration for WeChat Pay action. + */ + fun addWeChatPayActionConfiguration(configuration: WeChatPayActionConfiguration): Builder { + availableActionConfigs[configuration::class.java] = configuration return this } @@ -309,7 +366,8 @@ class DropInConfiguration : Configuration, Parcelable { shopperLocale, environment, clientKey, - availableConfigs, + availablePaymentConfigs, + availableActionConfigs, serviceComponentName, amount ) diff --git a/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt b/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt index 232ac16827..f3dd3f9ace 100644 --- a/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt +++ b/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt @@ -16,6 +16,7 @@ import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate +import com.adyen.checkout.adyen3ds2.Adyen3DS2Configuration import com.adyen.checkout.bcmc.BcmcConfiguration import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.components.model.PaymentMethodsApiResponse @@ -159,6 +160,11 @@ class MainActivity : AppCompatActivity() { .setEnvironment(Environment.TEST) .build() + val adyen3DS2Configuration = Adyen3DS2Configuration.Builder(this@MainActivity, BuildConfig.CLIENT_KEY) + .setShopperLocale(shopperLocale) + .setEnvironment(Environment.TEST) + .build() + val dropInConfigurationBuilder = DropInConfiguration.Builder( this@MainActivity, ExampleDropInService::class.java, @@ -169,6 +175,7 @@ class MainActivity : AppCompatActivity() { .addCardConfiguration(cardConfiguration) .addBcmcConfiguration(bcmcConfiguration) .addGooglePayConfiguration(googlePayConfig) + .add3ds2ActionConfiguration(adyen3DS2Configuration) val amount = keyValueStorage.getAmount() From ef14d0c10d88618616f017ca711ad3f75c0cf33e Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 21 Apr 2021 15:28:10 +0200 Subject: [PATCH 30/63] Remove WeChatPay component --- .../dropin/ComponentParsingProvider.kt | 11 --- .../wechatpay/WeChatPayComponent.java | 68 ------------- .../wechatpay/WeChatPayConfiguration.java | 96 ------------------- .../checkout/wechatpay/WeChatPayProvider.kt | 37 ------- 4 files changed, 212 deletions(-) delete mode 100644 wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayComponent.java delete mode 100644 wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayConfiguration.java delete mode 100644 wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index 57ebb13d0d..8ffb45c099 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -70,8 +70,6 @@ import com.adyen.checkout.sepa.SepaComponent import com.adyen.checkout.sepa.SepaConfiguration import com.adyen.checkout.sepa.SepaView import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration -import com.adyen.checkout.wechatpay.WeChatPayComponent -import com.adyen.checkout.wechatpay.WeChatPayConfiguration object ComponentParsingProvider { val TAG = LogUtil.getTag() @@ -106,7 +104,6 @@ internal fun getDefaultConfigForPaymentMethod( PaymentMethodTypes.MOLPAY_VIETNAM -> MolpayConfiguration.Builder(context, clientKey) PaymentMethodTypes.OPEN_BANKING -> OpenBankingConfiguration.Builder(context, clientKey) PaymentMethodTypes.SEPA -> SepaConfiguration.Builder(context, clientKey) - PaymentMethodTypes.WECHAT_PAY_SDK -> WeChatPayConfiguration.Builder(context, clientKey) else -> throw CheckoutException("Unable to find component configuration for paymentMethod - $paymentMethod") } @@ -180,7 +177,6 @@ internal fun getProviderForType(type: String): PaymentComponentProvider OpenBankingComponent.PROVIDER PaymentMethodTypes.SCHEME -> CardComponent.PROVIDER PaymentMethodTypes.SEPA -> SepaComponent.PROVIDER - PaymentMethodTypes.WECHAT_PAY_SDK -> WeChatPayComponent.PROVIDER else -> { throw CheckoutException("Unable to find component for type - $type") } @@ -299,13 +295,6 @@ internal fun getComponentFor( val sepaConfiguration: SepaConfiguration = dropInConfiguration.getConfigurationForPaymentMethod(PaymentMethodTypes.SEPA, context) SepaComponent.PROVIDER.get(fragment, paymentMethod, sepaConfiguration) } - PaymentMethodTypes.WECHAT_PAY_SDK -> { - val weChatPayConfiguration: WeChatPayConfiguration = dropInConfiguration.getConfigurationForPaymentMethod( - PaymentMethodTypes.WECHAT_PAY_SDK, - context - ) - WeChatPayComponent.PROVIDER.get(fragment, paymentMethod, weChatPayConfiguration) - } else -> { throw CheckoutException("Unable to find component for type - ${paymentMethod.type}") diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayComponent.java b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayComponent.java deleted file mode 100644 index cd6ef901a9..0000000000 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayComponent.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2019 Adyen N.V. - * - * This file is open source and available under the MIT license. See the LICENSE file for more info. - * - * Created by caiof on 17/9/2019. - */ - -package com.adyen.checkout.wechatpay; - -import androidx.annotation.NonNull; - -import com.adyen.checkout.components.GenericComponentState; -import com.adyen.checkout.components.PaymentComponentProvider; -import com.adyen.checkout.components.base.BasePaymentComponent; -import com.adyen.checkout.components.base.EmptyInputData; -import com.adyen.checkout.components.base.EmptyOutputData; -import com.adyen.checkout.components.base.GenericPaymentMethodDelegate; -import com.adyen.checkout.components.base.PaymentMethodDelegate; -import com.adyen.checkout.components.model.payments.request.GenericPaymentMethod; -import com.adyen.checkout.components.model.payments.request.PaymentComponentData; -import com.adyen.checkout.components.util.PaymentMethodTypes; - -public class WeChatPayComponent - extends BasePaymentComponent> { - - public static final PaymentComponentProvider PROVIDER = new WeChatPayProvider(); - - private static final String[] PAYMENT_METHOD_TYPES = {PaymentMethodTypes.WECHAT_PAY_SDK}; - - /** - * Component should not be instantiated directly. Instead use the PROVIDER object. - * - * @param paymentMethodDelegate {@link PaymentMethodDelegate} - * @param configuration {@link WeChatPayConfiguration} - */ - public WeChatPayComponent(@NonNull GenericPaymentMethodDelegate paymentMethodDelegate, @NonNull WeChatPayConfiguration configuration) { - super(paymentMethodDelegate, configuration); - onInputDataChanged(new EmptyInputData()); - } - - @NonNull - @Override - protected EmptyOutputData onInputDataChanged(@NonNull EmptyInputData inputData) { - return new EmptyOutputData(); - } - - @NonNull - @Override - protected GenericComponentState createComponentState() { - final GenericPaymentMethod paymentMethodDetails = new GenericPaymentMethod(PaymentMethodTypes.WECHAT_PAY_SDK); - final PaymentComponentData componentData = new PaymentComponentData<>(); - componentData.setPaymentMethod(paymentMethodDetails); - - return new GenericComponentState<>(componentData, true, true); - } - - @NonNull - @Override - public String[] getSupportedPaymentMethodTypes() { - return PAYMENT_METHOD_TYPES; - } - - @Override - public boolean requiresInput() { - return false; - } -} diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayConfiguration.java b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayConfiguration.java deleted file mode 100644 index 733b994e57..0000000000 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayConfiguration.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2019 Adyen N.V. - * - * This file is open source and available under the MIT license. See the LICENSE file for more info. - * - * Created by caiof on 17/9/2019. - */ - -package com.adyen.checkout.wechatpay; - -import android.content.Context; -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; - -import com.adyen.checkout.components.base.BaseConfigurationBuilder; -import com.adyen.checkout.components.base.Configuration; -import com.adyen.checkout.core.api.Environment; - -import java.util.Locale; - -public class WeChatPayConfiguration extends Configuration { - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public WeChatPayConfiguration createFromParcel(@NonNull Parcel in) { - return new WeChatPayConfiguration(in); - } - - public WeChatPayConfiguration[] newArray(int size) { - return new WeChatPayConfiguration[size]; - } - }; - - protected WeChatPayConfiguration( - @NonNull Locale shopperLocale, - @NonNull Environment environment, - @NonNull String clientKey - ) { - super(shopperLocale, environment, clientKey); - } - - protected WeChatPayConfiguration(@NonNull Parcel in) { - super(in); - } - - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - super.writeToParcel(dest, flags); - } - - /** - * Builder to create a {@link WeChatPayConfiguration}. - */ - public static class Builder extends BaseConfigurationBuilder { - - /** - * Constructor for Builder with default values. - * - * @param context A context - * @param clientKey Your Client Key used for network calls from the SDK to Adyen. - */ - public Builder(@NonNull Context context, @NonNull String clientKey) { - super(context, clientKey); - } - - /** - * Builder with required parameters. - * - * @param shopperLocale The Locale of the shopper. - * @param environment The {@link Environment} to be used for network calls to Adyen. - * @param clientKey Your Client Key used for network calls from the SDK to Adyen. - */ - public Builder(@NonNull Locale shopperLocale, @NonNull Environment environment, @NonNull String clientKey) { - super(shopperLocale, environment, clientKey); - } - - @Override - @NonNull - public Builder setShopperLocale(@NonNull Locale builderShopperLocale) { - return (Builder) super.setShopperLocale(builderShopperLocale); - } - - @Override - @NonNull - public Builder setEnvironment(@NonNull Environment builderEnvironment) { - return (Builder) super.setEnvironment(builderEnvironment); - } - - @NonNull - @Override - public WeChatPayConfiguration build() { - return new WeChatPayConfiguration(mBuilderShopperLocale, mBuilderEnvironment, mBuilderClientKey); - } - } -} diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt deleted file mode 100644 index f47175fe1e..0000000000 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2019 Adyen N.V. - * - * This file is open source and available under the MIT license. See the LICENSE file for more info. - * - * Created by caiof on 17/9/2019. - */ -package com.adyen.checkout.wechatpay - -import android.app.Application -import androidx.lifecycle.ViewModelProvider -import androidx.lifecycle.ViewModelStoreOwner -import com.adyen.checkout.components.ComponentAvailableCallback -import com.adyen.checkout.components.PaymentComponentProvider -import com.adyen.checkout.components.base.GenericPaymentMethodDelegate -import com.adyen.checkout.components.base.lifecycle.viewModelFactory -import com.adyen.checkout.components.model.paymentmethods.PaymentMethod - -class WeChatPayProvider : PaymentComponentProvider { - override operator fun get( - viewModelStoreOwner: ViewModelStoreOwner, - paymentMethod: PaymentMethod, - configuration: WeChatPayConfiguration - ): WeChatPayComponent { - val weChatFactory = viewModelFactory { WeChatPayComponent(GenericPaymentMethodDelegate(paymentMethod), configuration) } - return ViewModelProvider(viewModelStoreOwner, weChatFactory).get(WeChatPayComponent::class.java) - } - - override fun isAvailable( - applicationContext: Application, - paymentMethod: PaymentMethod, - configuration: WeChatPayConfiguration, - callback: ComponentAvailableCallback - ) { - callback.onAvailabilityResult(WeChatPayUtils.isAvailable(applicationContext), paymentMethod, configuration) - } -} From 09750500cb19922d1a6a2bcf5c0d0149a539d2e4 Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 22 Apr 2021 10:17:02 +0200 Subject: [PATCH 31/63] Remove unnecessary assignment in CardConfiguration.Builder --- .../main/java/com/adyen/checkout/card/CardConfiguration.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/card/src/main/java/com/adyen/checkout/card/CardConfiguration.java b/card/src/main/java/com/adyen/checkout/card/CardConfiguration.java index 9c188f34da..9356ae3143 100644 --- a/card/src/main/java/com/adyen/checkout/card/CardConfiguration.java +++ b/card/src/main/java/com/adyen/checkout/card/CardConfiguration.java @@ -168,8 +168,6 @@ public static final class Builder extends BaseConfigurationBuilder Date: Thu, 22 Apr 2021 11:39:45 +0200 Subject: [PATCH 32/63] Add GooglePayParams data class to be used in GooglePayUtils instead of GooglePayConfiguration --- .../model/paymentmethods/Configuration.java | 2 +- .../googlepay/GooglePayComponent.java | 19 +++++- .../checkout/googlepay/GooglePayProvider.kt | 7 +- .../googlepay/model/GooglePayParams.kt | 47 +++++++++++++ .../googlepay/util/GooglePayUtils.java | 66 +++++++++---------- 5 files changed, 103 insertions(+), 38 deletions(-) create mode 100644 googlepay/src/main/java/com/adyen/checkout/googlepay/model/GooglePayParams.kt diff --git a/components-core/src/main/java/com/adyen/checkout/components/model/paymentmethods/Configuration.java b/components-core/src/main/java/com/adyen/checkout/components/model/paymentmethods/Configuration.java index 43eeac0dad..a0fee1a066 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/model/paymentmethods/Configuration.java +++ b/components-core/src/main/java/com/adyen/checkout/components/model/paymentmethods/Configuration.java @@ -21,7 +21,7 @@ import org.json.JSONObject; @SuppressWarnings({"MemberName", "PMD.DataClass"}) -class Configuration extends ModelObject { +public class Configuration extends ModelObject { @NonNull public static final Creator CREATOR = new Creator<>(Configuration.class); diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java index b5b2330833..221306bee3 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java @@ -17,12 +17,14 @@ import com.adyen.checkout.components.PaymentComponentProvider; import com.adyen.checkout.components.base.BasePaymentComponent; import com.adyen.checkout.components.base.GenericPaymentMethodDelegate; +import com.adyen.checkout.components.model.paymentmethods.Configuration; import com.adyen.checkout.components.model.payments.request.GooglePayPaymentMethod; import com.adyen.checkout.components.model.payments.request.PaymentComponentData; import com.adyen.checkout.components.util.PaymentMethodTypes; import com.adyen.checkout.core.exception.ComponentException; import com.adyen.checkout.core.log.LogUtil; import com.adyen.checkout.core.log.Logger; +import com.adyen.checkout.googlepay.model.GooglePayParams; import com.adyen.checkout.googlepay.util.GooglePayUtils; import com.google.android.gms.common.api.Status; import com.google.android.gms.wallet.AutoResolveHelper; @@ -75,10 +77,23 @@ public String[] getSupportedPaymentMethodTypes() { @SuppressWarnings("JavadocReference") public void startGooglePayScreen(@NonNull Activity activity, int requestCode) { Logger.d(TAG, "startGooglePayScreen"); - final PaymentsClient paymentsClient = Wallet.getPaymentsClient(activity, GooglePayUtils.createWalletOptions(getConfiguration())); - final PaymentDataRequest paymentDataRequest = GooglePayUtils.createPaymentDataRequest(getConfiguration()); + final GooglePayParams googlePayParams = getGooglePayParams(); + final PaymentsClient paymentsClient = Wallet.getPaymentsClient(activity, GooglePayUtils.createWalletOptions(googlePayParams)); + final PaymentDataRequest paymentDataRequest = GooglePayUtils.createPaymentDataRequest(googlePayParams); AutoResolveHelper.resolveTask(paymentsClient.loadPaymentData(paymentDataRequest), activity, requestCode); + } + private GooglePayParams getGooglePayParams() { + final Configuration configuration = ((GenericPaymentMethodDelegate) mPaymentMethodDelegate) + .getPaymentMethod() + .getConfiguration(); + final String serverGatewayMerchantId; + if (configuration == null) { + serverGatewayMerchantId = null; + } else { + serverGatewayMerchantId = configuration.getGatewayMerchantId(); + } + return new GooglePayParams(getConfiguration(), serverGatewayMerchantId); } /** diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt index 83f81ced21..cddac72aee 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt @@ -15,6 +15,7 @@ import com.adyen.checkout.components.PaymentComponentProvider import com.adyen.checkout.components.base.GenericPaymentMethodDelegate import com.adyen.checkout.components.base.lifecycle.viewModelFactory import com.adyen.checkout.components.model.paymentmethods.PaymentMethod +import com.adyen.checkout.googlepay.model.GooglePayParams import com.adyen.checkout.googlepay.util.GooglePayUtils import com.google.android.gms.common.ConnectionResult import com.google.android.gms.common.GoogleApiAvailability @@ -46,8 +47,10 @@ class GooglePayProvider : PaymentComponentProvider> = WeakReference>(callback) - val paymentsClient: PaymentsClient = Wallet.getPaymentsClient(applicationContext, GooglePayUtils.createWalletOptions(configuration)) - val readyToPayRequest: IsReadyToPayRequest = GooglePayUtils.createIsReadyToPayRequest(configuration) + val serverGatewayMerchantId = paymentMethod.configuration?.gatewayMerchantId + val params = GooglePayParams(configuration, serverGatewayMerchantId) + val paymentsClient: PaymentsClient = Wallet.getPaymentsClient(applicationContext, GooglePayUtils.createWalletOptions(params)) + val readyToPayRequest: IsReadyToPayRequest = GooglePayUtils.createIsReadyToPayRequest(params) val readyToPayTask: Task = paymentsClient.isReadyToPay(readyToPayRequest) readyToPayTask.addOnCompleteListener { task -> callbackWeakReference.get()?.onAvailabilityResult(task.result == true, paymentMethod, configuration) diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/model/GooglePayParams.kt b/googlepay/src/main/java/com/adyen/checkout/googlepay/model/GooglePayParams.kt new file mode 100644 index 0000000000..2c11e5a26f --- /dev/null +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/model/GooglePayParams.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by josephj on 22/4/2021. + */ + +package com.adyen.checkout.googlepay.model + +import com.adyen.checkout.components.model.payments.Amount +import com.adyen.checkout.core.exception.ComponentException +import com.adyen.checkout.googlepay.GooglePayConfiguration + +/** + * Model class holding the parameters required to build requests for GooglePay + */ +data class GooglePayParams( + private val googlePayConfiguration: GooglePayConfiguration, + private val serverGatewayMerchantId: String? +) { + val gatewayMerchantId: String = getPreferredGatewayMerchantId() + val googlePayEnvironment: Int = googlePayConfiguration.googlePayEnvironment + val amount: Amount = googlePayConfiguration.amount + val countryCode: String? = googlePayConfiguration.countryCode + val merchantInfo: MerchantInfo? = googlePayConfiguration.merchantInfo + val allowedAuthMethods: List? = googlePayConfiguration.allowedAuthMethods + val allowedCardNetworks: List? = googlePayConfiguration.allowedCardNetworks + val isAllowPrepaidCards: Boolean = googlePayConfiguration.isAllowPrepaidCards + val isEmailRequired: Boolean = googlePayConfiguration.isEmailRequired + val isExistingPaymentMethodRequired: Boolean = googlePayConfiguration.isExistingPaymentMethodRequired + val isShippingAddressRequired: Boolean = googlePayConfiguration.isShippingAddressRequired + val shippingAddressParameters: ShippingAddressParameters? = googlePayConfiguration.shippingAddressParameters + val isBillingAddressRequired: Boolean = googlePayConfiguration.isBillingAddressRequired + val billingAddressParameters: BillingAddressParameters? = googlePayConfiguration.billingAddressParameters + + /** + * Returns the gatewayMerchantId provided by the API if available, or falls back to the one provided in GooglePayConfiguration + */ + private fun getPreferredGatewayMerchantId(): String { + return serverGatewayMerchantId + ?: googlePayConfiguration.merchantAccount + ?: throw ComponentException( + "GooglePay merchantAccount not found. Update your API version or pass it manually inside your GooglePayConfiguration" + ) + } +} diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/util/GooglePayUtils.java b/googlepay/src/main/java/com/adyen/checkout/googlepay/util/GooglePayUtils.java index f781a5bf86..3e16a135f5 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/util/GooglePayUtils.java +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/util/GooglePayUtils.java @@ -19,8 +19,8 @@ import com.adyen.checkout.core.exception.NoConstructorException; import com.adyen.checkout.core.log.LogUtil; import com.adyen.checkout.core.log.Logger; -import com.adyen.checkout.googlepay.GooglePayConfiguration; import com.adyen.checkout.googlepay.model.CardParameters; +import com.adyen.checkout.googlepay.model.GooglePayParams; import com.adyen.checkout.googlepay.model.GooglePayPaymentMethodModel; import com.adyen.checkout.googlepay.model.IsReadyToPayRequestModel; import com.adyen.checkout.googlepay.model.PaymentDataRequestModel; @@ -74,25 +74,25 @@ public final class GooglePayUtils { /** * Create a {@link com.google.android.gms.wallet.Wallet.WalletOptions} based on the component configuration. * - * @param configuration The configuration of the Google Pay component. + * @param params The parameters based on the Google Pay component configuration. * @return The WalletOptions object. */ @NonNull - public static Wallet.WalletOptions createWalletOptions(@NonNull GooglePayConfiguration configuration) { + public static Wallet.WalletOptions createWalletOptions(@NonNull GooglePayParams params) { return new Wallet.WalletOptions.Builder() - .setEnvironment(configuration.getGooglePayEnvironment()) + .setEnvironment(params.getGooglePayEnvironment()) .build(); } /** * Create a {@link IsReadyToPayRequest} based on the component configuration that can be used to verify Google Pay availability. * - * @param configuration The configuration of the Google Pay component. + * @param params The parameters based on the Google Pay component configuration. * @return The IsReadyToPayRequest to start the task to verify Google Pay availability */ @NonNull - public static IsReadyToPayRequest createIsReadyToPayRequest(@NonNull GooglePayConfiguration configuration) { - final IsReadyToPayRequestModel isReadyToPayRequestModel = createIsReadyToPayRequestModel(configuration); + public static IsReadyToPayRequest createIsReadyToPayRequest(@NonNull GooglePayParams params) { + final IsReadyToPayRequestModel isReadyToPayRequestModel = createIsReadyToPayRequestModel(params); final String requestJsonString = IsReadyToPayRequestModel.SERIALIZER.serialize(isReadyToPayRequestModel).toString(); return IsReadyToPayRequest.fromJson(requestJsonString); } @@ -100,12 +100,12 @@ public static IsReadyToPayRequest createIsReadyToPayRequest(@NonNull GooglePayCo /** * Create a {@link PaymentDataRequest} based on the component configuration that can be used to start the Google Pay payment. * - * @param configuration The configuration of the Google Pay component. + * @param params The parameters based on the Google Pay component configuration. * @return The PaymentDataRequest to start the Google Pay payment flow. */ @NonNull - public static PaymentDataRequest createPaymentDataRequest(@NonNull GooglePayConfiguration configuration) { - final PaymentDataRequestModel paymentDataRequestModel = createPaymentDataRequestModel(configuration); + public static PaymentDataRequest createPaymentDataRequest(@NonNull GooglePayParams params) { + final PaymentDataRequestModel paymentDataRequestModel = createPaymentDataRequestModel(params); final String requestJsonString = PaymentDataRequestModel.SERIALIZER.serialize(paymentDataRequestModel).toString(); return PaymentDataRequest.fromJson(requestJsonString); } @@ -163,69 +163,69 @@ public static GooglePayPaymentMethod createGooglePayPaymentMethod(@Nullable Paym } } - private static IsReadyToPayRequestModel createIsReadyToPayRequestModel(@NonNull GooglePayConfiguration configuration) { + private static IsReadyToPayRequestModel createIsReadyToPayRequestModel(@NonNull GooglePayParams params) { final IsReadyToPayRequestModel isReadyToPayRequestModel = new IsReadyToPayRequestModel(); isReadyToPayRequestModel.setApiVersion(MAJOR_API_VERSION); isReadyToPayRequestModel.setApiVersionMinor(MINOT_API_VERSION); - isReadyToPayRequestModel.setExistingPaymentMethodRequired(configuration.isExistingPaymentMethodRequired()); + isReadyToPayRequestModel.setExistingPaymentMethodRequired(params.isExistingPaymentMethodRequired()); final ArrayList allowedPaymentMethods = new ArrayList<>(); - allowedPaymentMethods.add(createCardPaymentMethod(configuration)); + allowedPaymentMethods.add(createCardPaymentMethod(params)); isReadyToPayRequestModel.setAllowedPaymentMethods(allowedPaymentMethods); return isReadyToPayRequestModel; } - private static PaymentDataRequestModel createPaymentDataRequestModel(@NonNull GooglePayConfiguration configuration) { + private static PaymentDataRequestModel createPaymentDataRequestModel(@NonNull GooglePayParams params) { final PaymentDataRequestModel paymentDataRequestModel = new PaymentDataRequestModel(); paymentDataRequestModel.setApiVersion(MAJOR_API_VERSION); paymentDataRequestModel.setApiVersionMinor(MINOT_API_VERSION); - paymentDataRequestModel.setMerchantInfo(configuration.getMerchantInfo()); - paymentDataRequestModel.setTransactionInfo(createTransactionInfo(configuration.getAmount(), configuration.getCountryCode())); + paymentDataRequestModel.setMerchantInfo(params.getMerchantInfo()); + paymentDataRequestModel.setTransactionInfo(createTransactionInfo(params.getAmount(), params.getCountryCode())); final ArrayList allowedPaymentMethods = new ArrayList<>(); - allowedPaymentMethods.add(createCardPaymentMethod(configuration)); + allowedPaymentMethods.add(createCardPaymentMethod(params)); paymentDataRequestModel.setAllowedPaymentMethods(allowedPaymentMethods); - paymentDataRequestModel.setEmailRequired(configuration.isEmailRequired()); - paymentDataRequestModel.setShippingAddressRequired(configuration.isShippingAddressRequired()); - paymentDataRequestModel.setShippingAddressParameters(configuration.getShippingAddressParameters()); + paymentDataRequestModel.setEmailRequired(params.isEmailRequired()); + paymentDataRequestModel.setShippingAddressRequired(params.isShippingAddressRequired()); + paymentDataRequestModel.setShippingAddressParameters(params.getShippingAddressParameters()); return paymentDataRequestModel; } - private static GooglePayPaymentMethodModel createCardPaymentMethod(@NonNull GooglePayConfiguration configuration) { + private static GooglePayPaymentMethodModel createCardPaymentMethod(@NonNull GooglePayParams params) { final GooglePayPaymentMethodModel cardPaymentMethod = new GooglePayPaymentMethodModel(); cardPaymentMethod.setType(PAYMENT_TYPE_CARD); - cardPaymentMethod.setParameters(createCardParameters(configuration)); - cardPaymentMethod.setTokenizationSpecification(createTokenizationSpecification(configuration)); + cardPaymentMethod.setParameters(createCardParameters(params)); + cardPaymentMethod.setTokenizationSpecification(createTokenizationSpecification(params)); return cardPaymentMethod; } - private static CardParameters createCardParameters(@NonNull GooglePayConfiguration configuration) { + private static CardParameters createCardParameters(@NonNull GooglePayParams params) { final CardParameters cardParameters = new CardParameters(); - cardParameters.setAllowedAuthMethods(configuration.getAllowedAuthMethods()); - cardParameters.setAllowedCardNetworks(configuration.getAllowedCardNetworks()); - cardParameters.setAllowPrepaidCards(configuration.isAllowPrepaidCards()); - cardParameters.setBillingAddressRequired(configuration.isBillingAddressRequired()); - cardParameters.setBillingAddressParameters(configuration.getBillingAddressParameters()); + cardParameters.setAllowedAuthMethods(params.getAllowedAuthMethods()); + cardParameters.setAllowedCardNetworks(params.getAllowedCardNetworks()); + cardParameters.setAllowPrepaidCards(params.isAllowPrepaidCards()); + cardParameters.setBillingAddressRequired(params.isBillingAddressRequired()); + cardParameters.setBillingAddressParameters(params.getBillingAddressParameters()); return cardParameters; } - private static PaymentMethodTokenizationSpecification createTokenizationSpecification(@NonNull GooglePayConfiguration configuration) { + private static PaymentMethodTokenizationSpecification createTokenizationSpecification(@NonNull GooglePayParams params) { final PaymentMethodTokenizationSpecification tokenizationSpecification = new PaymentMethodTokenizationSpecification(); tokenizationSpecification.setType(PAYMENT_GATEWAY); - tokenizationSpecification.setParameters(createGatewayParameters(configuration)); + tokenizationSpecification.setParameters(createGatewayParameters(params)); return tokenizationSpecification; } - private static TokenizationParameters createGatewayParameters(@NonNull GooglePayConfiguration configuration) { + private static TokenizationParameters createGatewayParameters(@NonNull GooglePayParams params) { final TokenizationParameters tokenizationParameters = new TokenizationParameters(); tokenizationParameters.setGateway(ADYEN_GATEWAY); - tokenizationParameters.setGatewayMerchantId(configuration.getMerchantAccount()); + tokenizationParameters.setGatewayMerchantId(params.getGatewayMerchantId()); return tokenizationParameters; } From 0058cb3dcf7c662c038fd8fe52bc7d75f7c3979e Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 22 Apr 2021 11:43:47 +0200 Subject: [PATCH 33/63] Remove unnecessary merchantAccount from GooglePayConfiguration.Builder --- .../adyen/checkout/example/ui/main/MainActivity.kt | 2 +- .../checkout/googlepay/GooglePayConfiguration.java | 12 ++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt b/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt index f3dd3f9ace..c5197851d7 100644 --- a/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt +++ b/example-app/src/main/java/com/adyen/checkout/example/ui/main/MainActivity.kt @@ -150,7 +150,7 @@ class MainActivity : AppCompatActivity() { .setEnvironment(Environment.TEST) .build() - val googlePayConfig = GooglePayConfiguration.Builder(this@MainActivity, BuildConfig.CLIENT_KEY, keyValueStorage.getMerchantAccount()) + val googlePayConfig = GooglePayConfiguration.Builder(this@MainActivity, BuildConfig.CLIENT_KEY) .setCountryCode(keyValueStorage.getCountry()) .setEnvironment(Environment.TEST) .build() diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java index 3543134475..89b6607979 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java @@ -64,7 +64,7 @@ public GooglePayConfiguration[] newArray(int size) { @NonNull Locale shopperLocale, @NonNull Environment environment, @NonNull String clientKey, - @NonNull String merchantAccount, + @Nullable String merchantAccount, int googlePayEnvironment, @NonNull Amount amount, @Nullable String countryCode, @@ -133,7 +133,7 @@ public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeParcelable(mBillingAddressParameters, flags); } - @NonNull + @Nullable public String getMerchantAccount() { return mMerchantAccount; } @@ -229,11 +229,9 @@ private static Amount createDefaultAmount() { * * @param context A context to get some information. * @param clientKey Your Client Key used for network calls from the SDK to Adyen. - * @param merchantAccount Your merchant account with Adyen. */ - public Builder(@NonNull Context context, @NonNull String clientKey, @NonNull String merchantAccount) { + public Builder(@NonNull Context context, @NonNull String clientKey) { super(context, clientKey); - mBuilderMerchantAccount = merchantAccount; } /** @@ -242,11 +240,9 @@ public Builder(@NonNull Context context, @NonNull String clientKey, @NonNull Str * @param shopperLocale The locale of the Shopper for translation. * @param environment TThe {@link Environment} to be used for network calls to Adyen. * @param clientKey Your Client Key used for network calls from the SDK to Adyen. - * @param merchantAccount Your merchant account with Adyen. */ - public Builder(@NonNull Locale shopperLocale, @NonNull Environment environment, @NonNull String clientKey, @NonNull String merchantAccount) { + public Builder(@NonNull Locale shopperLocale, @NonNull Environment environment, @NonNull String clientKey) { super(shopperLocale, environment, clientKey); - mBuilderMerchantAccount = merchantAccount; } @Override From 30d0cf69b2bf88857ce3717dc47798716703b10e Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 22 Apr 2021 11:45:04 +0200 Subject: [PATCH 34/63] Provide a default config for SCHEME and GOOGLE_PAY in drop-in --- .../adyen/checkout/dropin/ComponentParsingProvider.kt | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index 8ffb45c099..d5c8f04f81 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -81,14 +81,6 @@ internal fun getDefaultConfigForPaymentMethod( context: Context, dropInConfiguration: DropInConfiguration ): T { - - // TODO after fetching public key is enabled, build scheme if client key is present - val specificRequirementConfigs = listOf(PaymentMethodTypes.SCHEME, PaymentMethodTypes.GOOGLE_PAY) - - if (specificRequirementConfigs.contains(paymentMethod)) { - throw CheckoutException("Cannot provide default config for $paymentMethod. Please add it to the DropInConfiguration with required fields.") - } - val clientKey = dropInConfiguration.clientKey // get default builder for Configuration type @@ -97,6 +89,7 @@ internal fun getDefaultConfigForPaymentMethod( PaymentMethodTypes.DOTPAY -> DotpayConfiguration.Builder(context, clientKey) PaymentMethodTypes.ENTERCASH -> EntercashConfiguration.Builder(context, clientKey) PaymentMethodTypes.EPS -> EPSConfiguration.Builder(context, clientKey) + PaymentMethodTypes.GOOGLE_PAY -> GooglePayConfiguration.Builder(context, clientKey) PaymentMethodTypes.IDEAL -> IdealConfiguration.Builder(context, clientKey) PaymentMethodTypes.MB_WAY -> MBWayConfiguration.Builder(context, clientKey) PaymentMethodTypes.MOLPAY_THAILAND, @@ -104,6 +97,7 @@ internal fun getDefaultConfigForPaymentMethod( PaymentMethodTypes.MOLPAY_VIETNAM -> MolpayConfiguration.Builder(context, clientKey) PaymentMethodTypes.OPEN_BANKING -> OpenBankingConfiguration.Builder(context, clientKey) PaymentMethodTypes.SEPA -> SepaConfiguration.Builder(context, clientKey) + PaymentMethodTypes.SCHEME -> CardConfiguration.Builder(context, clientKey) else -> throw CheckoutException("Unable to find component configuration for paymentMethod - $paymentMethod") } From 21e1e910fbbbe371696b029e08eb608b573d8892 Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 22 Apr 2021 11:55:15 +0200 Subject: [PATCH 35/63] Initialize default GooglePay environment based on the merchant's Adyen environment --- .../googlepay/GooglePayConfiguration.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java index 89b6607979..36122f103d 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayConfiguration.java @@ -203,7 +203,7 @@ public BillingAddressParameters getBillingAddressParameters() { public static final class Builder extends BaseConfigurationBuilder { private String mBuilderMerchantAccount; - private int mBuilderGooglePayEnvironment = WalletConstants.ENVIRONMENT_TEST; + private int mBuilderGooglePayEnvironment = getDefaultGooglePayEnvironment(); private Amount mBuilderAmount = createDefaultAmount(); private MerchantInfo mBuilderMerchantInfo = null; private String mBuilderCountryCode = null; @@ -217,6 +217,13 @@ public static final class Builder extends BaseConfigurationBuilder Date: Thu, 22 Apr 2021 12:31:45 +0200 Subject: [PATCH 36/63] Update Gradle, android plugin and Kotlin versions. --- build.gradle | 4 ++-- config/gradle/checksums.gradle | 13 +++++++------ gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 7583b4a598..4bf9ac0ae1 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,8 @@ ext { buildscript { // Build Script - ext.android_gradle_plugin_version = '4.0.0' - ext.kotlin_version = '1.4.21' + ext.android_gradle_plugin_version = '4.1.0' + ext.kotlin_version = '1.4.32' ext.detekt_gradle_plugin_version = "1.13.1" ext.spotbugs_gradle_plugin_version = "4.5.1" ext.dokka_version = "1.4.20" diff --git a/config/gradle/checksums.gradle b/config/gradle/checksums.gradle index 8e2bce592f..47cf33bb40 100644 --- a/config/gradle/checksums.gradle +++ b/config/gradle/checksums.gradle @@ -12,12 +12,12 @@ if (!hasProperty("checksums")) { "com.adyen.threeds:adyen-3ds2:2.2.0:42314ec7f7f54b5fd9a77c12e59ae78d:MD5", // Kotlin - "org.jetbrains.kotlin:kotlin-stdlib:1.4.21:7b39fb8c6921178b139097b57fcdb046:MD5", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.21:3508a68d0c8cc354c42ca93e3ce0ef8e:MD5", - "org.jetbrains.kotlin:kotlin-android-extensions:1.4.21:d368e15fe6b52cdc7d552e601d2fabb0:MD5", - "org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.4.21:b60cf62e1d1ee16982940063dfa7b4ff:MD5", - "org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.21:9f6b0eaedc0a519b3d0964ac66c4810b:MD5", - "org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.4.21:fac5561ef8929962bab40ac50c94f8cc:MD5", + "org.jetbrains.kotlin:kotlin-stdlib:1.4.32:3be731bc74b5d1737559299a94b9248f:MD5", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.32:859460a9d6807e2627f366b14326b8d6:MD5", + "org.jetbrains.kotlin:kotlin-android-extensions:1.4.32:d368e15fe6b52cdc7d552e601d2fabb0:MD5", + "org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.4.32:b60cf62e1d1ee16982940063dfa7b4ff:MD5", + "org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.32:2b2fbc3503ec020d81673333d837d72f:MD5", + "org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.4.32:65d251d11636b869c10333a7bd01800c:MD5", // Coroutines "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2:caff3d53c3f68b5ba4855c4dcdc2df95:MD5", @@ -30,6 +30,7 @@ if (!hasProperty("checksums")) { "androidx.databinding:viewbinding:4.0.0:3d374767653c1e3892d067f57a2c969e:MD5", "androidx.recyclerview:recyclerview:1.1.0:b34afe47d8523d52ca130267cc0776df:MD5", "androidx.browser:browser:1.3.0:f4bd0b4782e1a25c4c3fae304aa982c2:MD5", + "androidx.databinding:viewbinding:4.1.0:6e16accfd0607f2d149ef1a58c74dd1f:MD5", // Google "com.google.android.material:material:1.3.0:5909e7762bdbf3704c7fe8a0ed71ee40:MD5", diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index eed5c759a8..03a8476b83 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip From 32eebddbd13b6858b50f1f04d8787962970cf815 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Thu, 22 Apr 2021 12:33:39 +0200 Subject: [PATCH 37/63] Fix comment on github action. --- .github/workflows/publish_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index 070380ac62..37fde85d72 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -38,7 +38,7 @@ jobs: git fetch --unshallow sudo bash -c "echo '$GPG_KEY_CONTENTS' | base64 -d > '$SIGNING_SECRET_KEY_RING_FILE'" - # Packages and publishes the AARs to Bintray + # Packages and publishes to Maven Central - name: Publish to Maven Central run: ./gradlew publishReleasePublicationToSonatypeRepository --max-workers 1 --stacktrace env: From e429e6cdbc6db4958a33c97d7298ffd6a61edc62 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Thu, 22 Apr 2021 15:13:47 +0200 Subject: [PATCH 38/63] Add CHECKOUT_VERSION to BuildConfig since VERSION_NAME has been removed. --- .../components/analytics/AnalyticEvent.java | 2 +- config/gradle/sharedTasks.gradle | 1 + config/gradle/versionName.gradle | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 config/gradle/versionName.gradle diff --git a/components-core/src/main/java/com/adyen/checkout/components/analytics/AnalyticEvent.java b/components-core/src/main/java/com/adyen/checkout/components/analytics/AnalyticEvent.java index 99d74f89f8..e5fbcf8768 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/analytics/AnalyticEvent.java +++ b/components-core/src/main/java/com/adyen/checkout/components/analytics/AnalyticEvent.java @@ -52,7 +52,7 @@ public enum Flavor { } private final String mPayloadVersion = CURRENT_PAYLOAD_VERSION; - private final String mVersion = BuildConfig.VERSION_NAME; + private final String mVersion = BuildConfig.CHECKOUT_VERSION; // e.g: 'dropin', 'component' private final String mFlavor; // e.g: dropin, paymentType diff --git a/config/gradle/sharedTasks.gradle b/config/gradle/sharedTasks.gradle index f6aace8d75..8bfcfac7b5 100644 --- a/config/gradle/sharedTasks.gradle +++ b/config/gradle/sharedTasks.gradle @@ -8,6 +8,7 @@ final kotlinSupport = new FileNameFinder().getFileNames("$project.projectDir/src", "**/*.kt").size() > 0 +apply from: "${rootDir}/config/gradle/versionName.gradle" apply from: "../config/gradle/checksums.gradle" apply from: "../config/gradle/dependenciesCheck.gradle" apply from: "../config/gradle/codeQuality.gradle" diff --git a/config/gradle/versionName.gradle b/config/gradle/versionName.gradle new file mode 100644 index 0000000000..21cb75cc9f --- /dev/null +++ b/config/gradle/versionName.gradle @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by caiof on 22/4/2021. + */ + +android { + defaultConfig { + buildConfigField "String", "CHECKOUT_VERSION", "\"$version_name\"" + } +} + From b4b3e167c275d8e36b197856dec2a55cf93cc420 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Thu, 22 Apr 2021 15:17:50 +0200 Subject: [PATCH 39/63] On Gradle files, use rootDir for direct path instead of relative previous path. --- 3ds2/build.gradle | 2 +- await/build.gradle | 2 +- bcmc/build.gradle | 2 +- blik/build.gradle | 2 +- card/build.gradle | 2 +- checkout-core/build.gradle | 2 +- components-core/build.gradle | 2 +- config/gradle/artifacts.gradle | 4 ++-- config/gradle/codeQuality.gradle | 12 ++++++------ config/gradle/release.gradle | 2 +- config/gradle/sharedTasks.gradle | 12 ++++++------ config/module/template/build.gradle | 2 +- cse/build.gradle | 2 +- dotpay/build.gradle | 2 +- drop-in/build.gradle | 2 +- entercash/build.gradle | 2 +- eps/build.gradle | 2 +- example-app/build.gradle | 6 +++--- googlepay/build.gradle | 2 +- ideal/build.gradle | 2 +- issuer-list/build.gradle | 2 +- mbway/build.gradle | 2 +- molpay/build.gradle | 2 +- openbanking/build.gradle | 2 +- qr-code/build.gradle | 2 +- redirect/build.gradle | 2 +- sepa/build.gradle | 2 +- ui-core/build.gradle | 2 +- wechatpay/build.gradle | 2 +- 29 files changed, 42 insertions(+), 42 deletions(-) diff --git a/3ds2/build.gradle b/3ds2/build.gradle index 80af5b928f..2a590f8a87 100644 --- a/3ds2/build.gradle +++ b/3ds2/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "3ds2" ext.mavenArtifactName = "Adyen checkout 3DS2 component" ext.mavenArtifactDescription = "Adyen Checkout 3DS2 component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/await/build.gradle b/await/build.gradle index cec695ec16..07f2c25ab6 100644 --- a/await/build.gradle +++ b/await/build.gradle @@ -15,7 +15,7 @@ ext.mavenArtifactId = "await" ext.mavenArtifactName = "Adyen Checkout Await component" ext.mavenArtifactDescription = "Adyen checkout await component for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/bcmc/build.gradle b/bcmc/build.gradle index 02b3bac9e4..34a158cc08 100644 --- a/bcmc/build.gradle +++ b/bcmc/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "bcmc" ext.mavenArtifactName = "Adyen checkout BCMC component" ext.mavenArtifactDescription = "Adyen checkout BCMC component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/blik/build.gradle b/blik/build.gradle index 7c7af3defc..9b88340e9f 100644 --- a/blik/build.gradle +++ b/blik/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "blik" ext.mavenArtifactName = "Adyen Checkout Blik Component" ext.mavenArtifactDescription = "Adyen Checkout Blik Component" -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/card/build.gradle b/card/build.gradle index 538bf15987..165c542a83 100644 --- a/card/build.gradle +++ b/card/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "card" ext.mavenArtifactName = "Adyen Checkout Card component" ext.mavenArtifactDescription = "Adyen checkout Card component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/checkout-core/build.gradle b/checkout-core/build.gradle index b34f0b76bb..205a49a31a 100644 --- a/checkout-core/build.gradle +++ b/checkout-core/build.gradle @@ -15,7 +15,7 @@ ext.mavenArtifactId = "checkout-core" ext.mavenArtifactName = "Adyen Checkout Core module" ext.mavenArtifactDescription = "Core module for Adyen Checkout products." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/components-core/build.gradle b/components-core/build.gradle index 0159b8fad2..20ad12c25b 100644 --- a/components-core/build.gradle +++ b/components-core/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "components-core" ext.mavenArtifactName = "Adyen Checkout Components Core" ext.mavenArtifactDescription = "Adyen checkout Components Core module." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/config/gradle/artifacts.gradle b/config/gradle/artifacts.gradle index 6dcc8529ad..5b345c6cfd 100644 --- a/config/gradle/artifacts.gradle +++ b/config/gradle/artifacts.gradle @@ -6,8 +6,8 @@ * Created by ran on 6/2/2019. */ -apply from: "../config/gradle/dokka.gradle" -apply from: "../config/gradle/sources.gradle" +apply from: "${rootDir}/config/gradle/dokka.gradle" +apply from: "${rootDir}/config/gradle/sources.gradle" artifacts { archives androidSourcesJar diff --git a/config/gradle/codeQuality.gradle b/config/gradle/codeQuality.gradle index a22be72fc3..826a7e8426 100644 --- a/config/gradle/codeQuality.gradle +++ b/config/gradle/codeQuality.gradle @@ -6,11 +6,11 @@ * Created by ran on 6/2/2019. */ -apply from: "../config/gradle/checkstyle.gradle" -apply from: "../config/gradle/lint.gradle" -apply from: "../config/gradle/ktlint.gradle" -apply from: "../config/gradle/pmd.gradle" -apply from:"../config/gradle/spotbugs.gradle" -apply from: "../config/gradle/detekt.gradle" +apply from: "${rootDir}/config/gradle/checkstyle.gradle" +apply from: "${rootDir}/config/gradle/lint.gradle" +apply from: "${rootDir}/config/gradle/ktlint.gradle" +apply from: "${rootDir}/config/gradle/pmd.gradle" +apply from:"${rootDir}/config/gradle/spotbugs.gradle" +apply from: "${rootDir}/config/gradle/detekt.gradle" check.dependsOn "checkstyle", "lint", "ktlint", "pmd", "detekt", "spotbugsDebug", "spotbugsRelease" \ No newline at end of file diff --git a/config/gradle/release.gradle b/config/gradle/release.gradle index 757e93bd73..344211911b 100644 --- a/config/gradle/release.gradle +++ b/config/gradle/release.gradle @@ -8,7 +8,7 @@ apply plugin: "maven-publish" apply plugin: "signing" -apply from: "../config/gradle/artifacts.gradle" +apply from: "${rootDir}/config/gradle/artifacts.gradle" ext["signing.keyId"] = '' ext["signing.password"] = '' diff --git a/config/gradle/sharedTasks.gradle b/config/gradle/sharedTasks.gradle index 8bfcfac7b5..0675264bf6 100644 --- a/config/gradle/sharedTasks.gradle +++ b/config/gradle/sharedTasks.gradle @@ -9,9 +9,9 @@ final kotlinSupport = new FileNameFinder().getFileNames("$project.projectDir/src", "**/*.kt").size() > 0 apply from: "${rootDir}/config/gradle/versionName.gradle" -apply from: "../config/gradle/checksums.gradle" -apply from: "../config/gradle/dependenciesCheck.gradle" -apply from: "../config/gradle/codeQuality.gradle" -apply from: "../config/gradle/ci.gradle" -apply from: "../config/gradle/release.gradle" -apply from: "../config/gradle/runConnectedAndroidTest.gradle" \ No newline at end of file +apply from: "${rootDir}/config/gradle/checksums.gradle" +apply from: "${rootDir}/config/gradle/dependenciesCheck.gradle" +apply from: "${rootDir}/config/gradle/codeQuality.gradle" +apply from: "${rootDir}/config/gradle/ci.gradle" +apply from: "${rootDir}/config/gradle/release.gradle" +apply from: "${rootDir}/config/gradle/runConnectedAndroidTest.gradle" \ No newline at end of file diff --git a/config/module/template/build.gradle b/config/module/template/build.gradle index 365466c3da..573a399cb5 100644 --- a/config/module/template/build.gradle +++ b/config/module/template/build.gradle @@ -7,7 +7,7 @@ ext.mavenArtifactId = "#module_name" ext.mavenArtifactName = "Adyen checkout #module_name component" ext.mavenArtifactDescription = "Adyen checkout #module_name component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/cse/build.gradle b/cse/build.gradle index 2d7ef9e98d..b03058f9fd 100644 --- a/cse/build.gradle +++ b/cse/build.gradle @@ -8,7 +8,7 @@ ext.mavenArtifactId = "cse" ext.mavenArtifactName = "Adyen Client Side Encryption" ext.mavenArtifactDescription = "Adyen Client Side Encryption for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/dotpay/build.gradle b/dotpay/build.gradle index aecf56ddc6..7c46882b77 100644 --- a/dotpay/build.gradle +++ b/dotpay/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "dotpay" ext.mavenArtifactName = "Adyen checkout Dotpay component" ext.mavenArtifactDescription = "Adyen checkout Dotpay component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/drop-in/build.gradle b/drop-in/build.gradle index 84b1e28594..b97ea92548 100644 --- a/drop-in/build.gradle +++ b/drop-in/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "drop-in" ext.mavenArtifactName = "Adyen checkout drop-in component" ext.mavenArtifactDescription = "Adyen checkout drop-in component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/entercash/build.gradle b/entercash/build.gradle index 49ea38725e..86beb79ada 100644 --- a/entercash/build.gradle +++ b/entercash/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "entercash" ext.mavenArtifactName = "Adyen checkout Entercash component" ext.mavenArtifactDescription = "Adyen checkout Entercash component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/eps/build.gradle b/eps/build.gradle index b9702582cf..dbd8466b92 100644 --- a/eps/build.gradle +++ b/eps/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "eps" ext.mavenArtifactName = "Adyen checkout EPS component" ext.mavenArtifactDescription = "Adyen checkout EPS component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/example-app/build.gradle b/example-app/build.gradle index b57178a9d3..21f4ac2200 100644 --- a/example-app/build.gradle +++ b/example-app/build.gradle @@ -11,8 +11,8 @@ plugins { id 'kotlin-android' } -apply from: "../config/gradle/codeQuality.gradle" -apply from: "../config/gradle/ci.gradle" +apply from: "${rootDir}/config/gradle/codeQuality.gradle" +apply from: "${rootDir}/config/gradle/ci.gradle" if (file("local.gradle").exists()) { apply from: "local.gradle" @@ -24,7 +24,7 @@ if (file("local.gradle").exists()) { // This runConnectedAndroidTest.gradle script is applied, // so it will be possible to run the example app connected android tests // in Jenkins release process. -apply from: "../config/gradle/runConnectedAndroidTest.gradle" +apply from: "${rootDir}/config/gradle/runConnectedAndroidTest.gradle" android { compileSdkVersion compile_sdk_version diff --git a/googlepay/build.gradle b/googlepay/build.gradle index 56888fd6f0..68cea02d0b 100644 --- a/googlepay/build.gradle +++ b/googlepay/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "googlepay" ext.mavenArtifactName = "Adyen checkout Google Pay component" ext.mavenArtifactDescription = "Adyen checkout Google Pay component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/ideal/build.gradle b/ideal/build.gradle index 1b44954eb0..bf3dd8dcf4 100644 --- a/ideal/build.gradle +++ b/ideal/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "ideal" ext.mavenArtifactName = "Adyen checkout iDEAL component" ext.mavenArtifactDescription = "Adyen checkout iDEAL component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/issuer-list/build.gradle b/issuer-list/build.gradle index 0174f537e2..13a1e0be8f 100644 --- a/issuer-list/build.gradle +++ b/issuer-list/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "issuer-list" ext.mavenArtifactName = "Adyen checkout issuer list component" ext.mavenArtifactDescription = "Adyen checkout issuer list component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/mbway/build.gradle b/mbway/build.gradle index 6ffff5bd0f..51617396e6 100644 --- a/mbway/build.gradle +++ b/mbway/build.gradle @@ -15,7 +15,7 @@ ext.mavenArtifactId = "mbway" ext.mavenArtifactName = "Adyen checkout MB WAY component" ext.mavenArtifactDescription = "Adyen checkout MB WAY component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/molpay/build.gradle b/molpay/build.gradle index 4c30d7f155..65e9a0586a 100644 --- a/molpay/build.gradle +++ b/molpay/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "molpay" ext.mavenArtifactName = "Adyen checkout MOLPay component" ext.mavenArtifactDescription = "Adyen checkout MOLPay component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/openbanking/build.gradle b/openbanking/build.gradle index 82fc507f50..2b796f15a1 100644 --- a/openbanking/build.gradle +++ b/openbanking/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "openbanking" ext.mavenArtifactName = "Adyen checkout Open Banking component" ext.mavenArtifactDescription = "Adyen checkout Open Banking component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/qr-code/build.gradle b/qr-code/build.gradle index 9fac650953..b2cdbcfcd6 100644 --- a/qr-code/build.gradle +++ b/qr-code/build.gradle @@ -15,7 +15,7 @@ ext.mavenArtifactId = "qr-code" ext.mavenArtifactName = "Adyen checkout QR code component" ext.mavenArtifactDescription = "Adyen checkout QR code component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/redirect/build.gradle b/redirect/build.gradle index 5c664278ff..c75ad36a69 100644 --- a/redirect/build.gradle +++ b/redirect/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "redirect" ext.mavenArtifactName = "Adyen checkout redirect component" ext.mavenArtifactDescription = "Adyen checkout redirect component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/sepa/build.gradle b/sepa/build.gradle index dd0f39b44a..7c6f7d1884 100644 --- a/sepa/build.gradle +++ b/sepa/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "sepa" ext.mavenArtifactName = "Adyen checkout SEPA component" ext.mavenArtifactDescription = "Adyen checkout SEPA component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/ui-core/build.gradle b/ui-core/build.gradle index c11543651a..3fad037173 100644 --- a/ui-core/build.gradle +++ b/ui-core/build.gradle @@ -16,7 +16,7 @@ ext.mavenArtifactId = "ui-core" ext.mavenArtifactName = "Adyen checkout base UI component" ext.mavenArtifactDescription = "Adyen checkout base UI component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version diff --git a/wechatpay/build.gradle b/wechatpay/build.gradle index d168e562e2..6fd2d6749e 100644 --- a/wechatpay/build.gradle +++ b/wechatpay/build.gradle @@ -15,7 +15,7 @@ ext.mavenArtifactId = "wechatpay" ext.mavenArtifactName = "Adyen Checkout WeChat Pay component" ext.mavenArtifactDescription = "Adyen checkout WeChat Pay component client for Adyen's Checkout API." -apply from: "../config/gradle/sharedTasks.gradle" +apply from: "${rootDir}/config/gradle/sharedTasks.gradle" android { compileSdkVersion compile_sdk_version From 5b9733918308128491bb2d21373ce455e1ca350a Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Fri, 23 Apr 2021 10:46:52 +0200 Subject: [PATCH 40/63] Fix Checkstyle version so it's not automatically update with gradle wrapper. Fix issues on rules XML. --- config/checkstyle/checkstyle-rules-adyen.xml | 4 ++-- config/gradle/checkstyle.gradle | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config/checkstyle/checkstyle-rules-adyen.xml b/config/checkstyle/checkstyle-rules-adyen.xml index 5298441ac9..0f85f5d4c7 100644 --- a/config/checkstyle/checkstyle-rules-adyen.xml +++ b/config/checkstyle/checkstyle-rules-adyen.xml @@ -129,10 +129,10 @@ - + - + diff --git a/config/gradle/checkstyle.gradle b/config/gradle/checkstyle.gradle index 750afd97a9..1725fc9298 100644 --- a/config/gradle/checkstyle.gradle +++ b/config/gradle/checkstyle.gradle @@ -14,7 +14,8 @@ task checkstyle(type: Checkstyle) { ignoreFailures false - configFile = file("$rootProject.rootDir/config/checkstyle/checkstyle-rules-adyen.xml") + project.ext.checkstyleVersion = '8.411' + configFile = file("${rootDir}/config/checkstyle/checkstyle-rules-adyen.xml") source = fileTree("src/main/java") include "**/*.java" exclude "**/gen/**" @@ -25,6 +26,6 @@ task checkstyle(type: Checkstyle) { reports { xml.enabled false html.enabled true - html.destination file("$project.buildDir/reports/checkstyle/checkstyle-results.html") + html.destination file("${project.buildDir}/reports/checkstyle/checkstyle-results.html") } } \ No newline at end of file From c3541a792a1180615ffe7e2d86256639b220538f Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Fri, 23 Apr 2021 11:13:52 +0200 Subject: [PATCH 41/63] Fix false positive and small issue. --- .../com/adyen/checkout/core/model/ModelUtils.java | 2 +- config/checkstyle/checkstyle-rules-adyen.xml | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/checkout-core/src/main/java/com/adyen/checkout/core/model/ModelUtils.java b/checkout-core/src/main/java/com/adyen/checkout/core/model/ModelUtils.java index 400fc9700a..d5ad946d67 100644 --- a/checkout-core/src/main/java/com/adyen/checkout/core/model/ModelUtils.java +++ b/checkout-core/src/main/java/com/adyen/checkout/core/model/ModelUtils.java @@ -65,7 +65,7 @@ public static T deserializeOpt(@Nullable JSONObject json * @param jsonArray The JSONArray to be parsed. * @param serializer The serializer of the ModelObject class to be used. * @param The type o the ModelObject class to be parse to. - * @return + * @return The List of objects from the JSONArray. */ @Nullable public static List deserializeOptList(@Nullable JSONArray jsonArray, @NonNull ModelObject.Serializer serializer) { diff --git a/config/checkstyle/checkstyle-rules-adyen.xml b/config/checkstyle/checkstyle-rules-adyen.xml index 0f85f5d4c7..aea40581c1 100644 --- a/config/checkstyle/checkstyle-rules-adyen.xml +++ b/config/checkstyle/checkstyle-rules-adyen.xml @@ -79,12 +79,12 @@ - - - - - + + + + + + From 17ec40c6a59c03b59e6c81e6a67159165682ae4b Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Wed, 28 Apr 2021 15:57:35 +0200 Subject: [PATCH 42/63] Don't pass threeDSRequestorAppURL on challenges in version 2.1.0 --- .../java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt b/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt index be762dc2a8..6b8ad44d16 100644 --- a/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt +++ b/3ds2/src/main/java/com/adyen/checkout/adyen3ds2/Adyen3DS2Component.kt @@ -271,7 +271,10 @@ class Adyen3DS2Component(application: Application, configuration: Adyen3DS2Confi acsTransactionID = challenge.acsTransID acsRefNumber = challenge.acsReferenceNumber acsSignedContent = challenge.acsSignedContent - threeDSRequestorAppURL = ChallengeParameters.getEmbeddedRequestorAppURL(getApplication()) + // This field was introduced in version 2.2.0 so older protocols don't expect it to be present and might throw an error. + if (challenge.messageVersion != PROTOCOL_VERSION_2_1_0) { + threeDSRequestorAppURL = ChallengeParameters.getEmbeddedRequestorAppURL(getApplication()) + } } } @@ -319,6 +322,7 @@ class Adyen3DS2Component(application: Application, configuration: Adyen3DS2Confi private const val FINGERPRINT_DETAILS_KEY = "threeds2.fingerprint" private const val CHALLENGE_DETAILS_KEY = "threeds2.challengeResult" private const val DEFAULT_CHALLENGE_TIME_OUT = 10 + private const val PROTOCOL_VERSION_2_1_0 = "2.1.0" private var sGotDestroyedWhileChallenging = false } From 63c9b3393342ca6c0ddcec7ebff6066e89f547d5 Mon Sep 17 00:00:00 2001 From: jreij Date: Mon, 26 Apr 2021 15:05:09 +0200 Subject: [PATCH 43/63] Add Pix translations --- qr-code/src/main/res/template/values/strings.xml.tt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qr-code/src/main/res/template/values/strings.xml.tt b/qr-code/src/main/res/template/values/strings.xml.tt index 57397b3cd0..de42098654 100644 --- a/qr-code/src/main/res/template/values/strings.xml.tt +++ b/qr-code/src/main/res/template/values/strings.xml.tt @@ -8,4 +8,8 @@ --> - \ No newline at end of file + %%pix.instructions.noQrCode%% + %%pix.instructions.copyButton%% + %%wechatpay.timetopay%% + %%pix.instructions.copiedMessage%% + From 54b5eb081b6dafb3f3a75b8c752f7d2e0b491a01 Mon Sep 17 00:00:00 2001 From: jreij Date: Wed, 28 Apr 2021 17:26:15 +0200 Subject: [PATCH 44/63] Minor syntax fix --- .../com/adyen/checkout/googlepay/GooglePayComponent.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java index 221306bee3..808f4240e5 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java @@ -87,12 +87,7 @@ private GooglePayParams getGooglePayParams() { final Configuration configuration = ((GenericPaymentMethodDelegate) mPaymentMethodDelegate) .getPaymentMethod() .getConfiguration(); - final String serverGatewayMerchantId; - if (configuration == null) { - serverGatewayMerchantId = null; - } else { - serverGatewayMerchantId = configuration.getGatewayMerchantId(); - } + final String serverGatewayMerchantId = (configuration != null) ? configuration.getGatewayMerchantId() : null; return new GooglePayParams(getConfiguration(), serverGatewayMerchantId); } From 305013443733a8cb0464fc37be9a7415485892e3 Mon Sep 17 00:00:00 2001 From: jreij Date: Fri, 30 Apr 2021 09:41:11 +0200 Subject: [PATCH 45/63] Make configuration non nullable in all components --- .../main/java/com/adyen/checkout/await/AwaitComponent.java | 5 +---- .../main/java/com/adyen/checkout/components/Component.java | 3 +-- .../components/base/ActionComponentProviderImpl.java | 3 +-- .../adyen/checkout/components/base/BaseActionComponent.java | 2 +- .../components/base/lifecycle/ActionComponentViewModel.java | 5 ++--- .../base/lifecycle/ActionComponentViewModelFactory.java | 3 +-- .../dropin/ui/component/CardComponentDialogFragment.kt | 4 +--- .../main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt | 2 -- .../src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt | 5 +---- .../java/com/adyen/checkout/redirect/RedirectComponent.java | 2 +- .../adyen/checkout/wechatpay/WeChatPayActionComponent.java | 2 +- 11 files changed, 11 insertions(+), 25 deletions(-) diff --git a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java index 1d7ba2b8ce..db8ee5e01b 100644 --- a/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java +++ b/await/src/main/java/com/adyen/checkout/await/AwaitComponent.java @@ -80,7 +80,7 @@ public void onChanged(@Nullable ComponentException e) { } }; - public AwaitComponent(@NonNull Application application, @Nullable AwaitConfiguration configuration) { + public AwaitComponent(@NonNull Application application, @NonNull AwaitConfiguration configuration) { super(application, configuration); if (configuration == null) { // This component requires the client key from the configuration to work. @@ -106,9 +106,6 @@ protected List getSupportedPaymentMethodTypes() { @Override protected void handleActionInternal(@NonNull Activity activity, @NonNull Action action) throws ComponentException { final Configuration configuration = getConfiguration(); - if (configuration == null) { - throw new ComponentException("Configuration not found"); - } mPaymentMethodType = action.getPaymentMethodType(); // Notify UI to get the logo. createOutputData(null); diff --git a/components-core/src/main/java/com/adyen/checkout/components/Component.java b/components-core/src/main/java/com/adyen/checkout/components/Component.java index 2b744d160d..2cba00cab5 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/Component.java +++ b/components-core/src/main/java/com/adyen/checkout/components/Component.java @@ -11,7 +11,6 @@ import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.Observer; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import com.adyen.checkout.components.base.Configuration; @@ -44,6 +43,6 @@ public interface Component private String mPaymentData; - public BaseActionComponent(@NonNull Application application, @Nullable ConfigurationT configuration) { + public BaseActionComponent(@NonNull Application application, @NonNull ConfigurationT configuration) { super(application, configuration); } diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/lifecycle/ActionComponentViewModel.java b/components-core/src/main/java/com/adyen/checkout/components/base/lifecycle/ActionComponentViewModel.java index 3988aa63b1..df3ae86a5c 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/base/lifecycle/ActionComponentViewModel.java +++ b/components-core/src/main/java/com/adyen/checkout/components/base/lifecycle/ActionComponentViewModel.java @@ -11,7 +11,6 @@ import android.app.Application; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.lifecycle.AndroidViewModel; import com.adyen.checkout.components.ActionComponent; @@ -28,12 +27,12 @@ public abstract class ActionComponentViewModel configurationClass, - @Nullable Configuration configuration + @NonNull Configuration configuration ) { mApplication = application; mConfigurationClass = configurationClass; diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/component/CardComponentDialogFragment.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/component/CardComponentDialogFragment.kt index f3ac254853..d596c2c345 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/component/CardComponentDialogFragment.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/component/CardComponentDialogFragment.kt @@ -22,7 +22,6 @@ import com.adyen.checkout.components.api.ImageLoader import com.adyen.checkout.components.model.payments.request.PaymentMethodDetails import com.adyen.checkout.components.util.CurrencyUtils import com.adyen.checkout.components.util.PaymentMethodTypes -import com.adyen.checkout.core.api.Environment import com.adyen.checkout.core.exception.CheckoutException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger @@ -98,8 +97,7 @@ class CardComponentDialogFragment : BaseComponentDialogFragment() { cardComponent.configuration.supportedCardTypes } cardListAdapter = CardListAdapter( - // TODO: 11/01/2021 Remove nullability after config is not nullable anymore - ImageLoader.getInstance(requireContext(), component.configuration?.environment ?: Environment.EUROPE), + ImageLoader.getInstance(requireContext(), component.configuration.environment), supportedCards ) binding.recyclerViewCardList.adapter = cardListAdapter diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt index a90763146a..bc5e197285 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeComponent.kt @@ -80,8 +80,6 @@ class QRCodeComponent(application: Application, configuration: QRCodeConfigurati @Throws(ComponentException::class) override fun handleActionInternal(activity: Activity, action: Action) { - val configuration = configuration - ?: throw ComponentException("Configuration not found") if (action !is QrCodeAction) throw ComponentException("Unsupported action") paymentMethodType = action.paymentMethodType qrCodeData = action.qrCodeData diff --git a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt index 834e26c006..187d3bd4f1 100644 --- a/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt +++ b/qr-code/src/main/java/com/adyen/checkout/qrcode/QRCodeView.kt @@ -19,7 +19,6 @@ import com.adyen.checkout.components.api.ImageLoader import com.adyen.checkout.components.extensions.copyTextToClipboard import com.adyen.checkout.components.ui.view.AdyenLinearLayout import com.adyen.checkout.components.util.PaymentMethodTypes -import com.adyen.checkout.core.exception.ComponentException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger import com.adyen.checkout.qrcode.databinding.QrcodeViewBinding @@ -54,9 +53,7 @@ class QRCodeView : AdyenLinearLayout PROVIDER = new ActionComponentProviderImpl<>(RedirectComponent.class, RedirectConfiguration.class); - public RedirectComponent(@NonNull Application application, @Nullable RedirectConfiguration configuration) { + public RedirectComponent(@NonNull Application application, @NonNull RedirectConfiguration configuration) { super(application, configuration); } diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java index 9719a8620b..374c9617b3 100644 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java +++ b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayActionComponent.java @@ -59,7 +59,7 @@ public void onResp(BaseResp baseResp) { } }; - public WeChatPayActionComponent(@NonNull Application application, @Nullable WeChatPayActionConfiguration configuration) { + public WeChatPayActionComponent(@NonNull Application application, @NonNull WeChatPayActionConfiguration configuration) { super(application, configuration); mApi = WXAPIFactory.createWXAPI(application, null, true); } From 2a0eb818a06dc3ae6bbe3bd101a4f09736a409ec Mon Sep 17 00:00:00 2001 From: jreij Date: Fri, 30 Apr 2021 10:22:08 +0200 Subject: [PATCH 46/63] Update release notes --- RELEASE_NOTES.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index d275d72f1b..6690fcc9bf 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -8,15 +8,8 @@ [//]: # ( ### Deprecated) [//]: # ( - Configurations public constructor are deprecated, please use each Configuration's builder to make a Configuration object) -## Added -- Validation of PublicKey in CSE module if it's used standalone. -- 'isReady' flag to ComponentState because some components might require some initialization time even if all the inputs are valid. -- 'isValid' now checks both 'isInputValid' and 'isReady' to be true. - -## Fixed -- Handle Intent results if DropInActivity got destroyed. -- Queue API request if DropInService is not yet bound to DropInActivity - - - - +## Changed +- Updated Material Components dependency to 1.3.0. +- Provided default `GooglePayConfiguration` and `CardConfiguration` in Drop-in. It's not required to manually set these configurations in `DropInConfiguration.Builder` anymore. +- The default Google Pay environment will automatically follow the Adyen environment. It will be initialized as `ENVIRONMENT_TEST` when using Adyen's `TEST` environment, otherwise it will be set to `ENVIRONMENT_PRODUCTION`. +- The `merchantAccount` parameter in `GooglePayConfiguration.Builder` is now optional. You can remove it from the builder constructor, or use `GooglePayConfiguration.Builder.setMerchantAccount` if you need to pass it manually. From aae60df70f635ae45149d311b326c81ca88477dd Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 29 Apr 2021 14:11:18 +0200 Subject: [PATCH 47/63] Rename .java to .kt --- .../checkout/redirect/{RedirectUtil.java => RedirectUtil.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename redirect/src/main/java/com/adyen/checkout/redirect/{RedirectUtil.java => RedirectUtil.kt} (100%) diff --git a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.java b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt similarity index 100% rename from redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.java rename to redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt From 78340285e7e89895f0a35a409fd06148768e6bc0 Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 29 Apr 2021 14:11:18 +0200 Subject: [PATCH 48/63] Refactor RedirectUtil to Kotlin --- .../adyen/checkout/redirect/RedirectUtil.kt | 197 +++++++----------- 1 file changed, 78 insertions(+), 119 deletions(-) diff --git a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt index b94122ee5b..d9c1917916 100644 --- a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt +++ b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt @@ -5,127 +5,92 @@ * * Created by caiof on 1/4/2019. */ - -package com.adyen.checkout.redirect; - -import static com.adyen.checkout.redirect.ResolveResult.Type.APPLICATION; -import static com.adyen.checkout.redirect.ResolveResult.Type.DEFAULT_BROWSER; -import static com.adyen.checkout.redirect.ResolveResult.Type.RESOLVER_ACTIVITY; -import static com.adyen.checkout.redirect.ResolveResult.Type.UNKNOWN; - -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; - -import androidx.annotation.NonNull; -import androidx.browser.customtabs.CustomTabsIntent; - -import com.adyen.checkout.components.ui.util.ThemeUtil; -import com.adyen.checkout.core.code.Lint; -import com.adyen.checkout.core.exception.CheckoutException; -import com.adyen.checkout.core.exception.NoConstructorException; -import com.adyen.checkout.core.log.LogUtil; -import com.adyen.checkout.core.log.Logger; - -import org.json.JSONException; -import org.json.JSONObject; - -public final class RedirectUtil { - private static final String TAG = LogUtil.getTag(); +package com.adyen.checkout.redirect + +import android.content.Context +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import androidx.browser.customtabs.CustomTabsIntent +import com.adyen.checkout.components.ui.util.ThemeUtil +import com.adyen.checkout.core.exception.CheckoutException +import com.adyen.checkout.core.log.LogUtil +import com.adyen.checkout.core.log.Logger +import org.json.JSONException +import org.json.JSONObject + +object RedirectUtil { + private val TAG = LogUtil.getTag() /** * The suggested scheme to be used in the intent filter to receive the redirect result. - * This value should be the beginning of the `returnUr` sent on the payments/ call. + * This value should be the beginning of the `returnUrl` sent on the payments/ call. */ - @NonNull - public static final String REDIRECT_RESULT_SCHEME = BuildConfig.checkoutRedirectScheme + "://"; - - private static final String PAYLOAD_PARAMETER = "payload"; - private static final String REDIRECT_RESULT_PARAMETER = "redirectResult"; - private static final String PAYMENT_RESULT_PARAMETER = "PaRes"; - private static final String MD_PARAMETER = "MD"; - - private static final String RESOLVER_ACTIVITY_PACKAGE_NAME = "android"; - - @NonNull - static ResolveResult determineResolveResult(@NonNull Context context, @NonNull Uri uri) { - final Intent intent = new Intent(Intent.ACTION_VIEW, uri); - final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://")); - - try { - final PackageManager packageManager = context.getPackageManager(); - final ResolveInfo resolveInfo = packageManager.resolveActivity(intent, 0); - final ResolveInfo browserInfo = packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY); - final String resolvedPackageName = resolveInfo != null ? resolveInfo.activityInfo.packageName : null; - final String browserPackageName = browserInfo != null ? browserInfo.activityInfo.packageName : null; - - if (resolvedPackageName != null) { - if (resolvedPackageName.equals(RESOLVER_ACTIVITY_PACKAGE_NAME)) { - return new ResolveResult(RESOLVER_ACTIVITY, resolveInfo); - } else if (resolvedPackageName.equals(browserPackageName)) { - return new ResolveResult(DEFAULT_BROWSER, resolveInfo); - } else { - return new ResolveResult(APPLICATION, resolveInfo); - } + const val REDIRECT_RESULT_SCHEME = BuildConfig.checkoutRedirectScheme + "://" + + private const val PAYLOAD_PARAMETER = "payload" + private const val REDIRECT_RESULT_PARAMETER = "redirectResult" + private const val PAYMENT_RESULT_PARAMETER = "PaRes" + private const val MD_PARAMETER = "MD" + + private const val RESOLVER_ACTIVITY_PACKAGE_NAME = "android" + + @SuppressWarnings("TooGenericExceptionCaught") + private fun determineResolveResult(context: Context, uri: Uri): ResolveResult { + return try { + val intent = Intent(Intent.ACTION_VIEW, uri) + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("http://")) + val packageManager = context.packageManager + val resolveInfo = packageManager.resolveActivity(intent, 0) + val browserInfo = packageManager.resolveActivity(browserIntent, PackageManager.MATCH_DEFAULT_ONLY) + val resolvedPackageName = resolveInfo?.activityInfo?.packageName + val browserPackageName = browserInfo?.activityInfo?.packageName + when (resolvedPackageName) { + RESOLVER_ACTIVITY_PACKAGE_NAME -> ResolveResult(ResolveResult.Type.RESOLVER_ACTIVITY, resolveInfo) + browserPackageName -> ResolveResult(ResolveResult.Type.DEFAULT_BROWSER, resolveInfo) + null -> ResolveResult(ResolveResult.Type.UNKNOWN, null) + else -> ResolveResult(ResolveResult.Type.APPLICATION, resolveInfo) } - } catch (Exception e) { - return new ResolveResult(UNKNOWN, null); + } catch (e: Exception) { + Logger.e(TAG, "determineResolveResult exception", e) + ResolveResult(ResolveResult.Type.UNKNOWN, null) } - - return new ResolveResult(UNKNOWN, null); } /** * A redirect may return to the application using the ReturnUrl when properly setup in an Intent Filter. Is usually contains result information - * as parameters on that returnUrl. This method parses those results and returns a {@link JSONObject} to be used in the details call. - * - *

- * We are not handling the case for returnUrlQueryString detail, merchants who use that custom scenario should parse the URL themselves. + * as parameters on that returnUrl. This method parses those results and returns a [JSONObject] to be used in the details call. * * @param data The returned Uri * @return The parsed value to be passed on the payments/details call, on the details parameter. */ - @NonNull - public static JSONObject parseRedirectResult(@NonNull Uri data) throws CheckoutException { - Logger.d(TAG, "parseRedirectResult - " + data.toString()); - - final JSONObject result = new JSONObject(); - - for (String parameter : data.getQueryParameterNames()) { - // getQueryParameter already does HTML decoding - if (PAYLOAD_PARAMETER.equals(parameter)) { - try { - result.put(PAYLOAD_PARAMETER, data.getQueryParameter(parameter)); - } catch (JSONException e) { - throw new CheckoutException("Error creating Redirect payload.", e); - } - } - if (REDIRECT_RESULT_PARAMETER.equals(parameter)) { - try { - result.put(REDIRECT_RESULT_PARAMETER, data.getQueryParameter(parameter)); - } catch (JSONException e) { - throw new CheckoutException("Error creating Redirect result parameter.", e); - } - } - if (PAYMENT_RESULT_PARAMETER.equals(parameter)) { - try { - result.put(PAYMENT_RESULT_PARAMETER, data.getQueryParameter(parameter)); - } catch (JSONException e) { - throw new CheckoutException("Error creating Redirect payment result.", e); - } - } - if (MD_PARAMETER.equals(parameter)) { - try { - result.put(MD_PARAMETER, data.getQueryParameter(parameter)); - } catch (JSONException e) { - throw new CheckoutException("Error creating Redirect MD.", e); + @JvmStatic + @Throws(CheckoutException::class) + fun parseRedirectResult(data: Uri): JSONObject { + Logger.d(TAG, "parseRedirectResult - $data") + + val extractedParams = HashMap().apply { + data.getQueryParameter(PAYLOAD_PARAMETER)?.let { put(PAYLOAD_PARAMETER, it) } + data.getQueryParameter(REDIRECT_RESULT_PARAMETER)?.let { put(REDIRECT_RESULT_PARAMETER, it) } + data.getQueryParameter(PAYMENT_RESULT_PARAMETER)?.let { paymentResult -> + data.getQueryParameter(MD_PARAMETER)?.let { md -> + put(PAYMENT_RESULT_PARAMETER, paymentResult) + put(MD_PARAMETER, md) } } } - return result; + if (extractedParams.size == 0) { + throw CheckoutException("Error parsing redirect result, could not any query parameters") + } + + try { + return JSONObject().apply { + extractedParams.forEach { put(it.key, it.value) } + } + } catch (e: JSONException) { + throw CheckoutException("Error creating redirect result.", e) + } } /** @@ -134,23 +99,17 @@ public final class RedirectUtil { * @param uri The Uri to redirect to. * @return And intent that targets either another app or a Web page. */ - @SuppressWarnings(Lint.MERCHANT_VISIBLE) - @NonNull - public static Intent createRedirectIntent(@NonNull Context context, @NonNull Uri uri) { - if (RedirectUtil.determineResolveResult(context, uri).getType() == APPLICATION) { - return new Intent(Intent.ACTION_VIEW, uri); + @JvmStatic + fun createRedirectIntent(context: Context, uri: Uri): Intent { + return if (determineResolveResult(context, uri).type == ResolveResult.Type.APPLICATION) { + Intent(Intent.ACTION_VIEW, uri) } else { - final CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder() - .setShowTitle(true) - .setToolbarColor(ThemeUtil.getPrimaryThemeColor(context)) - .build(); - customTabsIntent.intent.setData(uri); - - return customTabsIntent.intent; + val customTabsIntent = CustomTabsIntent.Builder() + .setShowTitle(true) + .setToolbarColor(ThemeUtil.getPrimaryThemeColor(context)) + .build() + customTabsIntent.intent.data = uri + customTabsIntent.intent } } - - private RedirectUtil() { - throw new NoConstructorException(); - } } From df345c2890ed7d118e2b409d48a9ff59b9aa5507 Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 29 Apr 2021 14:12:25 +0200 Subject: [PATCH 49/63] Return query params in returnUrlQueryString --- .../src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt index d9c1917916..b3d123a3c2 100644 --- a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt +++ b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt @@ -32,6 +32,7 @@ object RedirectUtil { private const val REDIRECT_RESULT_PARAMETER = "redirectResult" private const val PAYMENT_RESULT_PARAMETER = "PaRes" private const val MD_PARAMETER = "MD" + private const val QUERY_STRING_RESULT = "returnUrlQueryString" private const val RESOLVER_ACTIVITY_PACKAGE_NAME = "android" @@ -78,6 +79,7 @@ object RedirectUtil { put(MD_PARAMETER, md) } } + data.encodedQuery?.let { put(QUERY_STRING_RESULT, it) } } if (extractedParams.size == 0) { From a106d9c30c9abd1ec05e908b60de9c0268ffdb5d Mon Sep 17 00:00:00 2001 From: jreij Date: Thu, 29 Apr 2021 14:12:44 +0200 Subject: [PATCH 50/63] Add RedirectUtilTest --- redirect/build.gradle | 1 + .../checkout/redirect/RedirectUtilTest.kt | 106 ++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt diff --git a/redirect/build.gradle b/redirect/build.gradle index c75ad36a69..7fa3973bdd 100644 --- a/redirect/build.gradle +++ b/redirect/build.gradle @@ -47,6 +47,7 @@ android { dependencies { //Tests testImplementation "junit:junit:$junit_version" + testImplementation "org.robolectric:robolectric:$robolectric_version" androidTestImplementation "androidx.test.ext:junit:$test_ext_version" androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version" diff --git a/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt b/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt new file mode 100644 index 0000000000..ae2989c460 --- /dev/null +++ b/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by josephj on 22/4/2021. + */ + +package com.adyen.checkout.redirect + +import android.net.Uri +import com.adyen.checkout.core.exception.CheckoutException +import com.google.common.collect.Iterators +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config + +@RunWith(RobolectricTestRunner::class) +@Config(manifest = Config.NONE) +class RedirectUtilTest { + + @Test + fun parseRedirectResult_ExtractPayload_ExpectResponse() { + val uri = Uri.parse("http://www.example.com?p1=value1&payload=YOUR_PAYLOAD&p2=value2") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 2) + assertEquals(response.getString("payload"), "YOUR_PAYLOAD") + assertEquals(response.getString("returnUrlQueryString"), "p1=value1&payload=YOUR_PAYLOAD&p2=value2") + } + + @Test + fun parseRedirectResult_ExtractRedirectResult_ExpectResponse() { + val uri = Uri.parse("url://domain?param1=dfgsd&redirectResult=ZXdxcjQzMnI0Zg%3D%3D¶m2=1464") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 2) + assertEquals(response.getString("redirectResult"), "ZXdxcjQzMnI0Zg==") + assertEquals(response.getString("returnUrlQueryString"), "param1=dfgsd&redirectResult=ZXdxcjQzMnI0Zg%3D%3D¶m2=1464") + } + + @Test + fun parseRedirectResult_ExtractPaResAndMD_ExpectResponse() { + val uri = Uri.parse("https://example.com/actor/board?param=abcfd&PaRes=paymentresult&MD=lorem") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 3) + assertEquals(response.getString("MD"), "lorem") + assertEquals(response.getString("PaRes"), "paymentresult") + assertEquals(response.getString("returnUrlQueryString"), "param=abcfd&PaRes=paymentresult&MD=lorem") + } + + @Test + fun parseRedirectResult_ExtractReturnUrlQueryString_ExpectResponse() { + val uri = Uri.parse("http://www.example.com/attack.aspx?param1=abc&pp=ZXdxcj1zZ/+Cs0Mz+JyNGY=&p2=fdghb") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 1) + assertEquals(response.getString("returnUrlQueryString"), "param1=abc&pp=ZXdxcj1zZ/+Cs0Mz+JyNGY=&p2=fdghb") + } + + @Test + fun parseRedirectResult_PayloadAndPaResWithoutMD_ExpectResponse() { + val uri = Uri.parse("https://www.example.net/airport.htm/?payload=some¶m1=rtgt&PaRes=PA_RES") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 2) + assertEquals(response.getString("payload"), "some") + assertEquals(response.getString("returnUrlQueryString"), "payload=some¶m1=rtgt&PaRes=PA_RES") + } + + @Test + fun parseRedirectResult_PaResWithoutMD_ExpectResponse() { + val uri = Uri.parse("https://www.example.com/balance.php?param1=abc&PaRes=436564") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 1) + assertEquals(response.getString("returnUrlQueryString"), "param1=abc&PaRes=436564") + } + + @Test + fun parseRedirectResult_MDWithoutPaRes_ExpectResponse() { + val uri = Uri.parse("url://?param1=abc&MD=MD23u09") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 1) + assertEquals(response.getString("returnUrlQueryString"), "param1=abc&MD=MD23u09") + } + + @Test + fun parseRedirectResult_NoValidParameters_ExpectResponse() { + val uri = Uri.parse("url://www.example.com/?p1=abc&p2=3") + val response = RedirectUtil.parseRedirectResult(uri) + + assertEquals(Iterators.size(response.keys()), 1) + assertEquals(response.getString("returnUrlQueryString"), "p1=abc&p2=3") + } + + @Test(expected = CheckoutException::class) + fun parseRedirectResult_NoQuery_ExpectException() { + val uri = Uri.parse("http://www.example.com/payment#invoice") + RedirectUtil.parseRedirectResult(uri) + } +} From c8f5cd82be99342ffe72e37050fcde5e04bbf4cb Mon Sep 17 00:00:00 2001 From: jreij Date: Fri, 30 Apr 2021 09:44:46 +0200 Subject: [PATCH 51/63] Update release notes --- RELEASE_NOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6690fcc9bf..45f6837cef 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -8,6 +8,9 @@ [//]: # ( ### Deprecated) [//]: # ( - Configurations public constructor are deprecated, please use each Configuration's builder to make a Configuration object) +## Added +- Return `returnUrlQueryString` from redirect URL for some redirect payment methods like Swish. + ## Changed - Updated Material Components dependency to 1.3.0. - Provided default `GooglePayConfiguration` and `CardConfiguration` in Drop-in. It's not required to manually set these configurations in `DropInConfiguration.Builder` anymore. From 4e030e8ee65bcd9c91c605adbb451ba8c9fc1655 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 4 May 2021 12:47:46 +0200 Subject: [PATCH 52/63] Return returnUrlQueryString only if no other recognizable params exist --- .../java/com/adyen/checkout/redirect/RedirectUtil.kt | 7 +++++-- .../com/adyen/checkout/redirect/RedirectUtilTest.kt | 12 ++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt index b3d123a3c2..e7e9305446 100644 --- a/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt +++ b/redirect/src/main/java/com/adyen/checkout/redirect/RedirectUtil.kt @@ -79,10 +79,13 @@ object RedirectUtil { put(MD_PARAMETER, md) } } - data.encodedQuery?.let { put(QUERY_STRING_RESULT, it) } } - if (extractedParams.size == 0) { + if (extractedParams.isEmpty()) { + data.encodedQuery?.let { extractedParams.put(QUERY_STRING_RESULT, it) } + } + + if (extractedParams.isEmpty()) { throw CheckoutException("Error parsing redirect result, could not any query parameters") } diff --git a/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt b/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt index ae2989c460..b9bdb866f0 100644 --- a/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt +++ b/redirect/src/test/java/com/adyen/checkout/redirect/RedirectUtilTest.kt @@ -26,9 +26,8 @@ class RedirectUtilTest { val uri = Uri.parse("http://www.example.com?p1=value1&payload=YOUR_PAYLOAD&p2=value2") val response = RedirectUtil.parseRedirectResult(uri) - assertEquals(Iterators.size(response.keys()), 2) + assertEquals(Iterators.size(response.keys()), 1) assertEquals(response.getString("payload"), "YOUR_PAYLOAD") - assertEquals(response.getString("returnUrlQueryString"), "p1=value1&payload=YOUR_PAYLOAD&p2=value2") } @Test @@ -36,9 +35,8 @@ class RedirectUtilTest { val uri = Uri.parse("url://domain?param1=dfgsd&redirectResult=ZXdxcjQzMnI0Zg%3D%3D¶m2=1464") val response = RedirectUtil.parseRedirectResult(uri) - assertEquals(Iterators.size(response.keys()), 2) + assertEquals(Iterators.size(response.keys()), 1) assertEquals(response.getString("redirectResult"), "ZXdxcjQzMnI0Zg==") - assertEquals(response.getString("returnUrlQueryString"), "param1=dfgsd&redirectResult=ZXdxcjQzMnI0Zg%3D%3D¶m2=1464") } @Test @@ -46,10 +44,9 @@ class RedirectUtilTest { val uri = Uri.parse("https://example.com/actor/board?param=abcfd&PaRes=paymentresult&MD=lorem") val response = RedirectUtil.parseRedirectResult(uri) - assertEquals(Iterators.size(response.keys()), 3) + assertEquals(Iterators.size(response.keys()), 2) assertEquals(response.getString("MD"), "lorem") assertEquals(response.getString("PaRes"), "paymentresult") - assertEquals(response.getString("returnUrlQueryString"), "param=abcfd&PaRes=paymentresult&MD=lorem") } @Test @@ -66,9 +63,8 @@ class RedirectUtilTest { val uri = Uri.parse("https://www.example.net/airport.htm/?payload=some¶m1=rtgt&PaRes=PA_RES") val response = RedirectUtil.parseRedirectResult(uri) - assertEquals(Iterators.size(response.keys()), 2) + assertEquals(Iterators.size(response.keys()), 1) assertEquals(response.getString("payload"), "some") - assertEquals(response.getString("returnUrlQueryString"), "payload=some¶m1=rtgt&PaRes=PA_RES") } @Test From e1080418d986b66cc2d3a180b7c2071fb94e2c35 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 4 May 2021 16:05:50 +0200 Subject: [PATCH 53/63] Fix TextInputLayout style to show box label color --- ui-core/src/main/res/values/styles.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ui-core/src/main/res/values/styles.xml b/ui-core/src/main/res/values/styles.xml index 42cbecf56f..8f9836e524 100644 --- a/ui-core/src/main/res/values/styles.xml +++ b/ui-core/src/main/res/values/styles.xml @@ -32,13 +32,9 @@ false - - From c00ed8aa3290e5a58f9709216a7c9507a05df06c Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Wed, 12 May 2021 12:48:47 +0200 Subject: [PATCH 54/63] Update 3DS2 SDK to 2.2.2 Update WeChat Pay checksum since it's now on Maven Central. --- build.gradle | 7 ++++--- config/gradle/checksums.gradle | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 4bf9ac0ae1..d15ab79fdc 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ buildscript { repositories { google() - jcenter() + mavenCentral() maven { url "https://plugins.gradle.org/m2/" } } @@ -72,7 +72,7 @@ allprojects { // Adyen Dependencies ext.adyen_cse_version = "1.0.5" - ext.adyen3ds2_version = "2.2.0" + ext.adyen3ds2_version = "2.2.2" // External Dependencies ext.play_services_wallet_version = '18.1.2' @@ -97,7 +97,8 @@ allprojects { repositories { google() - jcenter() + mavenCentral() + jcenter() // Koin is still not migrated } } diff --git a/config/gradle/checksums.gradle b/config/gradle/checksums.gradle index 47cf33bb40..b38bc57787 100644 --- a/config/gradle/checksums.gradle +++ b/config/gradle/checksums.gradle @@ -9,7 +9,7 @@ if (!hasProperty("checksums")) { final checksums = [ // Adyen dependencies - "com.adyen.threeds:adyen-3ds2:2.2.0:42314ec7f7f54b5fd9a77c12e59ae78d:MD5", + "com.adyen.threeds:adyen-3ds2:2.2.2:3cfb727e53792118335d1632f2455870:MD5", // Kotlin "org.jetbrains.kotlin:kotlin-stdlib:1.4.32:3be731bc74b5d1737559299a94b9248f:MD5", @@ -37,7 +37,7 @@ if (!hasProperty("checksums")) { "com.google.android.gms:play-services-wallet:18.1.2:4e75fd00d8ed34fb55620d35f403ccb2:MD5", // WeChatPay - "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.6.4:50848e74e4937bf113ad8a44c44cec80:MD5" + "com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.6.4:8ae40b8665f98587e716b4593401aef2:MD5" ] ext.checksums = checksums From 254104a78a233f9effb4a249bc73d2188173d9f4 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Tue, 18 May 2021 13:13:05 +0200 Subject: [PATCH 55/63] Don't set window FLAG_SECURE in Debug builds to allow for screenshots and recording. --- card/src/main/java/com/adyen/checkout/card/CardView.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/card/src/main/java/com/adyen/checkout/card/CardView.kt b/card/src/main/java/com/adyen/checkout/card/CardView.kt index 0289ed75ad..d1f2471893 100644 --- a/card/src/main/java/com/adyen/checkout/card/CardView.kt +++ b/card/src/main/java/com/adyen/checkout/card/CardView.kt @@ -53,13 +53,17 @@ class CardView @JvmOverloads constructor(context: Context, attrs: AttributeSet? override fun onAttachedToWindow() { super.onAttachedToWindow() - // Prevent taking screenshot and screen on recents. - getActivity(context)?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + if (!BuildConfig.DEBUG) { + // Prevent taking screenshot and screen on recents. + getActivity(context)?.window?.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + } } override fun onDetachedFromWindow() { super.onDetachedFromWindow() - getActivity(context)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) + if (!BuildConfig.DEBUG) { + getActivity(context)?.window?.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) + } } override fun initView() { From 4acfdb041650379617472898c1b2c2582e493a82 Mon Sep 17 00:00:00 2001 From: jreij Date: Mon, 17 May 2021 11:46:26 +0200 Subject: [PATCH 56/63] Create ComponentAvailabilityCheck --- .../checkout/bcmc/BcmcComponentProvider.kt | 11 ------- .../checkout/card/CardComponentProvider.kt | 11 ------- .../components/ComponentAvailabilityCheck.kt | 26 +++++++++++++++ .../components/PaymentComponentProvider.java | 12 ++----- .../base/GenericPaymentComponentProvider.kt | 11 ------- .../GenericStoredPaymentComponentProvider.kt | 11 ------- .../checkout/googlepay/GooglePayProvider.kt | 9 +++-- .../checkout/wechatpay/WeChatPayProvider.kt | 33 +++++++++++++++++++ 8 files changed, 68 insertions(+), 56 deletions(-) create mode 100644 components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt create mode 100644 wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt diff --git a/bcmc/src/main/java/com/adyen/checkout/bcmc/BcmcComponentProvider.kt b/bcmc/src/main/java/com/adyen/checkout/bcmc/BcmcComponentProvider.kt index f7a5b4e30b..243744e8c7 100644 --- a/bcmc/src/main/java/com/adyen/checkout/bcmc/BcmcComponentProvider.kt +++ b/bcmc/src/main/java/com/adyen/checkout/bcmc/BcmcComponentProvider.kt @@ -7,11 +7,9 @@ */ package com.adyen.checkout.bcmc -import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner import com.adyen.checkout.card.repository.PublicKeyRepository -import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.PaymentComponentProvider import com.adyen.checkout.components.base.GenericPaymentMethodDelegate import com.adyen.checkout.components.base.lifecycle.viewModelFactory @@ -33,13 +31,4 @@ class BcmcComponentProvider : PaymentComponentProvider - ) { - callback.onAvailabilityResult(true, paymentMethod, configuration) - } } diff --git a/card/src/main/java/com/adyen/checkout/card/CardComponentProvider.kt b/card/src/main/java/com/adyen/checkout/card/CardComponentProvider.kt index f3c141ca5c..1fe6d0ebdd 100644 --- a/card/src/main/java/com/adyen/checkout/card/CardComponentProvider.kt +++ b/card/src/main/java/com/adyen/checkout/card/CardComponentProvider.kt @@ -7,13 +7,11 @@ */ package com.adyen.checkout.card -import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner import com.adyen.checkout.card.data.CardType import com.adyen.checkout.card.repository.BinLookupRepository import com.adyen.checkout.card.repository.PublicKeyRepository -import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.StoredPaymentComponentProvider import com.adyen.checkout.components.base.lifecycle.viewModelFactory import com.adyen.checkout.components.model.paymentmethods.PaymentMethod @@ -60,15 +58,6 @@ class CardComponentProvider : StoredPaymentComponentProvider - ) { - callback.onAvailabilityResult(true, paymentMethod, configuration) - } - /** * Check which set of supported cards to pass to the component. * Priority is: Custom -> PaymentMethod.brands -> Default diff --git a/components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt b/components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt new file mode 100644 index 0000000000..e45f0d7fa9 --- /dev/null +++ b/components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by josephj on 17/5/2021. + */ +package com.adyen.checkout.components + +import android.app.Application +import com.adyen.checkout.components.base.Configuration +import com.adyen.checkout.components.model.paymentmethods.PaymentMethod + +/** + * Specifies whether a certain component is available for use with the provided parameters. + * + * @param ConfigurationT The Configuration for the Component to be provided. Simply use [Configuration] if not applicable. + */ +interface ComponentAvailabilityCheck { + fun isAvailable( + applicationContext: Application, + paymentMethod: PaymentMethod, + configuration: ConfigurationT?, + callback: ComponentAvailableCallback + ) +} diff --git a/components-core/src/main/java/com/adyen/checkout/components/PaymentComponentProvider.java b/components-core/src/main/java/com/adyen/checkout/components/PaymentComponentProvider.java index 187e8170c6..f9d72399c2 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/PaymentComponentProvider.java +++ b/components-core/src/main/java/com/adyen/checkout/components/PaymentComponentProvider.java @@ -8,8 +8,6 @@ package com.adyen.checkout.components; -import android.app.Application; - import androidx.annotation.NonNull; import androidx.lifecycle.ViewModelStoreOwner; @@ -18,9 +16,9 @@ import com.adyen.checkout.core.exception.CheckoutException; /** - * Provides an instance of te associated Component linked to provided lifecycle and config. + * Provides an instance of the associated Component linked to provided lifecycle and config. * - * @param The Component to be provided + * @param The Component to be provided * @param The Configuration for the Component to be provided */ public interface PaymentComponentProvider @@ -33,10 +31,4 @@ ComponentT get( @NonNull PaymentMethod paymentMethod, @NonNull ConfigurationT configuration ) throws CheckoutException; - - void isAvailable( - @NonNull Application applicationContext, - @NonNull PaymentMethod paymentMethod, - @NonNull ConfigurationT configuration, - @NonNull ComponentAvailableCallback callback); } diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/GenericPaymentComponentProvider.kt b/components-core/src/main/java/com/adyen/checkout/components/base/GenericPaymentComponentProvider.kt index a9f76ff2b5..99c7f9d03a 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/base/GenericPaymentComponentProvider.kt +++ b/components-core/src/main/java/com/adyen/checkout/components/base/GenericPaymentComponentProvider.kt @@ -7,10 +7,8 @@ */ package com.adyen.checkout.components.base -import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner -import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.PaymentComponentProvider import com.adyen.checkout.components.base.lifecycle.viewModelFactory import com.adyen.checkout.components.model.paymentmethods.PaymentMethod @@ -32,13 +30,4 @@ class GenericPaymentComponentProvider - ) { - callback.onAvailabilityResult(true, paymentMethod, config) - } } diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/GenericStoredPaymentComponentProvider.kt b/components-core/src/main/java/com/adyen/checkout/components/base/GenericStoredPaymentComponentProvider.kt index a758a4e0c8..c277d0d08f 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/base/GenericStoredPaymentComponentProvider.kt +++ b/components-core/src/main/java/com/adyen/checkout/components/base/GenericStoredPaymentComponentProvider.kt @@ -8,10 +8,8 @@ package com.adyen.checkout.components.base -import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner -import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.StoredPaymentComponentProvider import com.adyen.checkout.components.base.lifecycle.viewModelFactory import com.adyen.checkout.components.model.paymentmethods.PaymentMethod @@ -49,13 +47,4 @@ class GenericStoredPaymentComponentProvider< } return ViewModelProvider(viewModelStoreOwner, genericFactory)[componentClass] } - - override fun isAvailable( - applicationContext: Application, - paymentMethod: PaymentMethod, - configuration: ConfigurationT, - callback: ComponentAvailableCallback - ) { - callback.onAvailabilityResult(true, paymentMethod, configuration) - } } diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt index cddac72aee..8c89aa06d3 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt @@ -10,11 +10,13 @@ package com.adyen.checkout.googlepay import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner +import com.adyen.checkout.components.ComponentAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.PaymentComponentProvider import com.adyen.checkout.components.base.GenericPaymentMethodDelegate import com.adyen.checkout.components.base.lifecycle.viewModelFactory import com.adyen.checkout.components.model.paymentmethods.PaymentMethod +import com.adyen.checkout.core.exception.CheckoutException import com.adyen.checkout.googlepay.model.GooglePayParams import com.adyen.checkout.googlepay.util.GooglePayUtils import com.google.android.gms.common.ConnectionResult @@ -25,7 +27,7 @@ import com.google.android.gms.wallet.PaymentsClient import com.google.android.gms.wallet.Wallet import java.lang.ref.WeakReference -class GooglePayProvider : PaymentComponentProvider { +class GooglePayProvider : PaymentComponentProvider, ComponentAvailabilityCheck { override operator fun get( viewModelStoreOwner: ViewModelStoreOwner, paymentMethod: PaymentMethod, @@ -38,9 +40,12 @@ class GooglePayProvider : PaymentComponentProvider ) { + if (configuration == null) { + throw CheckoutException("GooglePayConfiguration cannot be null") + } if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(applicationContext) != ConnectionResult.SUCCESS) { callback.onAvailabilityResult(false, paymentMethod, configuration) return diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt new file mode 100644 index 0000000000..d559b9d950 --- /dev/null +++ b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by josephj on 17/5/2021. + */ + +package com.adyen.checkout.wechatpay + +import android.app.Application +import com.adyen.checkout.components.ComponentAvailabilityCheck +import com.adyen.checkout.components.ComponentAvailableCallback +import com.adyen.checkout.components.base.Configuration +import com.adyen.checkout.components.model.paymentmethods.PaymentMethod + +/** + * This class is not an actual provider, it only checks whether WeChatPay is available. + * There is no viewable Payment Component for WeChatPay, only an Action Component. + * You can directly call /payments after you receive a callback from [isAvailable]. + * You can use [WeChatPayActionComponent] to handle the returned action. + */ +class WeChatPayProvider : ComponentAvailabilityCheck { + + override fun isAvailable( + applicationContext: Application, + paymentMethod: PaymentMethod, + configuration: Configuration?, + callback: ComponentAvailableCallback + ) { + callback.onAvailabilityResult(WeChatPayUtils.isAvailable(applicationContext), paymentMethod, configuration) + } +} From c808cf440a9460f945532d2db22be6560142871b Mon Sep 17 00:00:00 2001 From: jreij Date: Mon, 17 May 2021 11:47:08 +0200 Subject: [PATCH 57/63] Fix availability check logic in drop in --- .../dropin/ComponentParsingProvider.kt | 43 ++++++++----------- .../checkout/dropin/DropInConfiguration.kt | 8 ++++ .../PaymentMethodsListViewModel.kt | 3 +- .../googlepay/GooglePayComponent.java | 3 +- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index d5c8f04f81..bac43751db 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -23,6 +23,7 @@ import com.adyen.checkout.blik.BlikView import com.adyen.checkout.card.CardComponent import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.card.CardView +import com.adyen.checkout.components.ComponentAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.ComponentView import com.adyen.checkout.components.PaymentComponent @@ -51,6 +52,7 @@ import com.adyen.checkout.eps.EPSConfiguration import com.adyen.checkout.eps.EPSRecyclerView import com.adyen.checkout.googlepay.GooglePayComponent import com.adyen.checkout.googlepay.GooglePayConfiguration +import com.adyen.checkout.googlepay.GooglePayProvider import com.adyen.checkout.ideal.IdealComponent import com.adyen.checkout.ideal.IdealConfiguration import com.adyen.checkout.ideal.IdealRecyclerView @@ -70,6 +72,7 @@ import com.adyen.checkout.sepa.SepaComponent import com.adyen.checkout.sepa.SepaConfiguration import com.adyen.checkout.sepa.SepaView import com.adyen.checkout.wechatpay.WeChatPayActionConfiguration +import com.adyen.checkout.wechatpay.WeChatPayProvider object ComponentParsingProvider { val TAG = LogUtil.getTag() @@ -143,38 +146,30 @@ internal fun checkComponentAvailability( val type = paymentMethod.type ?: throw CheckoutException("PaymentMethod type is null") - val provider = getProviderForType(type) - val configuration = dropInConfiguration.getConfigurationForPaymentMethod(type, application) + val availabilityCheck = getComponentAvailabilityCheckForType(type) + if (availabilityCheck == null) { + callback.onAvailabilityResult(true, paymentMethod, null) + return + } + val configuration = dropInConfiguration.getConfigurationForPaymentMethodOrNull(type, application) - provider.isAvailable(application, paymentMethod, configuration, callback) + availabilityCheck.isAvailable(application, paymentMethod, configuration, callback) } catch (e: CheckoutException) { Logger.e(ComponentParsingProvider.TAG, "Unable to initiate ${paymentMethod.type}", e) callback.onAvailabilityResult(false, paymentMethod, null) } } -@Suppress("ComplexMethod") -internal fun getProviderForType(type: String): PaymentComponentProvider, Configuration> { +/** + * Provides the [ComponentAvailabilityCheck] class for the specified [paymentMethodType], if available. + */ +internal fun getComponentAvailabilityCheckForType(paymentMethodType: String): ComponentAvailabilityCheck? { @Suppress("UNCHECKED_CAST") - return when (type) { - PaymentMethodTypes.BCMC -> BcmcComponent.PROVIDER - PaymentMethodTypes.BLIK -> BlikComponent.PROVIDER - PaymentMethodTypes.DOTPAY -> DotpayComponent.PROVIDER - PaymentMethodTypes.ENTERCASH -> EntercashComponent.PROVIDER - PaymentMethodTypes.EPS -> EPSComponent.PROVIDER - PaymentMethodTypes.GOOGLE_PAY -> GooglePayComponent.PROVIDER - PaymentMethodTypes.IDEAL -> IdealComponent.PROVIDER - PaymentMethodTypes.MB_WAY -> MBWayComponent.PROVIDER - PaymentMethodTypes.MOLPAY_THAILAND, - PaymentMethodTypes.MOLPAY_MALAYSIA, - PaymentMethodTypes.MOLPAY_VIETNAM -> MolpayComponent.PROVIDER - PaymentMethodTypes.OPEN_BANKING -> OpenBankingComponent.PROVIDER - PaymentMethodTypes.SCHEME -> CardComponent.PROVIDER - PaymentMethodTypes.SEPA -> SepaComponent.PROVIDER - else -> { - throw CheckoutException("Unable to find component for type - $type") - } - } as PaymentComponentProvider, Configuration> + return when (paymentMethodType) { + PaymentMethodTypes.GOOGLE_PAY -> GooglePayProvider() + PaymentMethodTypes.WECHAT_PAY_SDK -> WeChatPayProvider() + else -> null + } as ComponentAvailabilityCheck? } /** diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt index 89346872fb..2b32f34070 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/DropInConfiguration.kt @@ -103,6 +103,14 @@ class DropInConfiguration : Configuration, Parcelable { return ParcelUtils.NO_FILE_DESCRIPTOR } + internal fun getConfigurationForPaymentMethodOrNull(paymentMethod: String, context: Context): T? { + return try { + getConfigurationForPaymentMethod(paymentMethod, context) + } catch (e: CheckoutException) { + null + } + } + internal fun getConfigurationForPaymentMethod(paymentMethod: String, context: Context): T { return if (availablePaymentConfigs.containsKey(paymentMethod)) { @Suppress("UNCHECKED_CAST") diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt index 0d6df4aa27..0ad5d954fa 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt @@ -84,8 +84,7 @@ class PaymentMethodsListViewModel( type == null -> { throw CheckoutException("PaymentMethod type is null") } - PaymentMethodTypes.SUPPORTED_PAYMENT_METHODS.contains(type) - && !PaymentMethodTypes.SUPPORTED_ACTION_ONLY_PAYMENT_METHODS.contains(type) -> { + PaymentMethodTypes.SUPPORTED_PAYMENT_METHODS.contains(type) -> { Logger.v(TAG, "Supported payment method: $type") // We assume payment method is available and remove it later when the callback comes // this is the overwhelming majority of cases, and we keep the list ordered this way. diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java index 808f4240e5..54efbc4beb 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayComponent.java @@ -14,7 +14,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.adyen.checkout.components.PaymentComponentProvider; import com.adyen.checkout.components.base.BasePaymentComponent; import com.adyen.checkout.components.base.GenericPaymentMethodDelegate; import com.adyen.checkout.components.model.paymentmethods.Configuration; @@ -37,7 +36,7 @@ public class GooglePayComponent extends BasePaymentComponent { private static final String TAG = LogUtil.getTag(); - public static final PaymentComponentProvider PROVIDER = new GooglePayProvider(); + public static final GooglePayProvider PROVIDER = new GooglePayProvider(); private static final String[] PAYMENT_METHOD_TYPES = {PaymentMethodTypes.GOOGLE_PAY}; From 88ac8e9b12ea2058378bbdff086018a9f6b29bee Mon Sep 17 00:00:00 2001 From: jreij Date: Mon, 17 May 2021 11:47:18 +0200 Subject: [PATCH 58/63] Removed unused classes --- .../checkout/components/base/EmptyInputData.java | 12 ------------ .../components/base/EmptyOutputData.java | 16 ---------------- 2 files changed, 28 deletions(-) delete mode 100644 components-core/src/main/java/com/adyen/checkout/components/base/EmptyInputData.java delete mode 100644 components-core/src/main/java/com/adyen/checkout/components/base/EmptyOutputData.java diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/EmptyInputData.java b/components-core/src/main/java/com/adyen/checkout/components/base/EmptyInputData.java deleted file mode 100644 index 000265b408..0000000000 --- a/components-core/src/main/java/com/adyen/checkout/components/base/EmptyInputData.java +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2019 Adyen N.V. - * - * This file is open source and available under the MIT license. See the LICENSE file for more info. - * - * Created by caiof on 15/10/2019. - */ - -package com.adyen.checkout.components.base; - -public final class EmptyInputData implements InputData { -} diff --git a/components-core/src/main/java/com/adyen/checkout/components/base/EmptyOutputData.java b/components-core/src/main/java/com/adyen/checkout/components/base/EmptyOutputData.java deleted file mode 100644 index 2d79156c11..0000000000 --- a/components-core/src/main/java/com/adyen/checkout/components/base/EmptyOutputData.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2019 Adyen N.V. - * - * This file is open source and available under the MIT license. See the LICENSE file for more info. - * - * Created by caiof on 15/10/2019. - */ - -package com.adyen.checkout.components.base; - -public final class EmptyOutputData implements OutputData { - @Override - public boolean isValid() { - return true; - } -} From 5e87a6398bd9ac33de31b7f939809dddf8046c3b Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 18 May 2021 14:00:43 +0200 Subject: [PATCH 59/63] Replace Component naming with PaymentMethod as not all payment methods have components --- ...ityCheck.kt => PaymentMethodAvailabilityCheck.kt} | 6 +++--- .../checkout/dropin/ComponentParsingProvider.kt | 12 ++++++------ .../ui/paymentmethods/PaymentMethodsListViewModel.kt | 4 ++-- .../adyen/checkout/googlepay/GooglePayProvider.kt | 4 ++-- .../adyen/checkout/wechatpay/WeChatPayProvider.kt | 4 ++-- 5 files changed, 15 insertions(+), 15 deletions(-) rename components-core/src/main/java/com/adyen/checkout/components/{ComponentAvailabilityCheck.kt => PaymentMethodAvailabilityCheck.kt} (65%) diff --git a/components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt b/components-core/src/main/java/com/adyen/checkout/components/PaymentMethodAvailabilityCheck.kt similarity index 65% rename from components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt rename to components-core/src/main/java/com/adyen/checkout/components/PaymentMethodAvailabilityCheck.kt index e45f0d7fa9..5ef0982049 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/ComponentAvailabilityCheck.kt +++ b/components-core/src/main/java/com/adyen/checkout/components/PaymentMethodAvailabilityCheck.kt @@ -12,11 +12,11 @@ import com.adyen.checkout.components.base.Configuration import com.adyen.checkout.components.model.paymentmethods.PaymentMethod /** - * Specifies whether a certain component is available for use with the provided parameters. + * Specifies whether a certain payment method is available for use with the provided parameters. * - * @param ConfigurationT The Configuration for the Component to be provided. Simply use [Configuration] if not applicable. + * @param ConfigurationT The Configuration for the Component corresponding to this payment method. Simply use [Configuration] if not applicable. */ -interface ComponentAvailabilityCheck { +interface PaymentMethodAvailabilityCheck { fun isAvailable( applicationContext: Application, paymentMethod: PaymentMethod, diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index bac43751db..30af9c2dba 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -23,7 +23,7 @@ import com.adyen.checkout.blik.BlikView import com.adyen.checkout.card.CardComponent import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.card.CardView -import com.adyen.checkout.components.ComponentAvailabilityCheck +import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.ComponentView import com.adyen.checkout.components.PaymentComponent @@ -135,7 +135,7 @@ internal inline fun getDefaultConfigForAction( return builder.build() as T } -internal fun checkComponentAvailability( +internal fun checkPaymentMethodAvailability( application: Application, paymentMethod: PaymentMethod, dropInConfiguration: DropInConfiguration, @@ -146,7 +146,7 @@ internal fun checkComponentAvailability( val type = paymentMethod.type ?: throw CheckoutException("PaymentMethod type is null") - val availabilityCheck = getComponentAvailabilityCheckForType(type) + val availabilityCheck = getPaymentMethodAvailabilityCheck(type) if (availabilityCheck == null) { callback.onAvailabilityResult(true, paymentMethod, null) return @@ -161,15 +161,15 @@ internal fun checkComponentAvailability( } /** - * Provides the [ComponentAvailabilityCheck] class for the specified [paymentMethodType], if available. + * Provides the [PaymentMethodAvailabilityCheck] class for the specified [paymentMethodType], if available. */ -internal fun getComponentAvailabilityCheckForType(paymentMethodType: String): ComponentAvailabilityCheck? { +internal fun getPaymentMethodAvailabilityCheck(paymentMethodType: String): PaymentMethodAvailabilityCheck? { @Suppress("UNCHECKED_CAST") return when (paymentMethodType) { PaymentMethodTypes.GOOGLE_PAY -> GooglePayProvider() PaymentMethodTypes.WECHAT_PAY_SDK -> WeChatPayProvider() else -> null - } as ComponentAvailabilityCheck? + } as PaymentMethodAvailabilityCheck? } /** diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt index 0ad5d954fa..b24dad8a0b 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ui/paymentmethods/PaymentMethodsListViewModel.kt @@ -21,7 +21,7 @@ import com.adyen.checkout.core.exception.CheckoutException import com.adyen.checkout.core.log.LogUtil import com.adyen.checkout.core.log.Logger import com.adyen.checkout.dropin.DropInConfiguration -import com.adyen.checkout.dropin.checkComponentAvailability +import com.adyen.checkout.dropin.checkPaymentMethodAvailability import com.adyen.checkout.dropin.ui.stored.makeStoredModel class PaymentMethodsListViewModel( @@ -91,7 +91,7 @@ class PaymentMethodsListViewModel( paymentMethodsList.add( PaymentMethodModel(type, paymentMethod.name.orEmpty()) ) - checkComponentAvailability(getApplication(), paymentMethod, dropInConfiguration, this) + checkPaymentMethodAvailability(getApplication(), paymentMethod, dropInConfiguration, this) } else -> { availabilitySkipSum++ diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt index 8c89aa06d3..28bb6825bf 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt @@ -10,7 +10,7 @@ package com.adyen.checkout.googlepay import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner -import com.adyen.checkout.components.ComponentAvailabilityCheck +import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.PaymentComponentProvider import com.adyen.checkout.components.base.GenericPaymentMethodDelegate @@ -27,7 +27,7 @@ import com.google.android.gms.wallet.PaymentsClient import com.google.android.gms.wallet.Wallet import java.lang.ref.WeakReference -class GooglePayProvider : PaymentComponentProvider, ComponentAvailabilityCheck { +class GooglePayProvider : PaymentComponentProvider, PaymentMethodAvailabilityCheck { override operator fun get( viewModelStoreOwner: ViewModelStoreOwner, paymentMethod: PaymentMethod, diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt index d559b9d950..27c16fcc79 100644 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt +++ b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt @@ -9,7 +9,7 @@ package com.adyen.checkout.wechatpay import android.app.Application -import com.adyen.checkout.components.ComponentAvailabilityCheck +import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.base.Configuration import com.adyen.checkout.components.model.paymentmethods.PaymentMethod @@ -20,7 +20,7 @@ import com.adyen.checkout.components.model.paymentmethods.PaymentMethod * You can directly call /payments after you receive a callback from [isAvailable]. * You can use [WeChatPayActionComponent] to handle the returned action. */ -class WeChatPayProvider : ComponentAvailabilityCheck { +class WeChatPayProvider : PaymentMethodAvailabilityCheck { override fun isAvailable( applicationContext: Application, From 119a332a036289f05e48aa8a89c2f3ed60d88249 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 18 May 2021 14:03:23 +0200 Subject: [PATCH 60/63] Replace null PaymentMethodAvailabilityCheck with AlwaysAvailablePaymentMethod --- .../AlwaysAvailablePaymentMethod.kt | 25 +++++++++++++++++++ .../dropin/ComponentParsingProvider.kt | 11 +++----- 2 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 components-core/src/main/java/com/adyen/checkout/components/AlwaysAvailablePaymentMethod.kt diff --git a/components-core/src/main/java/com/adyen/checkout/components/AlwaysAvailablePaymentMethod.kt b/components-core/src/main/java/com/adyen/checkout/components/AlwaysAvailablePaymentMethod.kt new file mode 100644 index 0000000000..bf5b06b75a --- /dev/null +++ b/components-core/src/main/java/com/adyen/checkout/components/AlwaysAvailablePaymentMethod.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Adyen N.V. + * + * This file is open source and available under the MIT license. See the LICENSE file for more info. + * + * Created by josephj on 18/5/2021. + */ + +package com.adyen.checkout.components + +import android.app.Application +import com.adyen.checkout.components.base.Configuration +import com.adyen.checkout.components.model.paymentmethods.PaymentMethod + +class AlwaysAvailablePaymentMethod : PaymentMethodAvailabilityCheck { + + override fun isAvailable( + applicationContext: Application, + paymentMethod: PaymentMethod, + configuration: Configuration?, + callback: ComponentAvailableCallback + ) { + callback.onAvailabilityResult(true, paymentMethod, configuration) + } +} diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index 30af9c2dba..6fddf5318f 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -23,6 +23,7 @@ import com.adyen.checkout.blik.BlikView import com.adyen.checkout.card.CardComponent import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.card.CardView +import com.adyen.checkout.components.AlwaysAvailablePaymentMethod import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.ComponentView @@ -147,10 +148,6 @@ internal fun checkPaymentMethodAvailability( val type = paymentMethod.type ?: throw CheckoutException("PaymentMethod type is null") val availabilityCheck = getPaymentMethodAvailabilityCheck(type) - if (availabilityCheck == null) { - callback.onAvailabilityResult(true, paymentMethod, null) - return - } val configuration = dropInConfiguration.getConfigurationForPaymentMethodOrNull(type, application) availabilityCheck.isAvailable(application, paymentMethod, configuration, callback) @@ -163,13 +160,13 @@ internal fun checkPaymentMethodAvailability( /** * Provides the [PaymentMethodAvailabilityCheck] class for the specified [paymentMethodType], if available. */ -internal fun getPaymentMethodAvailabilityCheck(paymentMethodType: String): PaymentMethodAvailabilityCheck? { +internal fun getPaymentMethodAvailabilityCheck(paymentMethodType: String): PaymentMethodAvailabilityCheck { @Suppress("UNCHECKED_CAST") return when (paymentMethodType) { PaymentMethodTypes.GOOGLE_PAY -> GooglePayProvider() PaymentMethodTypes.WECHAT_PAY_SDK -> WeChatPayProvider() - else -> null - } as PaymentMethodAvailabilityCheck? + else -> AlwaysAvailablePaymentMethod() + } as PaymentMethodAvailabilityCheck } /** From 077b3b9ee83a2854ba4228e4a2a74fcd1b6d5d81 Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 18 May 2021 15:24:16 +0200 Subject: [PATCH 61/63] Code checks --- .../com/adyen/checkout/dropin/ComponentParsingProvider.kt | 2 +- .../java/com/adyen/checkout/googlepay/GooglePayProvider.kt | 6 ++++-- .../java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt index 6fddf5318f..8f7ece6282 100644 --- a/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt +++ b/drop-in/src/main/java/com/adyen/checkout/dropin/ComponentParsingProvider.kt @@ -24,12 +24,12 @@ import com.adyen.checkout.card.CardComponent import com.adyen.checkout.card.CardConfiguration import com.adyen.checkout.card.CardView import com.adyen.checkout.components.AlwaysAvailablePaymentMethod -import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.ComponentView import com.adyen.checkout.components.PaymentComponent import com.adyen.checkout.components.PaymentComponentProvider import com.adyen.checkout.components.PaymentComponentState +import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ViewableComponent import com.adyen.checkout.components.base.BaseConfigurationBuilder import com.adyen.checkout.components.base.Configuration diff --git a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt index 28bb6825bf..aae7e050f7 100644 --- a/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt +++ b/googlepay/src/main/java/com/adyen/checkout/googlepay/GooglePayProvider.kt @@ -10,9 +10,9 @@ package com.adyen.checkout.googlepay import android.app.Application import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelStoreOwner -import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback import com.adyen.checkout.components.PaymentComponentProvider +import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.base.GenericPaymentMethodDelegate import com.adyen.checkout.components.base.lifecycle.viewModelFactory import com.adyen.checkout.components.model.paymentmethods.PaymentMethod @@ -27,7 +27,9 @@ import com.google.android.gms.wallet.PaymentsClient import com.google.android.gms.wallet.Wallet import java.lang.ref.WeakReference -class GooglePayProvider : PaymentComponentProvider, PaymentMethodAvailabilityCheck { +class GooglePayProvider : + PaymentComponentProvider, + PaymentMethodAvailabilityCheck { override operator fun get( viewModelStoreOwner: ViewModelStoreOwner, paymentMethod: PaymentMethod, diff --git a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt index 27c16fcc79..645077ad44 100644 --- a/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt +++ b/wechatpay/src/main/java/com/adyen/checkout/wechatpay/WeChatPayProvider.kt @@ -9,8 +9,8 @@ package com.adyen.checkout.wechatpay import android.app.Application -import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.ComponentAvailableCallback +import com.adyen.checkout.components.PaymentMethodAvailabilityCheck import com.adyen.checkout.components.base.Configuration import com.adyen.checkout.components.model.paymentmethods.PaymentMethod From 000fe0d1b6b05b9cf6bf99e8440aec9748ed74d5 Mon Sep 17 00:00:00 2001 From: Caio Faustino Date: Wed, 12 May 2021 14:37:04 +0200 Subject: [PATCH 62/63] Release 4.0.0-beta03 --- RELEASE_NOTES.md | 23 ++++++++++++++++++----- build.gradle | 2 +- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 45f6837cef..eb72af874b 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,18 +1,31 @@ [//]: # (This file will be used for the release notes on GitHub when publishing.) [//]: # (Types of changes: `Added` `Changed` `Deprecated` `Removed` `Fixed` `Security`) [//]: # (Example:) -[//]: # (### Added) +[//]: # (## Added) [//]: # ( - New payment method) -[//]: # ( ### Changed) +[//]: # (## Changed) [//]: # ( - DropIn service's package changed from `com.adyen.dropin` to `com.adyen.dropin.services`) -[//]: # ( ### Deprecated) +[//]: # ( # Deprecated) [//]: # ( - Configurations public constructor are deprecated, please use each Configuration's builder to make a Configuration object) ## Added -- Return `returnUrlQueryString` from redirect URL for some redirect payment methods like Swish. +- Support for Pix payment method. +- `QRCodeComponent` to handle action type `qrCode` from payment method `pix`. + - Support for other payment methods with a qrCode action will be added in the future. +- Support for returning `returnUrlQueryString` from redirect URL for some redirect payment methods like Swish. ## Changed -- Updated Material Components dependency to 1.3.0. +- New releases are now published to [Maven Central](https://repo1.maven.org/maven2/com/adyen/checkout/) +- A `Configuration` object is now required when initializing any component. Action Components did not require it previously. - Provided default `GooglePayConfiguration` and `CardConfiguration` in Drop-in. It's not required to manually set these configurations in `DropInConfiguration.Builder` anymore. - The default Google Pay environment will automatically follow the Adyen environment. It will be initialized as `ENVIRONMENT_TEST` when using Adyen's `TEST` environment, otherwise it will be set to `ENVIRONMENT_PRODUCTION`. - The `merchantAccount` parameter in `GooglePayConfiguration.Builder` is now optional. You can remove it from the builder constructor, or use `GooglePayConfiguration.Builder.setMerchantAccount` if you need to pass it manually. +- Updated 3DS2 SDK to version 2.2.2 +- Updated Material Components dependency to 1.3.0. + +## Fixed +- Passing `threeDSRequestorAppURL` to the SDK in the 3DS2 Component only when protocol version is 2.2.0 or higher since this is not expected in 2.1.0 +- Style in TextInputLayout where in some scenarios text color would be too light and hard to see. + +## Removed +- `WeChatPayComponent` since it didn't have any function. Instead you can simply check if the App is available by calling: `WeChatPayUtils.isAvailable(applicationContext)` \ No newline at end of file diff --git a/build.gradle b/build.gradle index d15ab79fdc..7f9e7ef830 100644 --- a/build.gradle +++ b/build.gradle @@ -43,7 +43,7 @@ allprojects { // just for example app, don't need to increment ext.version_code = 1 // The version_name format is "major.minor.patch(-(alpha|beta|rc)[0-9]{2}){0,1}" (e.g. 3.0.0, 3.1.1-alpha04 or 3.1.4-rc01 etc). - ext.version_name = "4.0.0-beta02" + ext.version_name = "4.0.0-beta03" // Code quality ext.ktlint_version = '0.40.0' From baef2f1434e9529b0a7440e72b0994bd5c34c05c Mon Sep 17 00:00:00 2001 From: jreij Date: Tue, 18 May 2021 17:12:44 +0200 Subject: [PATCH 63/63] Update release notes --- RELEASE_NOTES.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index eb72af874b..3470bb0cbe 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -22,10 +22,12 @@ - The `merchantAccount` parameter in `GooglePayConfiguration.Builder` is now optional. You can remove it from the builder constructor, or use `GooglePayConfiguration.Builder.setMerchantAccount` if you need to pass it manually. - Updated 3DS2 SDK to version 2.2.2 - Updated Material Components dependency to 1.3.0. +- Screenshots are now allowed in Debug builds, when the Card component is displayed. ## Fixed - Passing `threeDSRequestorAppURL` to the SDK in the 3DS2 Component only when protocol version is 2.2.0 or higher since this is not expected in 2.1.0 - Style in TextInputLayout where in some scenarios text color would be too light and hard to see. ## Removed -- `WeChatPayComponent` since it didn't have any function. Instead you can simply check if the App is available by calling: `WeChatPayUtils.isAvailable(applicationContext)` \ No newline at end of file +- `WeChatPayComponent` since it didn't have any function. Instead you can simply check if the App is available by calling: `WeChatPayProvider.isAvailable`. +- `PaymentComponentProvider.isAvailable` since most payment methods are always available. Replaced it with `PaymentMethodAvailabilityCheck`, only implemented for methods that need to check for availability. \ No newline at end of file