Skip to content

Commit f9d4ac2

Browse files
committed
DTPP-11 Organizing Demo app folder structure
1 parent 1982e54 commit f9d4ac2

30 files changed

+1830
-30
lines changed

Demo/Demo.xcodeproj/project.pbxproj

Lines changed: 78 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,78 @@
227227
/* End PBXFrameworksBuildPhase section */
228228

229229
/* Begin PBXGroup section */
230+
1001E2AA2CF53C970023A03C /* CardPayments */ = {
231+
isa = PBXGroup;
232+
children = (
233+
3BA56FEA2A9DCBB30081D14F /* CardPaymentViews */,
234+
1001E2AF2CF62EA20023A03C /* CardPaymentsViewModel */,
235+
);
236+
path = CardPayments;
237+
sourceTree = "<group>";
238+
};
239+
1001E2AB2CF53CB30023A03C /* CardVault */ = {
240+
isa = PBXGroup;
241+
children = (
242+
3B43290F2A8FD7FD00C5441A /* CardVaultViews */,
243+
1001E2AE2CF53E540023A03C /* CardVaulthViewModel */,
244+
);
245+
path = CardVault;
246+
sourceTree = "<group>";
247+
};
248+
1001E2AC2CF53CC70023A03C /* PayPalVault */ = {
249+
isa = PBXGroup;
250+
children = (
251+
3B2501052B2679F000903EAB /* VaultViews */,
252+
3BB60B512B1F9EE400A298CF /* PayPalVaultViews */,
253+
1001E2B02CF62EF40023A03C /* VaultViewModel */,
254+
);
255+
path = PayPalVault;
256+
sourceTree = "<group>";
257+
};
258+
1001E2AD2CF53CD70023A03C /* PayPalWebPayments */ = {
259+
isa = PBXGroup;
260+
children = (
261+
3BA56FFF2A9FF6630081D14F /* PayPalWebPaymentsView */,
262+
1001E2B12CF6300F0023A03C /* PayPalWebViewModel */,
263+
);
264+
path = PayPalWebPayments;
265+
sourceTree = "<group>";
266+
};
267+
1001E2AE2CF53E540023A03C /* CardVaulthViewModel */ = {
268+
isa = PBXGroup;
269+
children = (
270+
3B20273E2A89F24E0007907E /* CardVaultViewModel.swift */,
271+
);
272+
path = CardVaulthViewModel;
273+
sourceTree = "<group>";
274+
};
275+
1001E2AF2CF62EA20023A03C /* CardPaymentsViewModel */ = {
276+
isa = PBXGroup;
277+
children = (
278+
3BA56FE62A9DC9D70081D14F /* CardPaymentViewModel.swift */,
279+
3BA56FE82A9DCA520081D14F /* CardPaymentState.swift */,
280+
);
281+
path = CardPaymentsViewModel;
282+
sourceTree = "<group>";
283+
};
284+
1001E2B02CF62EF40023A03C /* VaultViewModel */ = {
285+
isa = PBXGroup;
286+
children = (
287+
3BB60B542B1FA00C00A298CF /* PayPalVaultViewModel.swift */,
288+
3BA0A58A2B1E240300330681 /* VaultViewModel.swift */,
289+
3B2027402A8A72050007907E /* VaultState.swift */,
290+
);
291+
path = VaultViewModel;
292+
sourceTree = "<group>";
293+
};
294+
1001E2B12CF6300F0023A03C /* PayPalWebViewModel */ = {
295+
isa = PBXGroup;
296+
children = (
297+
3BA56FFB2A9FEFE90081D14F /* PayPalWebViewModel.swift */,
298+
);
299+
path = PayPalWebViewModel;
300+
sourceTree = "<group>";
301+
};
230302
3B2501052B2679F000903EAB /* VaultViews */ = {
231303
isa = PBXGroup;
232304
children = (
@@ -263,17 +335,16 @@
263335
path = CardPaymentViews;
264336
sourceTree = "<group>";
265337
};
266-
3BA56FFF2A9FF6630081D14F /* PayPalWebPayments */ = {
338+
3BA56FFF2A9FF6630081D14F /* PayPalWebPaymentsView */ = {
267339
isa = PBXGroup;
268340
children = (
269341
3BA570062AA0DF330081D14F /* PayPalWebButtonsView.swift */,
270342
3BA570022AA053AE0081D14F /* PayPalWebCreateOrderView.swift */,
271343
3BA570002AA052E80081D14F /* PayPalWebPaymentsView.swift */,
272344
BE8117632B07E778009867B9 /* PayPalWebResultView.swift */,
273345
3B6472A62AFAEB3A004745C4 /* PayPalWebTransactionView.swift */,
274-
3BA56FFB2A9FEFE90081D14F /* PayPalWebViewModel.swift */,
275346
);
276-
path = PayPalWebPayments;
347+
path = PayPalWebPaymentsView;
277348
sourceTree = "<group>";
278349
};
279350
3BB60B512B1F9EE400A298CF /* PayPalVaultViews */ = {
@@ -300,13 +371,6 @@
300371
path = CommonComponents;
301372
sourceTree = "<group>";
302373
};
303-
53B9E8E828C93B2B00719239 /* Helpers */ = {
304-
isa = PBXGroup;
305-
children = (
306-
);
307-
path = Helpers;
308-
sourceTree = "<group>";
309-
};
310374
805AB84C26B87A87003BEE0D /* Frameworks */ = {
311375
isa = PBXGroup;
312376
children = (
@@ -350,17 +414,19 @@
350414
isa = PBXGroup;
351415
children = (
352416
806C7A812C000626000E85E8 /* Demo.entitlements */,
353-
53B9E8E828C93B2B00719239 /* Helpers */,
354417
806F1E4126B85369007A60E6 /* Assets.xcassets */,
355418
BED0422F2710833100C80954 /* Card */,
356419
BECD849E27036D95007CCAE4 /* DemoSettings */,
357420
BEDE3048275EA31800D275FD /* Extensions */,
358421
806F1E4626B85369007A60E6 /* Info.plist */,
359422
80921C1C2710A0720040D76F /* LaunchScreen.storyboard */,
423+
1001E2AD2CF53CD70023A03C /* PayPalWebPayments */,
424+
1001E2AC2CF53CC70023A03C /* PayPalVault */,
425+
1001E2AB2CF53CB30023A03C /* CardVault */,
426+
1001E2AA2CF53C970023A03C /* CardPayments */,
360427
80F33CEB26F8E799006811B1 /* Models */,
361428
BE1766B526FA562B007EF438 /* Networking */,
362429
BEDE3047275E998700D275FD /* SwiftUIComponents */,
363-
BE4876A827567D4200802EAF /* ViewModels */,
364430
3BCCFE482A9D96CA00C5102F /* DemoApp.swift */,
365431
);
366432
path = Demo;
@@ -411,19 +477,6 @@
411477
path = Networking;
412478
sourceTree = "<group>";
413479
};
414-
BE4876A827567D4200802EAF /* ViewModels */ = {
415-
isa = PBXGroup;
416-
children = (
417-
3B20273E2A89F24E0007907E /* CardVaultViewModel.swift */,
418-
3BA0A58A2B1E240300330681 /* VaultViewModel.swift */,
419-
3B2027402A8A72050007907E /* VaultState.swift */,
420-
3BA56FE62A9DC9D70081D14F /* CardPaymentViewModel.swift */,
421-
3BA56FE82A9DCA520081D14F /* CardPaymentState.swift */,
422-
3BB60B542B1FA00C00A298CF /* PayPalVaultViewModel.swift */,
423-
);
424-
path = ViewModels;
425-
sourceTree = "<group>";
426-
};
427480
BECD849E27036D95007CCAE4 /* DemoSettings */ = {
428481
isa = PBXGroup;
429482
children = (
@@ -446,12 +499,7 @@
446499
BEDE3047275E998700D275FD /* SwiftUIComponents */ = {
447500
isa = PBXGroup;
448501
children = (
449-
3B2501052B2679F000903EAB /* VaultViews */,
450-
3BB60B512B1F9EE400A298CF /* PayPalVaultViews */,
451-
3BA56FFF2A9FF6630081D14F /* PayPalWebPayments */,
452-
3BA56FEA2A9DCBB30081D14F /* CardPaymentViews */,
453502
3BCCFE472A9D962E00C5102F /* CommonComponents */,
454-
3B43290F2A8FD7FD00C5441A /* CardVaultViews */,
455503
CB9ED44D28411B110081F4DE /* SwiftUIPaymentButtonDemo.swift */,
456504
3BCCFE4A2A9D985F00C5102F /* FeatureSelectionView.swift */,
457505
BE8117672B080472009867B9 /* CurrentState.swift */,
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import SwiftUI
2+
3+
struct CardApprovalResultView: View {
4+
5+
@ObservedObject var cardPaymentViewModel: CardPaymentViewModel
6+
7+
var body: some View {
8+
switch cardPaymentViewModel.state.approveResultResponse {
9+
case .idle, .loading:
10+
EmptyView()
11+
case .loaded(let approvalResult):
12+
getSuccessView(approvalResult: approvalResult)
13+
case .error(let errorMessage):
14+
ErrorView(errorMessage: errorMessage)
15+
}
16+
}
17+
18+
func getSuccessView(approvalResult: CardPaymentState.CardResult) -> some View {
19+
VStack(spacing: 16) {
20+
HStack {
21+
Text("Card Approval Result")
22+
.font(.system(size: 20))
23+
Spacer()
24+
}
25+
LeadingText("ID", weight: .bold)
26+
LeadingText("\(approvalResult.id)")
27+
if let status = approvalResult.status {
28+
LeadingText("Order Status", weight: .bold)
29+
LeadingText("\(status)")
30+
}
31+
LeadingText("didAttemptThreeDSecureAuthentication", weight: .bold)
32+
LeadingText("\(approvalResult.didAttemptThreeDSecureAuthentication)")
33+
}
34+
.frame(maxWidth: .infinity)
35+
.padding()
36+
.background(
37+
RoundedRectangle(cornerRadius: 10)
38+
.stroke(.gray, lineWidth: 2)
39+
.padding(5)
40+
)
41+
}
42+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import SwiftUI
2+
3+
struct CardOrderActionButton: View {
4+
5+
let intent: Intent
6+
let orderID: String
7+
let selectedMerchantIntegration: MerchantIntegration
8+
9+
@ObservedObject var cardPaymentViewModel: CardPaymentViewModel
10+
11+
var body: some View {
12+
ZStack {
13+
Button("\(intent.rawValue)") {
14+
completeOrder()
15+
}
16+
.buttonStyle(RoundedBlueButtonStyle())
17+
.padding()
18+
19+
if .loading == cardPaymentViewModel.state.authorizedOrderResponse ||
20+
.loading == cardPaymentViewModel.state.capturedOrderResponse {
21+
CircularProgressView()
22+
}
23+
}
24+
}
25+
26+
private func completeOrder() {
27+
if intent == .capture {
28+
Task {
29+
do {
30+
try await cardPaymentViewModel.captureOrder(
31+
orderID: orderID,
32+
selectedMerchantIntegration: selectedMerchantIntegration
33+
)
34+
print("Order Captured. ID: \(cardPaymentViewModel.state.capturedOrder?.id ?? "")")
35+
} catch {
36+
print("Error capturing order: \(error.localizedDescription)")
37+
}
38+
}
39+
} else {
40+
Task {
41+
do {
42+
try await cardPaymentViewModel.authorizeOrder(
43+
orderID: orderID,
44+
selectedMerchantIntegration: selectedMerchantIntegration
45+
)
46+
print("Order Authorized. ID: \(cardPaymentViewModel.state.authorizedOrder?.id ?? "")")
47+
} catch {
48+
print("Error authorizing order: \(error.localizedDescription)")
49+
}
50+
}
51+
}
52+
}
53+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import SwiftUI
2+
import CardPayments
3+
import CorePayments
4+
5+
struct CardOrderApproveView: View {
6+
7+
let cardSections: [CardSection] = [
8+
CardSection(title: "Successful Authentication Visa", numbers: ["4868 7194 6070 7704"]),
9+
CardSection(title: "Vault with Purchase (no 3DS)", numbers: ["4000 0000 0000 0002"]),
10+
CardSection(title: "Step up", numbers: ["5314 6090 4083 0349"]),
11+
CardSection(title: "Frictionless - LiabilityShift Possible", numbers: ["4005 5192 0000 0004"]),
12+
CardSection(title: "Frictionless - LiabilityShift NO", numbers: ["4020 0278 5185 3235"]),
13+
CardSection(title: "No Challenge", numbers: ["4111 1111 1111 1111"])
14+
]
15+
let orderID: String
16+
17+
@ObservedObject var cardPaymentViewModel: CardPaymentViewModel
18+
@State private var cardNumberText: String = "4111 1111 1111 1111"
19+
@State private var expirationDateText: String = "01 / 25"
20+
@State private var cvvText: String = "123"
21+
22+
var body: some View {
23+
ScrollView {
24+
ScrollViewReader { scrollView in
25+
VStack {
26+
VStack(spacing: 16) {
27+
HStack {
28+
Text("Enter Card Information")
29+
.font(.system(size: 20))
30+
Spacer()
31+
}
32+
33+
CardFormView(
34+
cardSections: cardSections,
35+
cardNumberText: $cardNumberText,
36+
expirationDateText: $expirationDateText,
37+
cvvText: $cvvText
38+
)
39+
40+
let card = Card.createCard(
41+
cardNumber: cardNumberText,
42+
expirationDate: expirationDateText,
43+
cvv: cvvText
44+
)
45+
46+
Picker("SCA", selection: $cardPaymentViewModel.state.scaSelection) {
47+
Text(SCA.scaWhenRequired.rawValue).tag(SCA.scaWhenRequired)
48+
Text(SCA.scaAlways.rawValue).tag(SCA.scaAlways)
49+
}
50+
.pickerStyle(SegmentedPickerStyle())
51+
.frame(height: 50)
52+
53+
ZStack {
54+
Button("Approve Order") {
55+
Task {
56+
do {
57+
await cardPaymentViewModel.checkoutWith(
58+
card: card,
59+
orderID: orderID,
60+
sca: cardPaymentViewModel.state.scaSelection
61+
)
62+
}
63+
}
64+
}
65+
.buttonStyle(RoundedBlueButtonStyle())
66+
if case .loading = cardPaymentViewModel.state.approveResultResponse {
67+
CircularProgressView()
68+
}
69+
}
70+
}
71+
.padding()
72+
.background(
73+
RoundedRectangle(cornerRadius: 10)
74+
.stroke(.gray, lineWidth: 2)
75+
.padding(5)
76+
)
77+
CardApprovalResultView(cardPaymentViewModel: cardPaymentViewModel)
78+
if cardPaymentViewModel.state.approveResult != nil {
79+
NavigationLink {
80+
CardPaymentOrderCompletionView(orderID: orderID, cardPaymentViewModel: cardPaymentViewModel)
81+
} label: {
82+
Text("Complete Order Transaction")
83+
}
84+
.buttonStyle(RoundedBlueButtonStyle())
85+
.padding()
86+
}
87+
Text("")
88+
.id("bottomView")
89+
Spacer()
90+
}
91+
.onChange(of: cardPaymentViewModel.state) { _ in
92+
withAnimation {
93+
scrollView.scrollTo("bottomView")
94+
}
95+
}
96+
}
97+
}
98+
}
99+
}

0 commit comments

Comments
 (0)