Skip to content

Commit

Permalink
refactor current state; add back in OrderStatus; fix bug with ErrorView
Browse files Browse the repository at this point in the history
  • Loading branch information
jaxdesmarais committed Dec 4, 2023
1 parent af04b83 commit 518e8ec
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 37 deletions.
4 changes: 1 addition & 3 deletions Demo/Demo/SwiftUIComponents/CurrentState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import Foundation
enum CurrentState: Equatable {
case idle
case loading
case orderSuccess
case orderApproved
case transactionSuccess
case success
case error(message: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ struct PayPalWebButtonsView: View {
.padding(5)
)

if payPalWebViewModel.checkoutResult != nil {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel)
if payPalWebViewModel.checkoutResult != nil && payPalWebViewModel.state == .success {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel, status: .approved)
NavigationLink {
PayPalWebTransactionView(payPalWebViewModel: payPalWebViewModel)
.navigationTitle("Complete Transaction")
Expand All @@ -40,6 +40,8 @@ struct PayPalWebButtonsView: View {
.navigationViewStyle(StackNavigationViewStyle())
.buttonStyle(RoundedBlueButtonStyle())
.padding()
} else if case .error = payPalWebViewModel.state {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel, status: .error)
}
Spacer()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ struct PayPalWebPaymentsView: View {
ScrollView {
VStack(spacing: 16) {
PayPalWebCreateOrderView(payPalWebViewModel: payPalWebViewModel)
if payPalWebViewModel.order != nil {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel)
if payPalWebViewModel.createOrderResult != nil && payPalWebViewModel.state == .success {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel, status: .created)
NavigationLink {
PayPalWebButtonsView(payPalWebViewModel: payPalWebViewModel)
.navigationTitle("Checkout with PayPal")
Expand All @@ -18,6 +18,8 @@ struct PayPalWebPaymentsView: View {
}
.buttonStyle(RoundedBlueButtonStyle())
.padding()
} else if case .error = payPalWebViewModel.state {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel, status: .error)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import SwiftUI

enum OrderStatus {
case created
case approved
case completed
case error
}

struct PayPalWebResultView: View {

@ObservedObject var payPalWebViewModel: PayPalWebViewModel

var status: OrderStatus

var body: some View {
switch payPalWebViewModel.state {
case .idle, .loading:
EmptyView()
case .orderSuccess, .orderApproved, .transactionSuccess:
PayPalWebStatusView(payPalWebViewModel: payPalWebViewModel)
case .success:
PayPalWebStatusView(status: status, payPalWebViewModel: payPalWebViewModel)
case .error(let errorMessage):
ErrorView(errorMessage: errorMessage)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,40 @@ import SwiftUI

struct PayPalWebStatusView: View {

var status: OrderStatus
var payPalWebViewModel: PayPalWebViewModel

var body: some View {
VStack(spacing: 16) {
switch payPalWebViewModel.state {
case .orderSuccess:
switch status {
case .created:
HStack {
Text("Order Created")
.font(.system(size: 20))
Spacer()
}
if let order = payPalWebViewModel.order {
if let order = payPalWebViewModel.createOrderResult {
LeadingText("Order ID", weight: .bold)
LeadingText("\(order.id)")
LeadingText("Status", weight: .bold)
LeadingText("\(order.status)")
}
case .orderApproved:
case .approved:
HStack {
Text("Order Approved")
.font(.system(size: 20))
Spacer()
}
if let order = payPalWebViewModel.order {
if let order = payPalWebViewModel.createOrderResult {
LeadingText("Intent", weight: .bold)
LeadingText("\(payPalWebViewModel.intent)")
LeadingText("Order ID", weight: .bold)
LeadingText("\(order.id)")
LeadingText("Payer ID", weight: .bold)
LeadingText("\(payPalWebViewModel.checkoutResult?.payerID ?? "")")
}
case .transactionSuccess:
if let order = payPalWebViewModel.order {
case .completed:
if let order = payPalWebViewModel.transactionResult {
HStack {
Text("Order \(payPalWebViewModel.intent.rawValue.capitalized)d")
.font(.system(size: 20))
Expand All @@ -45,17 +46,17 @@ struct PayPalWebStatusView: View {
LeadingText("Status", weight: .bold)
LeadingText("\(order.status)")

if let emailAddress = payPalWebViewModel.order?.paymentSource?.paypal?.emailAddress {
if let emailAddress = order.paymentSource?.paypal?.emailAddress {
LeadingText("Email", weight: .bold)
LeadingText("\(emailAddress)")
}

if let vaultID = payPalWebViewModel.order?.paymentSource?.paypal?.attributes?.vault.id {
if let vaultID = order.paymentSource?.paypal?.attributes?.vault.id {
LeadingText("Vault ID / Payment Token", weight: .bold)
LeadingText("\(vaultID)")
}

if let customerID = payPalWebViewModel.order?.paymentSource?.paypal?.attributes?.vault.customer.id {
if let customerID = order.paymentSource?.paypal?.attributes?.vault.customer.id {
LeadingText("Customer ID", weight: .bold)
LeadingText("\(customerID)")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct PayPalWebTransactionView: View {
ScrollView {
ScrollViewReader { scrollView in
VStack {
PayPalWebStatusView(payPalWebViewModel: payPalWebViewModel)
PayPalWebStatusView(status: .approved, payPalWebViewModel: payPalWebViewModel)
ZStack {
Button("\(payPalWebViewModel.intent.rawValue.capitalized) Order") {
Task {
Expand All @@ -27,12 +27,14 @@ struct PayPalWebTransactionView: View {
}
}

if payPalWebViewModel.state == .transactionSuccess {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel)
if payPalWebViewModel.transactionResult != nil && payPalWebViewModel.state == .success {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel, status: .completed)
.id("bottomView")
} else if case .error = payPalWebViewModel.state {
PayPalWebResultView(payPalWebViewModel: payPalWebViewModel, status: .error)
}
}
.onChange(of: payPalWebViewModel.order) { _ in
.onChange(of: payPalWebViewModel.transactionResult) { _ in
withAnimation {
scrollView.scrollTo("bottomView")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {

@Published var state: CurrentState = .idle
@Published var intent: Intent = .authorize
@Published var order: Order?
@Published var createOrderResult: Order?
@Published var transactionResult: Order?
@Published var checkoutResult: PayPalWebCheckoutResult?

var payPalWebCheckoutClient: PayPalWebCheckoutClient?
var orderID: String?

let configManager = CoreConfigManager(domain: "PayPalWeb Payments")

Expand Down Expand Up @@ -44,8 +46,12 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
selectedMerchantIntegration: DemoSettings.merchantIntegration
)

updateOrder(order)
updateState(.orderSuccess)
self.orderID = order.id

DispatchQueue.main.async {
self.createOrderResult = order
}
updateState(.success)
print("✅ fetched orderID: \(order.id) with status: \(order.status)")
} catch {
updateState(.error(message: error.localizedDescription))
Expand All @@ -63,7 +69,7 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
return
}

if let orderID = order?.id {
if let orderID {
let payPalRequest = PayPalWebCheckoutRequest(orderID: orderID, fundingSource: funding)
payPalWebCheckoutClient.start(request: payPalRequest)
}
Expand All @@ -86,23 +92,19 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
do {
updateState(.loading)

if let orderID = order?.id {
if let orderID {
let order = try await DemoMerchantAPI.sharedService.completeOrder(intent: intent, orderID: orderID)
updateOrder(order)
updateState(.transactionSuccess)
DispatchQueue.main.async {
self.transactionResult = order
}
updateState(.success)
}
} catch {
updateState(.error(message: error.localizedDescription))
print("Error with \(intent) order: \(error.localizedDescription)")
}
}

private func updateOrder(_ order: Order) {
DispatchQueue.main.async {
self.order = order
}
}

private func updateState(_ state: CurrentState) {
DispatchQueue.main.async {
self.state = state
Expand All @@ -115,7 +117,7 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
_ payPalClient: PayPalWebCheckoutClient,
didFinishWithResult result: PayPalWebCheckoutResult
) {
updateState(.orderApproved)
updateState(.success)
checkoutResult = result
}

Expand Down

0 comments on commit 518e8ec

Please sign in to comment.