-
Notifications
You must be signed in to change notification settings - Fork 135
Expand file tree
/
Copy pathDropInExample.swift
More file actions
158 lines (122 loc) · 4.98 KB
/
DropInExample.swift
File metadata and controls
158 lines (122 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
//
// Copyright (c) 2023 Adyen N.V.
//
// This file is open source and available under the MIT license. See the LICENSE file for more info.
//
@_spi(AdyenInternal) import Adyen
import AdyenActions
import AdyenCard
import AdyenComponents
import AdyenDropIn
import AdyenNetworking
import AdyenSession
import UIKit
internal final class DropInExample: InitialDataFlowProtocol {
// MARK: - Properties
internal weak var presenter: PresenterExampleProtocol?
private var session: Session?
private var dropInComponent: DropInComponent?
internal lazy var apiClient = ApiClientHelper.generateApiClient()
internal var context: AdyenContext?
// MARK: - Initializers
internal init() {}
internal func start() {
presenter?.showLoadingIndicator()
Task {
do {
try await initializeExampleAppAdyenContext()
loadSession { [weak self] response in
guard let self else { return }
self.presenter?.hideLoadingIndicator()
switch response {
case let .success(session):
self.session = session
self.presentComponent(with: session)
case let .failure(error):
self.presentAlert(with: error)
}
}
} catch {
self.presenter?.hideLoadingIndicator()
self.presentAlert(with: error)
}
}
}
// MARK: - Networking
private func loadSession(completion: @escaping (Result<Session, Error>) -> Void) {
requestSessionInitialInfo { [weak self] response in
guard let self else { return }
switch response {
case let .success(model):
// Session.initialize(
// with: config,
// delegate: self,
// presentationDelegate: self,
// completion: completion
// )
break
case let .failure(error):
completion(.failure(error))
}
}
}
// MARK: - Presentation
private func presentComponent(with session: Session) {
let dropIn = dropInComponent(from: session)
presenter?.present(viewController: dropIn.viewController, completion: nil)
dropInComponent = dropIn
}
private func dropInComponent(from session: Session) -> DropInComponent {
guard let context else {
fatalError("AdyenContext is not initialized")
}
let paymentMethods = session.state.paymentMethods
let configuration = dropInConfiguration(from: paymentMethods)
let component = DropInComponent(
paymentMethods: paymentMethods,
context: context,
configuration: configuration,
title: ConfigurationConstants.appName
)
component.delegate = session
component.storedPaymentMethodsDelegate = session
component.partialPaymentDelegate = session
return component
}
private func dropInConfiguration(from paymentMethods: PaymentMethods) -> DropInComponent.Configuration {
let configuration = ConfigurationConstants.current.dropInConfiguration
configuration.applePay = try? ConfigurationConstants.current.applePayConfiguration(using: .demo)
configuration.actionComponent.authentication.delegatedAuthentication = ConfigurationConstants.delegatedAuthenticationConfigurations
configuration.card = ConfigurationConstants.current.cardDropInConfiguration
return configuration
}
// MARK: - Alert handling
private func presentAlert(with error: Error, retryHandler: (() -> Void)? = nil) {
presenter?.presentAlert(with: error, retryHandler: retryHandler)
}
private func dismissAndShowAlert(_ success: Bool, _ message: String) {
presenter?.dismiss {
// Payment is processed. Add your code here.
let title = success ? "Success" : "Error"
self.presenter?.presentAlert(withTitle: title, message: message)
}
}
}
extension DropInExample: SessionDelegate {
func didComplete(with result: CheckoutResult, component: Component, session: Session) {
dismissAndShowAlert(result.resultCode.isSuccess, result.resultCode.rawValue)
}
func didFail(with error: Error, from component: Component, session: Session) {
if (error as? ComponentError) == .cancelled {
presenter?.dismiss(completion: nil)
} else {
dismissAndShowAlert(false, error.localizedDescription)
}
}
func didOpenExternalApplication(component: ActionComponent, session: Session) {}
}
extension DropInExample: PresentationDelegate {
internal func present(component: PresentableComponent) {
// The implementation of this delegate method is not needed when using Session as the session handles the presentation
}
}