Skip to content

Commit

Permalink
Adjusted dropin to use the generic createSession method instead of re…
Browse files Browse the repository at this point in the history
…questing a own session.
  • Loading branch information
Robert-SD committed Dec 12, 2023
1 parent 69f4253 commit 11e5be0
Show file tree
Hide file tree
Showing 15 changed files with 150 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class AdyenCheckoutPlugin : FlutterPlugin, ActivityAware {

//DropIn init
dropInFlutterApi = DropInFlutterInterface(flutterPluginBinding.binaryMessenger)
dropInFlutterApi?.let { dropInPlatformApi = DropInPlatformApi(it) }
dropInFlutterApi?.let { dropInPlatformApi = DropInPlatformApi(it, sessionHolder) }
DropInPlatformInterface.setUp(flutterPluginBinding.binaryMessenger, dropInPlatformApi)

//Component init
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.adyen.adyen_checkout.session.SessionHolder
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToAnalyticsConfiguration
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToDropInConfiguration
import com.adyen.adyen_checkout.utils.ConfigurationMapper.toNativeModel
import com.adyen.checkout.components.core.OrderRequest
import com.adyen.checkout.components.core.PaymentMethodsApiResponse
Expand Down Expand Up @@ -66,7 +67,7 @@ class CheckoutPlatformApi(
}

is DropInConfigurationDTO -> {
//TODO: Add support for DropIn session
return configuration.mapToDropInConfiguration(activity)
}
}

Expand Down
14 changes: 2 additions & 12 deletions android/src/main/kotlin/com/adyen/adyen_checkout/PlatformApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1003,11 +1003,6 @@ private object DropInPlatformInterfaceCodec : StandardMessageCodec() {
PaymentFlowOutcomeDTO.fromList(it)
}
}
138.toByte() -> {
return (readValue(buffer) as? List<Any?>)?.let {
SessionDTO.fromList(it)
}
}
else -> super.readValueOfType(type, buffer)
}
}
Expand Down Expand Up @@ -1053,18 +1048,14 @@ private object DropInPlatformInterfaceCodec : StandardMessageCodec() {
stream.write(137)
writeValue(stream, value.toList())
}
is SessionDTO -> {
stream.write(138)
writeValue(stream, value.toList())
}
else -> super.writeValue(stream, value)
}
}
}

/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
interface DropInPlatformInterface {
fun startDropInSessionPayment(dropInConfigurationDTO: DropInConfigurationDTO, session: SessionDTO)
fun startDropInSessionPayment(dropInConfigurationDTO: DropInConfigurationDTO)
fun startDropInAdvancedFlowPayment(dropInConfigurationDTO: DropInConfigurationDTO, paymentMethodsResponse: String)
fun onPaymentsResult(paymentsResult: PaymentFlowOutcomeDTO)
fun onPaymentsDetailsResult(paymentsDetailsResult: PaymentFlowOutcomeDTO)
Expand All @@ -1085,10 +1076,9 @@ interface DropInPlatformInterface {
channel.setMessageHandler { message, reply ->
val args = message as List<Any?>
val dropInConfigurationDTOArg = args[0] as DropInConfigurationDTO
val sessionArg = args[1] as SessionDTO
var wrapped: List<Any?>
try {
api.startDropInSessionPayment(dropInConfigurationDTOArg, sessionArg)
api.startDropInSessionPayment(dropInConfigurationDTOArg)
wrapped = listOf<Any?>(null)
} catch (exception: Throwable) {
wrapped = wrapError(exception)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import PaymentResultEnum
import PaymentResultModelDTO
import PlatformCommunicationModel
import PlatformCommunicationType
import SessionDTO
import androidx.activity.result.ActivityResultLauncher
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
Expand All @@ -24,9 +23,10 @@ import com.adyen.adyen_checkout.dropIn.dropInAdvancedFlow.DropInPaymentResultMes
import com.adyen.adyen_checkout.dropIn.dropInAdvancedFlow.DropInServiceResultMessenger
import com.adyen.adyen_checkout.dropIn.dropInSession.SessionDropInService
import com.adyen.adyen_checkout.dropIn.models.DropInFlowType
import com.adyen.adyen_checkout.session.SessionHolder
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToDropInConfiguration
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToOrderResponseModel
import com.adyen.adyen_checkout.utils.ConfigurationMapper.mapToSession
import com.adyen.checkout.components.core.Order
import com.adyen.checkout.components.core.PaymentMethodsApiResponse
import com.adyen.checkout.dropin.DropIn
import com.adyen.checkout.dropin.DropInCallback
Expand All @@ -36,39 +36,30 @@ import com.adyen.checkout.dropin.SessionDropInResult
import com.adyen.checkout.dropin.internal.ui.model.DropInResultContractParams
import com.adyen.checkout.dropin.internal.ui.model.SessionDropInResultContractParams
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 DropInPlatformApi(
private val dropInFlutterApi: DropInFlutterInterface,
private val sessionHolder: SessionHolder,
) : DropInPlatformInterface {
lateinit var activity: FragmentActivity
lateinit var dropInSessionLauncher: ActivityResultLauncher<SessionDropInResultContractParams>
lateinit var dropInAdvancedFlowLauncher: ActivityResultLauncher<DropInResultContractParams>
override fun startDropInSessionPayment(
dropInConfigurationDTO: DropInConfigurationDTO,
session: SessionDTO,
) {
override fun startDropInSessionPayment(dropInConfigurationDTO: DropInConfigurationDTO) {
setStoredPaymentMethodDeletionObserver()
activity.lifecycleScope.launch(Dispatchers.IO) {
val sessionModel = session.mapToSession()
val dropInConfiguration = dropInConfigurationDTO.mapToDropInConfiguration(activity.applicationContext)
val checkoutSession = createCheckoutSession(sessionModel, dropInConfiguration)
withContext(Dispatchers.Main) {
DropIn.startPayment(
activity.applicationContext,
dropInSessionLauncher,
checkoutSession,
dropInConfiguration,
SessionDropInService::class.java
)
}
}
val dropInConfiguration = dropInConfigurationDTO.mapToDropInConfiguration(activity.applicationContext)
val checkoutSession = createCheckoutSession(sessionHolder)
DropIn.startPayment(
activity.applicationContext,
dropInSessionLauncher,
checkoutSession,
dropInConfiguration,
SessionDropInService::class.java
)
}

override fun startDropInAdvancedFlowPayment(
Expand Down Expand Up @@ -178,15 +169,10 @@ class DropInPlatformApi(
}
}

private suspend fun createCheckoutSession(
sessionModel: SessionModel,
dropInConfiguration: com.adyen.checkout.dropin.DropInConfiguration,
): CheckoutSession {
return when (val checkoutSessionResult =
CheckoutSessionProvider.createSession(sessionModel, dropInConfiguration)) {
is CheckoutSessionResult.Success -> checkoutSessionResult.checkoutSession
is CheckoutSessionResult.Error -> throw checkoutSessionResult.exception
}
private fun createCheckoutSession(sessionHolder: SessionHolder): CheckoutSession {
val sessionSetupResponse = SessionSetupResponse.SERIALIZER.deserialize(sessionHolder.sessionSetupResponse)
val order = sessionHolder.orderResponse?.let { Order.SERIALIZER.deserialize(it) }
return CheckoutSession(sessionSetupResponse = sessionSetupResponse, order = order)
}

// Gift cards will be supported in a later version
Expand Down Expand Up @@ -217,7 +203,8 @@ class DropInPlatformApi(
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()
Expand Down
7 changes: 4 additions & 3 deletions example/lib/screens/drop_in/drop_in_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ class _DropInScreenState extends State<DropInScreen> {
await widget.repository.fetchSession();
final DropInConfiguration dropInConfiguration =
await _createDropInConfiguration();
final Session session = Session(
id: sessionResponse.id,

final Session session = await widget.adyenCheckout.createSession(
sessionId: sessionResponse.id,
sessionData: sessionResponse.sessionData,
paymentMethodsJson: "",
configuration: dropInConfiguration,
);

final PaymentResult paymentResult = await widget.adyenCheckout.startPayment(
Expand Down
4 changes: 2 additions & 2 deletions ios/Classes/AdyenCheckoutPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ public class AdyenCheckoutPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let sessionHolder = SessionHolder()
let messenger: FlutterBinaryMessenger = registrar.messenger()
let dropInFlutterApi = DropInFlutterInterface(binaryMessenger: messenger)
let componentFlutterApi = ComponentFlutterInterface(binaryMessenger: messenger)
let checkoutPlatformApi = CheckoutPlatformApi(componentFlutterApi: componentFlutterApi, sessionHolder: sessionHolder)
let checkoutPlatformApi = CheckoutPlatformApi(dropInFlutterApi: dropInFlutterApi, componentFlutterApi: componentFlutterApi, sessionHolder: sessionHolder)
CheckoutPlatformInterfaceSetup.setUp(binaryMessenger: messenger, api: checkoutPlatformApi)

// DropIn
let dropInFlutterApi = DropInFlutterInterface(binaryMessenger: messenger)
let dropInPlatformApi = DropInPlatformApi(dropInFlutterApi: dropInFlutterApi, sessionHolder: sessionHolder)
DropInPlatformInterfaceSetup.setUp(binaryMessenger: messenger, api: dropInPlatformApi)

Expand Down
99 changes: 76 additions & 23 deletions ios/Classes/CheckoutPlatformApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@ import AdyenNetworking

class CheckoutPlatformApi: CheckoutPlatformInterface {
private let configurationMapper = ConfigurationMapper()
private let dropInFlutterApi: DropInFlutterInterface
private let componentFlutterApi: ComponentFlutterInterface
private let sessionHolder: SessionHolder

init(
dropInFlutterApi : DropInFlutterInterface,
componentFlutterApi: ComponentFlutterInterface,
sessionHolder: SessionHolder
) {
self.dropInFlutterApi = dropInFlutterApi
self.componentFlutterApi = componentFlutterApi
self.sessionHolder = sessionHolder
}

func createSession(
sessionId: String,
sessionData: String,
Expand All @@ -28,29 +31,10 @@ class CheckoutPlatformApi: CheckoutPlatformInterface {
) {
do {
switch configuration {
case is DropInConfigurationDTO:
try createSessionForDropIn(configuration as! DropInConfigurationDTO, sessionId, sessionData, completion)
case is CardComponentConfigurationDTO:
let adyenContext = try (configuration as! CardComponentConfigurationDTO).createAdyenContext()
let sessionConfiguration = AdyenSession.Configuration(sessionIdentifier: sessionId,
initialSessionData: sessionData,
context: adyenContext,
actionComponent: .init())
let sessionDelegate = CardSessionFlowDelegate(componentFlutterApi: componentFlutterApi)
let sessionPresentationDelegate = CardPresentationDelegate(topViewController: getViewController())
AdyenSession.initialize(with: sessionConfiguration,
delegate: sessionDelegate,
presentationDelegate: sessionPresentationDelegate)
{ [weak self] result in
switch result {
case let .success(session):
self?.sessionHolder.setup(session: session, sessionPresentationDelegate: sessionPresentationDelegate, sessionDelegate: sessionDelegate)
// TODO: serialize paymentMethods
completion(Result.success(SessionDTO(id: sessionId,
sessionData: sessionData,
paymentMethodsJson: "")))
case let .failure(error):
completion(Result.failure(error))
}
}
try createSessionForCardComponent(configuration as! CardComponentConfigurationDTO, sessionId, sessionData, completion)
case .none, .some:
completion(Result.failure(PlatformError(errorDescription: "Configuration is not valid")))
}
Expand All @@ -66,6 +50,75 @@ class CheckoutPlatformApi: CheckoutPlatformInterface {
func enableConsoleLogging(loggingEnabled: Bool) {
AdyenLogging.isEnabled = loggingEnabled
}

private func createSessionForDropIn(
_ configuration: DropInConfigurationDTO,
_ sessionId: String,
_ sessionData: String,
_ completion: @escaping (Result<SessionDTO, Error>) -> Void
) throws {
let adyenContext = try configuration.createAdyenContext()
let sessionDelegate = DropInSessionsDelegate(viewController: getViewController(), dropInFlutterApi: dropInFlutterApi)
let sessionPresentationDelegate = DropInSessionsPresentationDelegate()
requestAndSetSession(
adyenContext,
sessionId,
sessionData,
sessionDelegate,
sessionPresentationDelegate,
completion
)
}

private func createSessionForCardComponent(
_ configuration: CardComponentConfigurationDTO,
_ sessionId: String,
_ sessionData: String,
_ completion: @escaping (Result<SessionDTO, Error>) -> Void
) throws {
let adyenContext = try configuration.createAdyenContext()
let sessionDelegate = CardSessionFlowDelegate(componentFlutterApi: componentFlutterApi)
let sessionPresentationDelegate = CardPresentationDelegate(topViewController: getViewController())
requestAndSetSession(
adyenContext,
sessionId,
sessionData,
sessionDelegate,
sessionPresentationDelegate,
completion
)
}

private func requestAndSetSession(
_ adyenContext: AdyenContext,
_ sessionId: String,
_ sessionData: String,
_ sessionDelegate: AdyenSessionDelegate,
_ sessionPresentationDelegate : PresentationDelegate,
_ completion: @escaping (Result<SessionDTO, Error>) -> Void
) {
let sessionConfiguration = AdyenSession.Configuration(sessionIdentifier: sessionId,
initialSessionData: sessionData,
context: adyenContext,
actionComponent: .init())
AdyenSession.initialize(with: sessionConfiguration,
delegate: sessionDelegate,
presentationDelegate: sessionPresentationDelegate)
{ [weak self] result in
switch result {
case let .success(session):
// TODO: For a later version - We need to return the actual session and removing the session holder when the session is codable.
self?.sessionHolder.setup(session: session, sessionPresentationDelegate: sessionPresentationDelegate, sessionDelegate: sessionDelegate)
// TODO: serialize paymentMethods
completion(Result.success(SessionDTO(id: sessionId,
sessionData: sessionData,
paymentMethodsJson: "")))
case let .failure(error):
completion(Result.failure(error))
}
}
}


private func getViewController() -> UIViewController? {
var rootViewController = UIApplication.shared.adyen.mainKeyWindow?.rootViewController
Expand Down
10 changes: 2 additions & 8 deletions ios/Classes/PlatformApi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -896,8 +896,6 @@ private class DropInPlatformInterfaceCodecReader: FlutterStandardReader {
return GooglePayConfigurationDTO.fromList(self.readValue() as! [Any?])
case 137:
return PaymentFlowOutcomeDTO.fromList(self.readValue() as! [Any?])
case 138:
return SessionDTO.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
Expand Down Expand Up @@ -936,9 +934,6 @@ private class DropInPlatformInterfaceCodecWriter: FlutterStandardWriter {
} else if let value = value as? PaymentFlowOutcomeDTO {
super.writeByte(137)
super.writeValue(value.toList())
} else if let value = value as? SessionDTO {
super.writeByte(138)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
Expand All @@ -961,7 +956,7 @@ class DropInPlatformInterfaceCodec: FlutterStandardMessageCodec {

/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol DropInPlatformInterface {
func startDropInSessionPayment(dropInConfigurationDTO: DropInConfigurationDTO, session: SessionDTO) throws
func startDropInSessionPayment(dropInConfigurationDTO: DropInConfigurationDTO) throws
func startDropInAdvancedFlowPayment(dropInConfigurationDTO: DropInConfigurationDTO, paymentMethodsResponse: String) throws
func onPaymentsResult(paymentsResult: PaymentFlowOutcomeDTO) throws
func onPaymentsDetailsResult(paymentsDetailsResult: PaymentFlowOutcomeDTO) throws
Expand All @@ -980,9 +975,8 @@ class DropInPlatformInterfaceSetup {
startDropInSessionPaymentChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let dropInConfigurationDTOArg = args[0] as! DropInConfigurationDTO
let sessionArg = args[1] as! SessionDTO
do {
try api.startDropInSessionPayment(dropInConfigurationDTO: dropInConfigurationDTOArg, session: sessionArg)
try api.startDropInSessionPayment(dropInConfigurationDTO: dropInConfigurationDTOArg)
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
Expand Down
Loading

0 comments on commit 11e5be0

Please sign in to comment.