Skip to content

Commit

Permalink
Merge pull request #515 from feature/risk-sdk
Browse files Browse the repository at this point in the history
Integrate Risk SDK
  • Loading branch information
okhan-okbay-cko authored Mar 1, 2024
2 parents 6bcf57d + e9a0046 commit 2dae4f8
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 17 deletions.
1 change: 1 addition & 0 deletions Checkout.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ Pod::Spec.new do |s|
s.exclude_files = "Checkout/Samples/**"

s.dependency 'CheckoutEventLoggerKit', '~> 1.2.4'
s.dependency 'Risk', '2.0.1'

end
43 changes: 38 additions & 5 deletions Checkout/Source/Tokenisation/CheckoutAPIService.swift
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
//
// CheckoutAPIService.swift
//
//
//
// Created by Harry Brown on 23/11/2021.
//

import Foundation
import UIKit
import CheckoutEventLoggerKit
import Risk

public protocol CheckoutAPIProtocol {
func createToken(_ paymentSource: PaymentSource, completion: @escaping (Result<TokenDetails, TokenisationError.TokenRequest>) -> Void)
func createSecurityCodeToken(securityCode: String, completion: @escaping (Result<SecurityCodeResponse, TokenisationError.SecurityCodeError>) -> Void)
var correlationID: String { get }
}

protocol RiskProtocol: AnyObject {
func configure(completion: @escaping (Result<Void, RiskError.Configuration>) -> Void)
func publishData (cardToken: String?, completion: @escaping (Result<PublishRiskData, RiskError.Publish>) -> Void)
}

extension Risk: RiskProtocol {}

final public class CheckoutAPIService: CheckoutAPIProtocol {
private let requestExecutor: RequestExecuting
private let requestFactory: RequestProviding
private let tokenRequestFactory: TokenRequestProviding
private let tokenDetailsFactory: TokenDetailsProviding
private let logManager: LogManaging.Type
private var riskSDK: RiskProtocol

private let publicKey: String
private let environment: BaseURLProviding
Expand All @@ -41,7 +50,18 @@ final public class CheckoutAPIService: CheckoutAPIProtocol {
let tokenRequestFactory = TokenRequestFactory(cardValidator: cardValidator, decoder: snakeCaseJSONDecoder)
let tokenDetailsFactory = TokenDetailsFactory()
let logManager = LogManager.self


var riskEnvironment: RiskEnvironment
switch environment {
case .production:
riskEnvironment = .production
case .sandbox:
riskEnvironment = .sandbox
}

let riskConfig = RiskConfig(publicKey: publicKey, environment: riskEnvironment, framesMode: true)
let riskSDK = Risk.init(config: riskConfig)

logManager.setup(
environment: environment,
logger: CheckoutEventLogger(productName: Constants.Product.name),
Expand All @@ -57,7 +77,8 @@ final public class CheckoutAPIService: CheckoutAPIProtocol {
requestFactory: requestFactory,
tokenRequestFactory: tokenRequestFactory,
tokenDetailsFactory: tokenDetailsFactory,
logManager: logManager)
logManager: logManager,
riskSDK: riskSDK)
}

init(
Expand All @@ -67,7 +88,8 @@ final public class CheckoutAPIService: CheckoutAPIProtocol {
requestFactory: RequestProviding,
tokenRequestFactory: TokenRequestProviding,
tokenDetailsFactory: TokenDetailsProviding,
logManager: LogManaging.Type
logManager: LogManaging.Type,
riskSDK: RiskProtocol
) {
self.publicKey = publicKey
self.environment = environment
Expand All @@ -76,6 +98,7 @@ final public class CheckoutAPIService: CheckoutAPIProtocol {
self.tokenRequestFactory = tokenRequestFactory
self.tokenDetailsFactory = tokenDetailsFactory
self.logManager = logManager
self.riskSDK = riskSDK
}

/// The create token method tokenises the user’s card details.
Expand Down Expand Up @@ -126,12 +149,22 @@ final public class CheckoutAPIService: CheckoutAPIProtocol {
requestParameters,
responseType: TokenResponse.self,
responseErrorType: TokenisationError.ServerError.self
) { [tokenDetailsFactory, logManager, logTokenResponse] tokenResponseResult, httpURLResponse in
) { [weak self, tokenDetailsFactory, logManager, logTokenResponse] tokenResponseResult, httpURLResponse in
logTokenResponse(tokenResponseResult, httpURLResponse)

switch tokenResponseResult {
case .response(let tokenResponse):
let tokenDetails = tokenDetailsFactory.create(tokenResponse: tokenResponse)

guard let self else { return }
self.riskSDK.configure { configurationResult in
switch configurationResult {
case .failure: break
case .success():
self.riskSDK.publishData(cardToken: tokenDetails.token) { _ in }
}
}

completion(.success(tokenDetails))
case .errorResponse(let errorResponse):
completion(.failure(.serverError(errorResponse)))
Expand Down
28 changes: 28 additions & 0 deletions CheckoutTests/Stubs/StubRisk.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//
// StubRisk.swift
//
//
// Created by Precious Ossai on 20/02/2024.
//

import Foundation
@testable import Risk
@testable import Checkout

// swiftlint:disable large_tuple
class StubRisk: RiskProtocol {

var configureCalledCount = 0
var publishDataCalledCount = 0

func configure(completion: @escaping (Result<Void, RiskError.Configuration>) -> Void) {
configureCalledCount += 1
completion(.success(()))
}

func publishData (cardToken: String? = nil, completion: @escaping (Result<PublishRiskData, RiskError.Publish>) -> Void) {
publishDataCalledCount += 1
completion(.success(PublishRiskData(deviceSessionId: "dsid_testDeviceSessionId")))
}
}

10 changes: 8 additions & 2 deletions CheckoutTests/Tokenisation/CheckoutAPIServiceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ final class CheckoutAPIServiceTests: XCTestCase {
private var stubRequestFactory: StubRequestFactory! = StubRequestFactory()
private var stubTokenRequestFactory: StubTokenRequestFactory! = StubTokenRequestFactory()
private var stubTokenDetailsFactory: StubTokenDetailsFactory! = StubTokenDetailsFactory()
private var stubRisk: StubRisk! = .init()


override func setUp() {
Expand All @@ -36,7 +37,8 @@ final class CheckoutAPIServiceTests: XCTestCase {
requestFactory: stubRequestFactory,
tokenRequestFactory: stubTokenRequestFactory,
tokenDetailsFactory: stubTokenDetailsFactory,
logManager: StubLogManager.self
logManager: StubLogManager.self,
riskSDK: stubRisk
)
}

Expand All @@ -49,6 +51,7 @@ final class CheckoutAPIServiceTests: XCTestCase {
stubTokenRequestFactory = nil
stubSecurityCodeRequestExecutor = nil
stubTokenDetailsFactory = nil
stubRisk = nil

super.tearDown()
}
Expand Down Expand Up @@ -90,6 +93,8 @@ final class CheckoutAPIServiceTests: XCTestCase {
.init(tokenID: "token", scheme: "visa", httpStatusCode: 200, serverError: nil)
))

XCTAssertEqual(stubRisk.configureCalledCount, 1)
XCTAssertEqual(stubRisk.publishDataCalledCount, 1)
XCTAssertEqual(result, .success(tokenDetails))
}

Expand Down Expand Up @@ -213,7 +218,8 @@ extension CheckoutAPIServiceTests {
requestFactory: stubRequestFactory,
tokenRequestFactory: stubTokenRequestFactory,
tokenDetailsFactory: stubTokenDetailsFactory,
logManager: StubLogManager.self
logManager: StubLogManager.self,
riskSDK: stubRisk
)
}

Expand Down
18 changes: 18 additions & 0 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@
"version" : "1.2.4"
}
},
{
"identity" : "checkout-risk-sdk-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/checkout/checkout-risk-sdk-ios.git",
"state" : {
"revision" : "4823f05166dca8392a41b56b975515c7e0f1a8da",
"version" : "2.0.1"
}
},
{
"identity" : "fingerprintjs-pro-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/fingerprintjs/fingerprintjs-pro-ios",
"state" : {
"revision" : "ceb8b845ec99727ee9f78869a51688c6daa16bd8",
"version" : "2.2.0"
}
},
{
"identity" : "phonenumberkit",
"kind" : "remoteSourceControl",
Expand Down
5 changes: 5 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ let package = Package(
.package(
url: "https://github.com/marmelroy/PhoneNumberKit.git",
exact: "3.5.9"),
.package(
url: "https://github.com/checkout/checkout-risk-sdk-ios.git",
exact: "2.0.1"),
.package(
url: "https://github.com/checkout/checkout-event-logger-ios-framework.git",
from: "1.2.4"
Expand All @@ -29,6 +32,7 @@ let package = Package(
dependencies: [
.product(name: "CheckoutEventLoggerKit",
package: "checkout-event-logger-ios-framework"),
.product(name: "Risk", package: "checkout-risk-sdk-ios"),
"PhoneNumberKit",
"Checkout"
],
Expand All @@ -43,6 +47,7 @@ let package = Package(
dependencies: [
.product(name: "CheckoutEventLoggerKit",
package: "checkout-event-logger-ios-framework"),
.product(name: "Risk", package: "checkout-risk-sdk-ios"),
],
path: "Checkout/Source"
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
16900D442AE6BA38009A7CE9 /* SecurityCodeComponentUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16900D432AE6BA38009A7CE9 /* SecurityCodeComponentUITests.swift */; };
16900D702AEAD30D009A7CE9 /* XCUIElement+TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16900D6F2AEAD30D009A7CE9 /* XCUIElement+TestHelpers.swift */; };
169DF1482A7BFB1B00891DF0 /* CardSchemeFormatSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 169DF1472A7BFB1B00891DF0 /* CardSchemeFormatSnapshotTests.swift */; };
16BA563F2B8FA6CE000775F9 /* Frames in Frameworks */ = {isa = PBXBuildFile; productRef = 16BA563E2B8FA6CE000775F9 /* Frames */; };
16C3F8402A7927ED00690639 /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = 16C3F83F2A7927ED00690639 /* SnapshotTesting */; };
16C3F8422A7956EA00690639 /* CardValidationSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16C3F8412A7956EA00690639 /* CardValidationSnapshotTests.swift */; };
16E0AD482A8455F0003C9DDC /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16E0AD472A8455F0003C9DDC /* Helper.swift */; };
Expand Down Expand Up @@ -227,6 +228,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
16BA563F2B8FA6CE000775F9 /* Frames in Frameworks */,
1629C08C2AF90379001BD3D9 /* Frames in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -529,6 +531,7 @@
name = "iOS Example Frame";
packageProductDependencies = (
1629C08B2AF90379001BD3D9 /* Frames */,
16BA563E2B8FA6CE000775F9 /* Frames */,
);
productName = "iOS Example Frame";
productReference = 16AE74C32A5C1EBB0031F794 /* iOS Example Frame.app */;
Expand Down Expand Up @@ -577,7 +580,7 @@
mainGroup = E6646F8120CE6C0900D8353A;
packageReferences = (
16C3F83E2A7927ED00690639 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */,
1629C08A2AF90379001BD3D9 /* XCRemoteSwiftPackageReference "frames-ios" */,
16BA563D2B8FA6CE000775F9 /* XCRemoteSwiftPackageReference "frames-ios" */,
);
productRefGroup = E6646F8120CE6C0900D8353A;
projectDirPath = "";
Expand Down Expand Up @@ -1231,12 +1234,12 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
1629C08A2AF90379001BD3D9 /* XCRemoteSwiftPackageReference "frames-ios" */ = {
16BA563D2B8FA6CE000775F9 /* XCRemoteSwiftPackageReference "frames-ios" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/checkout/frames-ios";
requirement = {
kind = exactVersion;
version = 4.3.1;
branch = "PRISM-10522-risk-i-os-is-added-to-frames-i-os";
kind = branch;
};
};
16C3F83E2A7927ED00690639 /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = {
Expand All @@ -1252,17 +1255,19 @@
/* Begin XCSwiftPackageProductDependency section */
1629C08B2AF90379001BD3D9 /* Frames */ = {
isa = XCSwiftPackageProductDependency;
package = 1629C08A2AF90379001BD3D9 /* XCRemoteSwiftPackageReference "frames-ios" */;
productName = Frames;
};
1629C08D2AF905A4001BD3D9 /* Frames */ = {
isa = XCSwiftPackageProductDependency;
package = 1629C08A2AF90379001BD3D9 /* XCRemoteSwiftPackageReference "frames-ios" */;
productName = Frames;
};
1629C08F2AF905A8001BD3D9 /* Frames */ = {
isa = XCSwiftPackageProductDependency;
package = 1629C08A2AF90379001BD3D9 /* XCRemoteSwiftPackageReference "frames-ios" */;
productName = Frames;
};
16BA563E2B8FA6CE000775F9 /* Frames */ = {
isa = XCSwiftPackageProductDependency;
package = 16BA563D2B8FA6CE000775F9 /* XCRemoteSwiftPackageReference "frames-ios" */;
productName = Frames;
};
16C3F83F2A7927ED00690639 /* SnapshotTesting */ = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,31 @@
"version" : "1.2.4"
}
},
{
"identity" : "checkout-risk-sdk-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/checkout/checkout-risk-sdk-ios.git",
"state" : {
"revision" : "4823f05166dca8392a41b56b975515c7e0f1a8da",
"version" : "2.0.1"
}
},
{
"identity" : "fingerprintjs-pro-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/fingerprintjs/fingerprintjs-pro-ios",
"state" : {
"revision" : "ceb8b845ec99727ee9f78869a51688c6daa16bd8",
"version" : "2.2.0"
}
},
{
"identity" : "frames-ios",
"kind" : "remoteSourceControl",
"location" : "https://github.com/checkout/frames-ios",
"state" : {
"revision" : "347e873ff9702d5783709bed5d4b6b28adfca3ab",
"version" : "4.3.1"
"branch" : "PRISM-10522-risk-i-os-is-added-to-frames-i-os",
"revision" : "de71eed3638875dac5af1d3ca01de6e5704420ea"
}
},
{
Expand Down
3 changes: 2 additions & 1 deletion iOS Example Frame/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ target 'iOS Example Frame' do
use_frameworks!

# Pods for iOS Example Custom
pod 'Frames', '4.3.1'
# pod 'Frames', '4.3.1'
pod 'Frames', :git => 'https://github.com/checkout/frames-ios', :branch => 'PRISM-10522-risk-i-os-is-added-to-frames-i-os'

end

Expand Down

0 comments on commit 2dae4f8

Please sign in to comment.