Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Feature/stored card component #69

Merged
merged 18 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.lifecycle.LifecycleEventObserver
import com.adyen.adyen_checkout.components.ComponentPlatformApi
import com.adyen.adyen_checkout.components.card.advancedFlow.CardAdvancedFlowComponentFactory
import com.adyen.adyen_checkout.components.card.session.CardSessionFlowComponentFactory
import com.adyen.adyen_checkout.session.SessionHolder
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToOrderResponseModel
import com.adyen.adyen_checkout.utils.Constants.Companion.WRONG_FLUTTER_ACTIVITY_USAGE_ERROR_MESSAGE
import com.adyen.checkout.dropin.DropIn
Expand All @@ -37,11 +38,12 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {
private var lifecycleReference: HiddenLifecycleReference? = null
private var lifecycleObserver: LifecycleEventObserver? = null
private var flutterPluginBinding: FlutterPluginBinding? = null
private var sessionHolder: SessionHolder = SessionHolder()

override fun onAttachedToEngine(flutterPluginBinding: FlutterPluginBinding) {
this.flutterPluginBinding = flutterPluginBinding
checkoutFlutterApi = CheckoutFlutterApi(flutterPluginBinding.binaryMessenger)
checkoutPlatformApi = CheckoutPlatformApi(checkoutFlutterApi)
checkoutPlatformApi = CheckoutPlatformApi(checkoutFlutterApi, sessionHolder)
componentFlutterApi = ComponentFlutterInterface(flutterPluginBinding.binaryMessenger)
componentPlatformApi = ComponentPlatformApi()
CheckoutPlatformInterface.setUp(flutterPluginBinding.binaryMessenger, checkoutPlatformApi)
Expand Down Expand Up @@ -84,7 +86,7 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {
)

flutterPluginBinding?.platformViewRegistry?.registerViewFactory(
"cardComponentSessionFlow", CardSessionFlowComponentFactory(fragmentActivity, it)
"cardComponentSessionFlow", CardSessionFlowComponentFactory(fragmentActivity, it, sessionHolder)
)
}
}
Expand Down Expand Up @@ -116,28 +118,19 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {
)

is SessionDropInResult.Error -> PaymentResultDTO(
PaymentResultEnum.ERROR,
reason = sessionDropInResult.reason
PaymentResultEnum.ERROR, reason = sessionDropInResult.reason
)

is SessionDropInResult.Finished -> PaymentResultDTO(
PaymentResultEnum.FINISHED,
is SessionDropInResult.Finished -> PaymentResultDTO(PaymentResultEnum.FINISHED,
result = with(sessionDropInResult.result) {
PaymentResultModelDTO(
sessionId,
sessionData,
sessionResult,
resultCode,
order?.mapToOrderResponseModel()
sessionId, sessionData, sessionResult, resultCode, order?.mapToOrderResponseModel()
)
}
)
})
}

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

checkoutFlutterApi?.onDropInSessionPlatformCommunication(platformCommunicationModel) {}
Expand All @@ -154,22 +147,18 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {
)

is DropInResult.Error -> PaymentResultDTO(
PaymentResultEnum.ERROR,
reason = dropInAdvancedFlowResult.reason
PaymentResultEnum.ERROR, reason = dropInAdvancedFlowResult.reason
)

is DropInResult.Finished -> PaymentResultDTO(
PaymentResultEnum.FINISHED,
result = PaymentResultModelDTO(
PaymentResultEnum.FINISHED, result = PaymentResultModelDTO(
resultCode = dropInAdvancedFlowResult.result
)
)
}

val platformCommunicationModel = PlatformCommunicationModel(
PlatformCommunicationType.RESULT,
data = "",
paymentResult = mappedResult
PlatformCommunicationType.RESULT, data = "", paymentResult = mappedResult
)
checkoutFlutterApi?.onDropInAdvancedFlowPlatformCommunication(platformCommunicationModel) {}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.adyen.adyen_checkout

import CardComponentConfigurationDTO
import CheckoutFlutterApi
import CheckoutPlatformInterface
import DeletedStoredPaymentMethodResultDTO
Expand All @@ -22,10 +23,14 @@ 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.session.SessionHolder
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToDropInConfiguration
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToSession
import com.adyen.adyen_checkout.utils.ConfigurationMapper.toNativeModel
import com.adyen.adyen_checkout.utils.Constants.Companion.WRONG_FLUTTER_ACTIVITY_USAGE_ERROR_MESSAGE
import com.adyen.checkout.components.core.OrderRequest
import com.adyen.checkout.components.core.PaymentMethodsApiResponse
import com.adyen.checkout.components.core.internal.Configuration
import com.adyen.checkout.core.AdyenLogger
import com.adyen.checkout.core.internal.util.Logger.NONE
import com.adyen.checkout.dropin.DropIn
Expand All @@ -35,15 +40,20 @@ import com.adyen.checkout.redirect.RedirectComponent
import com.adyen.checkout.sessions.core.CheckoutSession
import com.adyen.checkout.sessions.core.CheckoutSessionProvider
import com.adyen.checkout.sessions.core.CheckoutSessionResult
import com.adyen.checkout.sessions.core.SessionModel
import com.adyen.checkout.sessions.core.SessionSetupResponse
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject

class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) : CheckoutPlatformInterface {
@Suppress("NAME_SHADOWING")
class CheckoutPlatformApi(
private val checkoutFlutterApi: CheckoutFlutterApi?,
private val sessionHolder: SessionHolder,
) : CheckoutPlatformInterface {
lateinit var activity: FragmentActivity
lateinit var dropInSessionLauncher:
ActivityResultLauncher<SessionDropInResultContractParams>
lateinit var dropInSessionLauncher: ActivityResultLauncher<SessionDropInResultContractParams>
lateinit var dropInAdvancedFlowLauncher: ActivityResultLauncher<DropInResultContractParams>

override fun getPlatformVersion(callback: (Result<String>) -> Unit) {
Expand All @@ -54,6 +64,69 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
callback(Result.success(RedirectComponent.getReturnUrl(activity.applicationContext)))
}

override fun createSession(
sessionId: String, sessionData: String,
configuration: Any?,
callback: (Result<SessionDTO>) -> Unit,
) {
activity.lifecycleScope.launch(Dispatchers.IO) {
val sessionModel = SessionModel(sessionId, sessionData)
determineSessionConfiguration(configuration)?.let { sessionConfiguration ->
when (val sessionResult = CheckoutSessionProvider.createSession(sessionModel, sessionConfiguration)) {
is CheckoutSessionResult.Error -> callback(Result.failure(sessionResult.exception))
is CheckoutSessionResult.Success -> onSessionSuccessfullyCreated(
sessionResult, sessionModel, callback
)
}
}
}
}


private fun determineSessionConfiguration(configuration: Any?): Configuration? {
when (configuration) {
is CardComponentConfigurationDTO -> {
return configuration.cardConfiguration.toNativeModel(
"${configuration.shopperLocale}",
activity,
configuration.environment.toNativeModel(),
configuration.clientKey
)
}

is DropInConfigurationDTO -> {
//TODO: Add support for DropIn session
Robert-SD marked this conversation as resolved.
Show resolved Hide resolved
}
}

return null
}

private fun onSessionSuccessfullyCreated(
sessionResult: CheckoutSessionResult.Success,
sessionModel: SessionModel,
callback: (Result<SessionDTO>) -> Unit,
) {
with(sessionResult.checkoutSession) {
val sessionResponse = SessionSetupResponse.SERIALIZER.serialize(sessionSetupResponse)
val orderResponse = order?.let { OrderRequest.SERIALIZER.serialize(it) }
val paymentMethodsJsonObject = sessionSetupResponse.paymentMethodsApiResponse?.let {
PaymentMethodsApiResponse.SERIALIZER.serialize(it)
}
sessionHolder.init(sessionResponse, orderResponse)
callback(
Result.success(
SessionDTO(
id = sessionModel.id,
sessionData = sessionModel.sessionData ?: "",
paymentMethodsJson = paymentMethodsJsonObject?.toString() ?: "",
)
)
)
}
}


override fun startDropInSessionPayment(
dropInConfigurationDTO: DropInConfigurationDTO,
session: SessionDTO,
Expand All @@ -62,8 +135,7 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
setStoredPaymentMethodDeletionObserver()
activity.lifecycleScope.launch(Dispatchers.IO) {
val sessionModel = session.mapToSession()
val dropInConfiguration =
dropInConfigurationDTO.mapToDropInConfiguration(activity.applicationContext)
val dropInConfiguration = dropInConfigurationDTO.mapToDropInConfiguration(activity.applicationContext)
val checkoutSession = createCheckoutSession(sessionModel, dropInConfiguration)
withContext(Dispatchers.Main) {
DropIn.startPayment(
Expand All @@ -88,10 +160,8 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
val paymentMethodsApiResponse = PaymentMethodsApiResponse.SERIALIZER.deserialize(
JSONObject(paymentMethodsResponse),
)
val paymentMethodsWithoutGiftCards =
removeGiftCardPaymentMethods(paymentMethodsApiResponse)
val dropInConfiguration =
dropInConfigurationDTO.mapToDropInConfiguration(activity.applicationContext)
val paymentMethodsWithoutGiftCards = removeGiftCardPaymentMethods(paymentMethodsApiResponse)
val dropInConfiguration = dropInConfigurationDTO.mapToDropInConfiguration(activity.applicationContext)
withContext(Dispatchers.Main) {
DropIn.startPayment(
activity.applicationContext,
Expand All @@ -117,8 +187,7 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
}

override fun onDeleteStoredPaymentMethodResult(
deleteStoredPaymentMethodResultDTO:
DeletedStoredPaymentMethodResultDTO
deleteStoredPaymentMethodResultDTO: DeletedStoredPaymentMethodResultDTO
) {
DropInPaymentMethodDeletionResultMessenger.sendResult(deleteStoredPaymentMethodResultDTO)
}
Expand All @@ -138,12 +207,11 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
}

private suspend fun createCheckoutSession(
sessionModel: com.adyen.checkout.sessions.core.SessionModel,
sessionModel: SessionModel,
dropInConfiguration: com.adyen.checkout.dropin.DropInConfiguration,
): CheckoutSession {
val checkoutSessionResult =
CheckoutSessionProvider.createSession(sessionModel, dropInConfiguration)
return when (checkoutSessionResult) {
return when (val checkoutSessionResult =
CheckoutSessionProvider.createSession(sessionModel, dropInConfiguration)) {
is CheckoutSessionResult.Success -> checkoutSessionResult.checkoutSession
is CheckoutSessionResult.Error -> throw checkoutSessionResult.exception
}
Expand Down Expand Up @@ -220,12 +288,10 @@ class CheckoutPlatformApi(private val checkoutFlutterApi: CheckoutFlutterApi?) :
val giftCardTypeIdentifier = "giftcard"
val storedPaymentMethods =
paymentMethodsResponse.storedPaymentMethods?.filterNot { it.type == giftCardTypeIdentifier }
val paymentMethods =
paymentMethodsResponse.paymentMethods?.filterNot { it.type == giftCardTypeIdentifier }
val paymentMethods = paymentMethodsResponse.paymentMethods?.filterNot { it.type == giftCardTypeIdentifier }

return PaymentMethodsApiResponse(
storedPaymentMethods = storedPaymentMethods,
paymentMethods = paymentMethods
storedPaymentMethods = storedPaymentMethods, paymentMethods = paymentMethods
)
}
}
Loading
Loading