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

Make the CVV recapture flag available on Headless #828

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a7768ba
swiftlint --fix --format
BorisNikolic Mar 18, 2024
4d5523d
Fix cyclomatic_complexity warnings and error
BorisNikolic Mar 18, 2024
c40fe5d
Fix all file length warnings
BorisNikolic Mar 18, 2024
2433ce6
Fix all function_body_length warnings and errors
BorisNikolic Mar 18, 2024
3db73c9
Fix all type_body_length warnings and errors
BorisNikolic Mar 18, 2024
1b320e9
Alter line_length rule and update all violations
BorisNikolic Mar 18, 2024
f51da9c
Trigger danger for new swiftlint comments
BorisNikolic Mar 18, 2024
61596d7
Trigger danger for new swiftlint comments
BorisNikolic Mar 18, 2024
6b635a5
Trigger danger for new swiftlint comments
BorisNikolic Mar 19, 2024
036df87
Finish UI implementation
BorisNikolic Feb 29, 2024
f11f9e7
Implement MVVM design pattern, update flow
BorisNikolic Mar 5, 2024
b88debe
Fix card network image rendering
BorisNikolic Mar 5, 2024
7532a93
Treat Localizable.strings as textual file
BorisNikolic Mar 13, 2024
f39f49b
Update wording
BorisNikolic Mar 13, 2024
a1918d8
Add localized strings
BorisNikolic Mar 18, 2024
36ec886
reset .swiftlint.yml
BorisNikolic Mar 19, 2024
e955d46
Add UNIT tests
BorisNikolic Mar 19, 2024
311f739
Handle backend flag for CVV recapture
BorisNikolic Mar 19, 2024
b62bf05
Remove testing headers
BorisNikolic Mar 25, 2024
5cb11cf
Merge branch 'master' into bn/cvv-recapture-drop-in
BorisNikolic Mar 25, 2024
8f61ef3
Refactor function to multiple smaller ones
BorisNikolic Mar 25, 2024
c838977
Make the CVV recapture flag available on Headless
BorisNikolic Mar 25, 2024
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
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.strings diff
8 changes: 6 additions & 2 deletions Debug App/Primer.io Debug App.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@
A1536BAD2AEBEC3A0087DDC0 /* NolPayPhoneMetadataServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1536BAC2AEBEC3A0087DDC0 /* NolPayPhoneMetadataServiceTests.swift */; };
A1536BAF2AEC0A6D0087DDC0 /* NolTestsMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1536BAE2AEC0A6D0087DDC0 /* NolTestsMocks.swift */; };
A1585C752ACDAA700014F0B9 /* NolPayLinkedCardsComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1585C742ACDAA700014F0B9 /* NolPayLinkedCardsComponentTests.swift */; };
A19CB17B2BAA129900DB4326 /* CVVRecaptureViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A19CB17A2BAA129900DB4326 /* CVVRecaptureViewModelTests.swift */; };
A19EF5632B20E22E00A72F60 /* .swiftlint.yml in Resources */ = {isa = PBXBuildFile; fileRef = A19EF5622B20E22E00A72F60 /* .swiftlint.yml */; };
A1A3D0F32AD5585A00F7D8C9 /* NolPayUnlinkCardComponentTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A3D0F22AD5585A00F7D8C9 /* NolPayUnlinkCardComponentTest.swift */; };
A1A3D0F52AD56BE300F7D8C9 /* NolPayPaymentComponentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1A3D0F42AD56BE300F7D8C9 /* NolPayPaymentComponentTests.swift */; };
Expand Down Expand Up @@ -129,7 +130,7 @@
E6F85ECD80B64754E7A6D35E /* RawDataManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C7C082270CF1C6B7810F9B3 /* RawDataManagerTests.swift */; };
EA7FAA4F8476BD3711D628CB /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B18D7E7738BF86467B0F1465 /* Images.xcassets */; };
F02F496FD20B5291C044F62C /* MerchantResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00E3C8FE62D22147335F2455 /* MerchantResultViewController.swift */; };
F03699592AC2E63700E4179D /* BuildFile in Sources */ = {isa = PBXBuildFile; };
F03699592AC2E63700E4179D /* (null) in Sources */ = {isa = PBXBuildFile; };
F08F63D82B9B5A7C006EF9A9 /* SessionConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08F63D72B9B5A7C006EF9A9 /* SessionConfiguration.swift */; };
F08F63DA2B9B5BC5006EF9A9 /* AppetizeConfigProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08F63D92B9B5BC5006EF9A9 /* AppetizeConfigProvider.swift */; };
F08F63DC2B9F27B0006EF9A9 /* MetadataParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F08F63DB2B9F27B0006EF9A9 /* MetadataParser.swift */; };
Expand Down Expand Up @@ -284,6 +285,7 @@
A1536BAE2AEC0A6D0087DDC0 /* NolTestsMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NolTestsMocks.swift; sourceTree = "<group>"; };
A1585C742ACDAA700014F0B9 /* NolPayLinkedCardsComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NolPayLinkedCardsComponentTests.swift; sourceTree = "<group>"; };
A1604A656AF654D7422A2A5E /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Main.strings; sourceTree = "<group>"; };
A19CB17A2BAA129900DB4326 /* CVVRecaptureViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CVVRecaptureViewModelTests.swift; sourceTree = "<group>"; };
A19EF5622B20E22E00A72F60 /* .swiftlint.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.yaml; path = .swiftlint.yml; sourceTree = "<group>"; };
A1A3D0F22AD5585A00F7D8C9 /* NolPayUnlinkCardComponentTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NolPayUnlinkCardComponentTest.swift; sourceTree = "<group>"; };
A1A3D0F42AD56BE300F7D8C9 /* NolPayPaymentComponentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NolPayPaymentComponentTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -509,6 +511,7 @@
EEB1E1B37192BF739461AFF1 /* PrimerRawCardDataManagerTests.swift */,
B266F9E1651BD20E45DCCF68 /* PrimerRawRetailerDataTests.swift */,
049A055F2B4C191D002CEEBA /* NativeUIManagerTests.swift */,
A19CB17A2BAA129900DB4326 /* CVVRecaptureViewModelTests.swift */,
);
path = Primer;
sourceTree = "<group>";
Expand Down Expand Up @@ -1091,6 +1094,7 @@
3BB02CA24B6B3EF458326B7D /* Networking.swift in Sources */,
25FA73D4BBA89962663B5378 /* Mocks.swift in Sources */,
2E0D85B7343377F1319902AD /* MockPaymentMethodTokenizationViewModel.swift in Sources */,
A19CB17B2BAA129900DB4326 /* CVVRecaptureViewModelTests.swift in Sources */,
E11F473D2B0694C50091C31F /* PrimerHeadlessFormWithRedirectManagerTests.swift in Sources */,
161D4BE3FFD5E4A60F4461F0 /* CreateResumePaymentService.swift in Sources */,
C6D7F7ECFD35B3DC3AFD6CB2 /* PayPalService.swift in Sources */,
Expand All @@ -1099,7 +1103,7 @@
583EBAA90902121CEA479416 /* VaultService.swift in Sources */,
961B5D18058EF4CFCD0185AE /* MockVaultCheckoutViewModel.swift in Sources */,
622A605DDEA98D981670B53F /* DropInUI_TokenizationViewModelTests.swift in Sources */,
F03699592AC2E63700E4179D /* BuildFile in Sources */,
F03699592AC2E63700E4179D /* (null) in Sources */,
208CA849F3187C2DA63CC17B /* HUC_TokenizationViewModelTests.swift in Sources */,
213196DEDF2A3A84037ED884 /* PollingModuleTests.swift in Sources */,
04F6EF742AE6A06200115D05 /* AnalyticsEventsTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"repositoryURL": "https://github.com/primer-io/primer-klarna-sdk-ios",
"state": {
"branch": null,
"revision": "146d9ae8f7accc1ad7b64b2a455106d54914edef",
"version": "1.1.0"
"revision": "f13260c24a900f28e21bafd213c22191e6280e86",
"version": "1.0.4"
}
},
{
Expand Down
25 changes: 20 additions & 5 deletions Debug App/Resources/Localized Views/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@
<rect key="frame" x="0.0" y="163" width="414" height="561"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="40" translatesAutoresizingMaskIntoConstraints="NO" id="Yce-hH-uhX">
<rect key="frame" x="20" y="20" width="374" height="3686"/>
<rect key="frame" x="20" y="20" width="374" height="3737"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="oCT-9e-d89" userLabel="Environment Stack View">
<rect key="frame" x="0.0" y="0.0" width="374" height="420.5"/>
Expand Down Expand Up @@ -380,7 +380,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="f7f-4e-ZPN" userLabel="SDK Settings Stack View">
<rect key="frame" x="0.0" y="925" width="374" height="505.5"/>
<rect key="frame" x="0.0" y="925" width="374" height="556.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SDK Settings" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HZ9-hO-miI">
<rect key="frame" x="0.0" y="0.0" width="374" height="33.5"/>
Expand Down Expand Up @@ -505,10 +505,24 @@
</switch>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="YZe-Oh-Inv" userLabel="Recapture CVV">
<rect key="frame" x="0.0" y="525.5" width="374" height="31"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Enable CVV Recapture flow" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hxC-Ql-YpN" userLabel="Apply theming">
<rect key="frame" x="0.0" y="0.0" width="318" height="31"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="XZa-6j-T8o">
<rect key="frame" x="325" y="0.0" width="51" height="31"/>
</switch>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Wmb-0A-wCB" userLabel="Order Stack View">
<rect key="frame" x="0.0" y="1470.5" width="374" height="461"/>
<rect key="frame" x="0.0" y="1521.5" width="374" height="461"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Order" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rhW-8E-83f">
<rect key="frame" x="0.0" y="0.0" width="374" height="33.5"/>
Expand Down Expand Up @@ -619,7 +633,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="cka-yb-xqD" userLabel="Customer Stack View">
<rect key="frame" x="0.0" y="1971.5" width="374" height="1565.5"/>
<rect key="frame" x="0.0" y="2022.5" width="374" height="1565.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Customer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3y1-pX-UrW">
<rect key="frame" x="0.0" y="0.0" width="374" height="33.5"/>
Expand Down Expand Up @@ -1020,7 +1034,7 @@
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="32O-OV-0ey" userLabel="Surcharge Group Stack View">
<rect key="frame" x="0.0" y="3577" width="374" height="109"/>
<rect key="frame" x="0.0" y="3628" width="374" height="109"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hmO-CL-ebG">
<rect key="frame" x="0.0" y="0.0" width="374" height="31"/>
Expand Down Expand Up @@ -1154,6 +1168,7 @@
<outlet property="disableErrorScreenSwitch" destination="RC1-bw-dHB" id="8Vu-yw-7ka"/>
<outlet property="disableInitScreenSwitch" destination="9ji-Ev-HnU" id="XJy-Z6-Jjc"/>
<outlet property="disableSuccessScreenSwitch" destination="h2a-FU-Cbb" id="dYl-8C-tNa"/>
<outlet property="enableCVVRecaptureFlowSwitch" destination="XZa-6j-T8o" id="M4Q-x4-pMw"/>
<outlet property="environmentSegmentedControl" destination="ekZ-3s-TxK" id="SsX-7s-JaH"/>
<outlet property="environmentStackView" destination="oCT-9e-d89" id="JnB-93-2Gv"/>
<outlet property="lineItemsStackView" destination="KMj-Qp-rNj" id="gVb-8g-WNx"/>
Expand Down
24 changes: 20 additions & 4 deletions Debug App/Sources/Model/CreateClientToken.swift
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ struct ClientSessionRequestBody {

struct PaymentMethod: Codable {
let vaultOnSuccess: Bool?
let options: PaymentMethodOptionGroup?
var options: PaymentMethodOptionGroup?
let descriptor: String?
let paymentType: String?

Expand Down Expand Up @@ -348,6 +348,7 @@ struct ClientSessionRequestBody {

struct PaymentMethodOptionGroup: Codable {
var KLARNA: PaymentMethodOption?
var PAYMENT_CARD: PaymentMethodOption?

var dictionaryValue: [String: Any]? {
var dic: [String: Any] = [:]
Expand All @@ -356,6 +357,10 @@ struct ClientSessionRequestBody {
dic["KLARNA"] = KLARNA.dictionaryValue
}

if let PAYMENT_CARD = PAYMENT_CARD {
dic["PAYMENT_CARD"] = PAYMENT_CARD.dictionaryValue
}

return dic.keys.count == 0 ? nil : dic
}
}
Expand All @@ -364,15 +369,20 @@ struct ClientSessionRequestBody {
var surcharge: SurchargeOption?
var instalmentDuration: String?
var extraMerchantData: [String: Any]?
var captureVaultedCardCvv: Bool?

enum CodingKeys: CodingKey {
case surcharge, instalmentDuration, extraMerchantData
case surcharge, instalmentDuration, extraMerchantData, captureVaultedCardCvv
}

init(surcharge: SurchargeOption?, instalmentDuration: String?, extraMerchantData: [String: Any]?) {

init(surcharge: SurchargeOption?,
instalmentDuration: String?,
extraMerchantData: [String: Any]?,
captureVaultedCardCvv: Bool?) {
self.surcharge = surcharge
self.instalmentDuration = instalmentDuration
self.extraMerchantData = extraMerchantData
self.captureVaultedCardCvv = captureVaultedCardCvv
}

func encode(to encoder: Encoder) throws {
Expand Down Expand Up @@ -404,6 +414,8 @@ struct ClientSessionRequestBody {
} else {
extraMerchantData = nil
}

captureVaultedCardCvv = try container.decodeIfPresent(Bool.self, forKey: .captureVaultedCardCvv) ?? false
}

var dictionaryValue: [String: Any]? {
Expand All @@ -421,6 +433,10 @@ struct ClientSessionRequestBody {
dic["extraMerchantData"] = extraMerchantData
}

if let captureVaultedCardCvv = captureVaultedCardCvv {
dic["captureVaultedCardCvv"] = captureVaultedCardCvv
}

return dic.keys.count == 0 ? nil : dic
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,16 +87,17 @@ struct MerchantMockDataManager {

static var klarnaPaymentMethod = ClientSessionRequestBody.PaymentMethod(
vaultOnSuccess: nil,
options: paymentOptions,
options: klarnaPaymentOptions,
descriptor: "test-descriptor",
paymentType: nil
)

static var paymentOptions = ClientSessionRequestBody.PaymentMethod.PaymentMethodOptionGroup(
static var klarnaPaymentOptions = ClientSessionRequestBody.PaymentMethod.PaymentMethodOptionGroup(
KLARNA: ClientSessionRequestBody.PaymentMethod.PaymentMethodOption(
surcharge: ClientSessionRequestBody.PaymentMethod.SurchargeOption(amount: 140),
instalmentDuration: "test",
extraMerchantData: extraMerchantData))
extraMerchantData: extraMerchantData,
captureVaultedCardCvv: false))

static var extraMerchantData: [String: Any] = [
"subscription": [
Expand All @@ -115,5 +116,4 @@ struct MerchantMockDataManager {
]
]
]

}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ class MerchantSessionAndSettingsViewController: UIViewController {
@IBOutlet weak var disableSuccessScreenSwitch: UISwitch!
@IBOutlet weak var disableErrorScreenSwitch: UISwitch!
@IBOutlet weak var disableInitScreenSwitch: UISwitch!

@IBOutlet weak var enableCVVRecaptureFlowSwitch: UISwitch!

// MARK: Order Inputs

@IBOutlet weak var currencyTextField: UITextField!
Expand Down Expand Up @@ -416,7 +417,15 @@ class MerchantSessionAndSettingsViewController: UIViewController {
}

clientSession.paymentMethod = MerchantMockDataManager.getPaymentMethod(sessionType: paymentSessionType)

if paymentSessionType == .generic && enableCVVRecaptureFlowSwitch.isOn {
let option = ClientSessionRequestBody.PaymentMethod.PaymentMethodOption(surcharge: nil,
instalmentDuration: nil,
extraMerchantData: nil,
captureVaultedCardCvv: enableCVVRecaptureFlowSwitch.isOn)

let optionGroup = ClientSessionRequestBody.PaymentMethod.PaymentMethodOptionGroup(PAYMENT_CARD: option)
clientSession.paymentMethod?.options = optionGroup
}
if let metadata = metadataTextField.text, !metadata.isEmpty {
clientSession.metadata = MetadataParser().parse(metadata)
}
Expand All @@ -425,6 +434,8 @@ class MerchantSessionAndSettingsViewController: UIViewController {
func populateSessionSettingsFields() {
clientSession = MerchantMockDataManager.getClientSession(sessionType: paymentSessionType)

enableCVVRecaptureFlowSwitch.isOn = clientSession.paymentMethod?.options?.PAYMENT_CARD?.captureVaultedCardCvv == true

currencyTextField.text = clientSession.currencyCode?.code
countryCodeTextField.text = clientSession.order?.countryCode?.rawValue
orderIdTextField.text = clientSession.orderId
Expand Down
2 changes: 1 addition & 1 deletion Debug App/Tests/Unit Tests/Mocks.swift
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class MockPrimerDelegate: PrimerDelegate {
"class": "\(Self.self)",
"function": #function,
"line": "\(#line)"],
diagnosticsId: UUID().uuidString))
diagnosticsId: UUID().uuidString))
return
}
completion(token, nil)
Expand Down
Loading
Loading