Skip to content

Commit

Permalink
Merge pull request #36 from Adyen/feature/storedPaymentMethods
Browse files Browse the repository at this point in the history
Feature/stored payment methods
  • Loading branch information
Robert-SD authored Sep 29, 2023
2 parents dd65047 + b581237 commit 54a737e
Show file tree
Hide file tree
Showing 37 changed files with 939 additions and 279 deletions.
2 changes: 1 addition & 1 deletion android/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
package="com.adyen.adyen_checkout">

<application>
<service android:name=".dropInSession.SessionDropInService" />
<service android:name=".dropInAdvancedFlow.AdvancedFlowDropInService" />

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,14 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {
}
)
}
checkoutFlutterApi?.onDropInSessionResult(mappedResult) {}

val platformCommunicationModel = PlatformCommunicationModel(
PlatformCommunicationType.RESULT,
data = "",
paymentResult = mappedResult
)

checkoutFlutterApi?.onDropInSessionPlatformCommunication(platformCommunicationModel) {}
}

private val dropInAdvancedFlowCallback = DropInCallback { dropInAdvancedFlowResult ->
Expand All @@ -133,12 +140,12 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {
)
}

val model = PlatformCommunicationModel(
val platformCommunicationModel = PlatformCommunicationModel(
PlatformCommunicationType.RESULT,
data = "",
paymentResult = mappedResult
)
checkoutFlutterApi?.onDropInAdvancedFlowPlatformCommunication(model) {}
checkoutFlutterApi?.onDropInAdvancedFlowPlatformCommunication(platformCommunicationModel) {}
}

private fun teardown() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.adyen.adyen_checkout

import CheckoutFlutterApi
import CheckoutPlatformInterface
import DeletedStoredPaymentMethodResultDTO
import DropInConfigurationDTO
import DropInResultDTO
import DropInResultType
Expand All @@ -14,8 +15,12 @@ import androidx.lifecycle.lifecycleScope
import com.adyen.adyen_checkout.dropInAdvancedFlow.AdvancedFlowDropInService
import com.adyen.adyen_checkout.dropInAdvancedFlow.DropInAdditionalDetailsPlatformMessenger
import com.adyen.adyen_checkout.dropInAdvancedFlow.DropInAdditionalDetailsResultMessenger
import com.adyen.adyen_checkout.dropInAdvancedFlow.DropInPaymentMethodDeletionPlatformMessenger
import com.adyen.adyen_checkout.dropInAdvancedFlow.DropInPaymentMethodDeletionResultMessenger
import com.adyen.adyen_checkout.dropInAdvancedFlow.DropInPaymentResultMessenger
import com.adyen.adyen_checkout.dropInAdvancedFlow.DropInServiceResultMessenger
import com.adyen.adyen_checkout.dropInSession.SessionDropInService
import com.adyen.adyen_checkout.models.DropInFlowType
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToDropInConfiguration
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToSession
import com.adyen.adyen_checkout.utils.Constants.Companion.WRONG_FLUTTER_ACTIVITY_USAGE_ERROR_MESSAGE
Expand Down Expand Up @@ -53,6 +58,7 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
session: SessionDTO,
) {
checkForFlutterFragmentActivity()
setStoredPaymentMethodDeletionObserver()
activity.lifecycleScope.launch(Dispatchers.IO) {
val sessionModel = session.mapToSession()
val dropInConfiguration =
Expand All @@ -64,6 +70,7 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
dropInSessionLauncher,
checkoutSession,
dropInConfiguration,
SessionDropInService::class.java
)
}
}
Expand All @@ -75,6 +82,7 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
) {
checkForFlutterFragmentActivity()
setAdvancedFlowDropInServiceObserver()
setStoredPaymentMethodDeletionObserver()
activity.lifecycleScope.launch(Dispatchers.IO) {
val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(
JSONObject(paymentMethodsResponse),
Expand Down Expand Up @@ -107,6 +115,13 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
DropInAdditionalDetailsResultMessenger.sendResult(paymentsDetailsResult)
}

override fun onDeleteStoredPaymentMethodResult(
deleteStoredPaymentMethodResultDTO:
DeletedStoredPaymentMethodResultDTO
) {
DropInPaymentMethodDeletionResultMessenger.sendResult(deleteStoredPaymentMethodResultDTO)
}

private suspend fun createCheckoutSession(
sessionModel: com.adyen.checkout.sessions.core.SessionModel,
dropInConfiguration: com.adyen.checkout.dropin.DropInConfiguration,
Expand Down Expand Up @@ -134,18 +149,46 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
}
}

private fun setStoredPaymentMethodDeletionObserver() {
DropInPaymentMethodDeletionPlatformMessenger.instance().removeObservers(activity)
DropInPaymentMethodDeletionPlatformMessenger.instance().observe(activity) { message ->
if (message.hasBeenHandled()) {
return@observe
}

val dropInStoredPaymentMethodDeletionModel = message.contentIfNotHandled
val platformCommunicationModel = PlatformCommunicationModel(
PlatformCommunicationType.DELETESTOREDPAYMENTMETHOD,
data = dropInStoredPaymentMethodDeletionModel?.storedPaymentMethodId,
)

when (dropInStoredPaymentMethodDeletionModel?.dropInFlowType) {
DropInFlowType.SESSION -> checkoutFlutterApi?.onDropInSessionPlatformCommunication(
platformCommunicationModel
) {}

DropInFlowType.ADVANCED_FLOW -> checkoutFlutterApi?.onDropInAdvancedFlowPlatformCommunication(
platformCommunicationModel
) {}

null -> return@observe
}
}
}

private fun setAdvanceFlowDropInAdditionalDetailsMessengerObserver() {
DropInAdditionalDetailsPlatformMessenger.instance().removeObservers(activity)
DropInAdditionalDetailsPlatformMessenger.instance().observe(activity) { message ->
if (message.hasBeenHandled()) {
return@observe
}

val model = PlatformCommunicationModel(
val platformCommunicationModel = PlatformCommunicationModel(
PlatformCommunicationType.ADDITIONALDETAILS,
data = message.contentIfNotHandled.toString(),
)
checkoutFlutterApi?.onDropInAdvancedFlowPlatformCommunication(model) {}

checkoutFlutterApi?.onDropInAdvancedFlowPlatformCommunication(platformCommunicationModel) {}
}
}

Expand Down
119 changes: 87 additions & 32 deletions android/src/main/kotlin/com/adyen/adyen_checkout/PlatformApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ enum class PaymentResultEnum(val raw: Int) {
enum class PlatformCommunicationType(val raw: Int) {
PAYMENTCOMPONENT(0),
ADDITIONALDETAILS(1),
RESULT(2);
RESULT(2),
DELETESTOREDPAYMENTMETHOD(3);

companion object {
fun ofRaw(raw: Int): PlatformCommunicationType? {
Expand Down Expand Up @@ -174,14 +175,14 @@ data class SessionDTO (

/** Generated class from Pigeon that represents data sent in messages. */
data class AmountDTO (
val currency: String? = null,
val currency: String,
val value: Long

) {
companion object {
@Suppress("UNCHECKED_CAST")
fun fromList(list: List<Any?>): AmountDTO {
val currency = list[0] as String?
val currency = list[0] as String
val value = list[1].let { if (it is Int) it.toLong() else it as Long }
return AmountDTO(currency, value)
}
Expand Down Expand Up @@ -223,13 +224,14 @@ data class DropInConfigurationDTO (
val countryCode: String,
val amount: AmountDTO,
val shopperLocale: String,
val analyticsOptionsDTO: AnalyticsOptionsDTO? = null,
val showPreselectedStoredPaymentMethod: Boolean? = null,
val skipListWhenSinglePaymentMethod: Boolean? = null,
val cardsConfigurationDTO: CardsConfigurationDTO? = null,
val applePayConfigurationDTO: ApplePayConfigurationDTO? = null,
val googlePayConfigurationDTO: GooglePayConfigurationDTO? = null,
val cashAppPayConfigurationDTO: CashAppPayConfigurationDTO? = null
val cashAppPayConfigurationDTO: CashAppPayConfigurationDTO? = null,
val analyticsOptionsDTO: AnalyticsOptionsDTO? = null,
val showPreselectedStoredPaymentMethod: Boolean,
val skipListWhenSinglePaymentMethod: Boolean,
val isRemoveStoredPaymentMethodEnabled: Boolean

) {
companion object {
Expand All @@ -240,24 +242,25 @@ data class DropInConfigurationDTO (
val countryCode = list[2] as String
val amount = AmountDTO.fromList(list[3] as List<Any?>)
val shopperLocale = list[4] as String
val analyticsOptionsDTO: AnalyticsOptionsDTO? = (list[5] as List<Any?>?)?.let {
AnalyticsOptionsDTO.fromList(it)
}
val showPreselectedStoredPaymentMethod = list[6] as Boolean?
val skipListWhenSinglePaymentMethod = list[7] as Boolean?
val cardsConfigurationDTO: CardsConfigurationDTO? = (list[8] as List<Any?>?)?.let {
val cardsConfigurationDTO: CardsConfigurationDTO? = (list[5] as List<Any?>?)?.let {
CardsConfigurationDTO.fromList(it)
}
val applePayConfigurationDTO: ApplePayConfigurationDTO? = (list[9] as List<Any?>?)?.let {
val applePayConfigurationDTO: ApplePayConfigurationDTO? = (list[6] as List<Any?>?)?.let {
ApplePayConfigurationDTO.fromList(it)
}
val googlePayConfigurationDTO: GooglePayConfigurationDTO? = (list[10] as List<Any?>?)?.let {
val googlePayConfigurationDTO: GooglePayConfigurationDTO? = (list[7] as List<Any?>?)?.let {
GooglePayConfigurationDTO.fromList(it)
}
val cashAppPayConfigurationDTO: CashAppPayConfigurationDTO? = (list[11] as List<Any?>?)?.let {
val cashAppPayConfigurationDTO: CashAppPayConfigurationDTO? = (list[8] as List<Any?>?)?.let {
CashAppPayConfigurationDTO.fromList(it)
}
return DropInConfigurationDTO(environment, clientKey, countryCode, amount, shopperLocale, analyticsOptionsDTO, showPreselectedStoredPaymentMethod, skipListWhenSinglePaymentMethod, cardsConfigurationDTO, applePayConfigurationDTO, googlePayConfigurationDTO, cashAppPayConfigurationDTO)
val analyticsOptionsDTO: AnalyticsOptionsDTO? = (list[9] as List<Any?>?)?.let {
AnalyticsOptionsDTO.fromList(it)
}
val showPreselectedStoredPaymentMethod = list[10] as Boolean
val skipListWhenSinglePaymentMethod = list[11] as Boolean
val isRemoveStoredPaymentMethodEnabled = list[12] as Boolean
return DropInConfigurationDTO(environment, clientKey, countryCode, amount, shopperLocale, cardsConfigurationDTO, applePayConfigurationDTO, googlePayConfigurationDTO, cashAppPayConfigurationDTO, analyticsOptionsDTO, showPreselectedStoredPaymentMethod, skipListWhenSinglePaymentMethod, isRemoveStoredPaymentMethodEnabled)
}
}
fun toList(): List<Any?> {
Expand All @@ -267,13 +270,14 @@ data class DropInConfigurationDTO (
countryCode,
amount.toList(),
shopperLocale,
analyticsOptionsDTO?.toList(),
showPreselectedStoredPaymentMethod,
skipListWhenSinglePaymentMethod,
cardsConfigurationDTO?.toList(),
applePayConfigurationDTO?.toList(),
googlePayConfigurationDTO?.toList(),
cashAppPayConfigurationDTO?.toList(),
analyticsOptionsDTO?.toList(),
showPreselectedStoredPaymentMethod,
skipListWhenSinglePaymentMethod,
isRemoveStoredPaymentMethodEnabled,
)
}
}
Expand Down Expand Up @@ -584,6 +588,28 @@ data class DropInErrorDTO (
}
}

/** Generated class from Pigeon that represents data sent in messages. */
data class DeletedStoredPaymentMethodResultDTO (
val storedPaymentMethodId: String,
val isSuccessfullyRemoved: Boolean

) {
companion object {
@Suppress("UNCHECKED_CAST")
fun fromList(list: List<Any?>): DeletedStoredPaymentMethodResultDTO {
val storedPaymentMethodId = list[0] as String
val isSuccessfullyRemoved = list[1] as Boolean
return DeletedStoredPaymentMethodResultDTO(storedPaymentMethodId, isSuccessfullyRemoved)
}
}
fun toList(): List<Any?> {
return listOf<Any?>(
storedPaymentMethodId,
isSuccessfullyRemoved,
)
}
}

@Suppress("UNCHECKED_CAST")
private object CheckoutPlatformInterfaceCodec : StandardMessageCodec() {
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
Expand Down Expand Up @@ -615,25 +641,30 @@ private object CheckoutPlatformInterfaceCodec : StandardMessageCodec() {
}
133.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
DropInConfigurationDTO.fromList(it)
DeletedStoredPaymentMethodResultDTO.fromList(it)
}
}
134.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
DropInErrorDTO.fromList(it)
DropInConfigurationDTO.fromList(it)
}
}
135.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
DropInResultDTO.fromList(it)
DropInErrorDTO.fromList(it)
}
}
136.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
GooglePayConfigurationDTO.fromList(it)
DropInResultDTO.fromList(it)
}
}
137.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
GooglePayConfigurationDTO.fromList(it)
}
}
138.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
SessionDTO.fromList(it)
}
Expand Down Expand Up @@ -663,26 +694,30 @@ private object CheckoutPlatformInterfaceCodec : StandardMessageCodec() {
stream.write(132)
writeValue(stream, value.toList())
}
is DropInConfigurationDTO -> {
is DeletedStoredPaymentMethodResultDTO -> {
stream.write(133)
writeValue(stream, value.toList())
}
is DropInErrorDTO -> {
is DropInConfigurationDTO -> {
stream.write(134)
writeValue(stream, value.toList())
}
is DropInResultDTO -> {
is DropInErrorDTO -> {
stream.write(135)
writeValue(stream, value.toList())
}
is GooglePayConfigurationDTO -> {
is DropInResultDTO -> {
stream.write(136)
writeValue(stream, value.toList())
}
is SessionDTO -> {
is GooglePayConfigurationDTO -> {
stream.write(137)
writeValue(stream, value.toList())
}
is SessionDTO -> {
stream.write(138)
writeValue(stream, value.toList())
}
else -> super.writeValue(stream, value)
}
}
Expand All @@ -696,6 +731,7 @@ interface CheckoutPlatformInterface {
fun startDropInAdvancedFlowPayment(dropInConfigurationDTO: DropInConfigurationDTO, paymentMethodsResponse: String)
fun onPaymentsResult(paymentsResult: DropInResultDTO)
fun onPaymentsDetailsResult(paymentsDetailsResult: DropInResultDTO)
fun onDeleteStoredPaymentMethodResult(deleteStoredPaymentMethodResultDTO: DeletedStoredPaymentMethodResultDTO)

companion object {
/** The codec used by CheckoutPlatformInterface. */
Expand Down Expand Up @@ -819,6 +855,25 @@ interface CheckoutPlatformInterface {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.adyen_checkout.CheckoutPlatformInterface.onDeleteStoredPaymentMethodResult", codec)
if (api != null) {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val deleteStoredPaymentMethodResultDTOArg = args[0] as DeletedStoredPaymentMethodResultDTO
var wrapped: List<Any?>
try {
api.onDeleteStoredPaymentMethodResult(deleteStoredPaymentMethodResultDTOArg)
wrapped = listOf<Any?>(null)
} catch (exception: Throwable) {
wrapped = wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
}
}
}
Expand Down Expand Up @@ -890,9 +945,9 @@ class CheckoutFlutterApi(private val binaryMessenger: BinaryMessenger) {
CheckoutFlutterApiCodec
}
}
fun onDropInSessionResult(sessionPaymentResultArg: PaymentResultDTO, callback: () -> Unit) {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.adyen_checkout.CheckoutFlutterApi.onDropInSessionResult", codec)
channel.send(listOf(sessionPaymentResultArg)) {
fun onDropInSessionPlatformCommunication(platformCommunicationModelArg: PlatformCommunicationModel, callback: () -> Unit) {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.adyen_checkout.CheckoutFlutterApi.onDropInSessionPlatformCommunication", codec)
channel.send(listOf(platformCommunicationModelArg)) {
callback()
}
}
Expand Down
Loading

0 comments on commit 54a737e

Please sign in to comment.