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//
// AuthenticationSession.swift
// hyperswitch
//
// Created by Harshit Srivastava on 31/10/25.
//
import Foundation
import UIKit
public class AuthenticationSession {
private var authIntentClientSecret: String?
private var authConfiguration: AuthenticationConfiguration?
private var threeDSProvider: ThreeDSProvider?
private var sessionProvider: ThreeDSSessionProvider?
private var publishableKey: String
private var customBackendUrl: String?
private var customParams: [String: Any]?
private var customLogUrl: String?
private var clientSecret: String?
private var profileId: String?
private var authenticationId: String?
private var merchantId: String?
private var currentClickToPaySession: ClickToPaySession?
public init(publishableKey: String, customBackendUrl: String? = nil, customParams: [String : Any]? = nil, customLogUrl: String? = nil) {
self.publishableKey = publishableKey
self.customBackendUrl = customBackendUrl
self.customLogUrl = customLogUrl
self.customParams = customParams
APIClient.shared.publishableKey = publishableKey
APIClient.shared.customBackendUrl = customBackendUrl
APIClient.shared.customLogUrl = customLogUrl
APIClient.shared.customParams = customParams
}
public func initAuthenticationSession(clientSecret: String, profileId: String, authenticationId: String, merchantId: String) {
self.clientSecret = clientSecret
self.profileId = profileId
self.authenticationId = authenticationId
self.merchantId = merchantId
}
public func initThreeDSSession(authIntentClientSecret: String, configuration: AuthenticationConfiguration? = nil) async throws -> ThreeDSSession {
self.authIntentClientSecret = authIntentClientSecret
self.authConfiguration = configuration
do {
self.threeDSProvider = try ThreeDSProviderFactory.createProvider(preferredProvider: configuration?.preferredProvider)
try await self.threeDSProvider?.initialize(configuration: configuration)
guard let sessionProvider = try self.threeDSProvider?.createSession() else {
throw TransactionError.transactionCreationFailed("Failed to create session provider.", nil)
}
return ThreeDSSession(sessionProvider: sessionProvider)
}
catch {
self.threeDSProvider = nil
self.sessionProvider = nil
throw error
}
}
public func initClickToPaySession(request3DSAuthentication: Bool? = true, viewController: UIViewController? = nil) async throws -> ClickToPaySession {
guard let clientSecret = clientSecret,
let profileId = profileId,
let authenticationId = authenticationId,
let merchantId = merchantId else {
throw NSError(domain: "ClickToPay", code: -1, userInfo: [NSLocalizedDescriptionKey: "Missing required authentication parameters"])
}
if let currentClickToPaySession = currentClickToPaySession {
await currentClickToPaySession.close()
}
currentClickToPaySession = nil
do {
let impl = try await ClickToPaySessionImpl(
publishableKey: publishableKey,
customBackendUrl: customBackendUrl,
customLogUrl: customLogUrl,
customParams: customParams,
viewController: viewController
)
try await impl.initClickToPaySession(
clientSecret: clientSecret,
profileId: profileId,
authenticationId: authenticationId,
merchantId: merchantId,
request3DSAuthentication: request3DSAuthentication ?? true
)
currentClickToPaySession = impl
return impl
} catch {
throw NSError(domain: "ClickToPay", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to initialize Click to Pay session: \(error.localizedDescription)"])
}
}
}