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

Error Refactor Spike #300

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,39 @@
# PayPal iOS SDK Release Notes

## unreleased
* Breaking Changes
* PayPalNativePayments
* Remove entire PayPalNativePayments module
* PayPalWebPayments
* Replace delegate pattern with completion handlers and Swift concurrency
* Remove `PayPalWebCheckoutDelegate` and `PayPalVaultDelegate`
* Remove `start(request:)` method that uses delegate callbacks
* Remove `vault(vaultRequest:)` method that uses delegate callbacks
* Add `start(request:completion(PayPalWebCheckoutResult?, CoreSDKError?) -> Void)` to `PayPalWebCheckoutClient`
* Add `vault(vaultRequest:completion(PayPalVaultResult?, CoreSDKError?) -> Void)` to `PayPalWebCheckoutClient`
* Add `start(request:) async throws -> PayPalCheckoutResult`
* Add `vault(vaultRequest:) async throws -> PayPalVaultResult`
* CardPayments
* Replace delegate pattern with completion handlers and Swift concurrency
* Remove `CardDelegate` and `CardVaultDelegate`
* Remove `approveOrder(request:)` method that uses delegate callbacks
* Remove `vault(vaultRequest:)` method that uses delegate callbacks
* Add `approveOrder(request:completion:(CardResult?, CoreSDKError?) -> Void)` to `CardClient`
* Add `vault(request:completion:(CardVaultResult?, CoreSDKError?) -> Void)` to `CardClient`
* Add `approveOrder(request:) async throws -> CardResult`
* Add `vault(vaultRequest:) async throws -> CardVaultResult`
* PayPalWebPayments
* Deprecate `PayPalVaultRequest(url:setupTokenID:)`
* Add `PayPalVaultRequest(setupTokenID:)`
* Rename `PayPalWebCheckoutClientError` to `PayPalError`
* Add `.checkoutCanceledError` and `vaultCanceledError` to `PayPalError`
* Add public static functions `isCheckoutCanceled(Error)` and `isVaultCanceled(Error)` to `PayPalError` to distinguish cancellation errors in PayPal flows.
* Make `PayPalError` public to expose cancellation error handling helpers
* CardPayments
* Rename `CardClientError` to `CardError`
* Add `threeDSecureCanceledError` to `CardError`
* Add public static function `isThreeDSecureCanceled(Error)` to `CardError` to distinguish cancellation error from threeDSecure verification
* Make `CardError` public to expose cancellation error handling helper

## 1.4.0 (2024-07-09)
* PayPalNativePayments (DEPRECATED)
Expand Down
51 changes: 0 additions & 51 deletions Demo/Demo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

99 changes: 0 additions & 99 deletions Demo/Demo/Helpers/OrderRequestHelpers.swift

This file was deleted.

6 changes: 0 additions & 6 deletions Demo/Demo/Models/ProcessOrderParams.swift

This file was deleted.

7 changes: 0 additions & 7 deletions Demo/Demo/Models/ShippingPreference.swift

This file was deleted.

68 changes: 0 additions & 68 deletions Demo/Demo/Models/UpdateOrderParams.swift

This file was deleted.

12 changes: 0 additions & 12 deletions Demo/Demo/Networking/DemoMerchantAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,6 @@ final class DemoMerchantAPI {
return try parse(from: data)
}

/// This function replicates a way a merchant may go about patching an order on their server and is not part of the SDK flow.
/// - Parameters:
/// - updateOrderParams: the parameters to update the order with
/// - Throws: an error explaining why patching the order failed
func updateOrder(_ updateOrderParams: UpdateOrderParams, selectedMerchantIntegration: MerchantIntegration) async throws {
guard let url = buildBaseURL(with: "/orders/" + updateOrderParams.orderID) else {
throw URLResponseError.invalidURL
}
let urlRequest = buildURLRequest(method: "PATCH", url: url, body: updateOrderParams.updateOperations)
_ = try await data(for: urlRequest)
}

/// This function fetches a clientID to initialize any module of the SDK
/// - Parameters:
/// - environment: the current environment
Expand Down
5 changes: 0 additions & 5 deletions Demo/Demo/SwiftUIComponents/FeatureSelectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,6 @@ struct FeatureSelectionView: View {
} label: {
Text("PayPal Vaulting")
}
NavigationLink {
SwiftUINativeCheckoutDemo()
} label: {
Text("Native Checkout")
}
NavigationLink {
SwiftUIPaymentButtonDemo()
} label: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ struct PayPalVaultView: View {
)
SetupTokenResultView(vaultViewModel: paypalVaultViewModel)
if let setupTokenID = paypalVaultViewModel.state.setupToken?.id {
Button("Vault PayPal") {
Task {
await paypalVaultViewModel.vault(setupTokenID: setupTokenID)
ZStack {
Button("Vault PayPal") {
Task {
await paypalVaultViewModel.vault(setupTokenID: setupTokenID)
}
}
.buttonStyle(RoundedBlueButtonStyle())
.padding()
if case .loading = paypalVaultViewModel.state.paypalVaultTokenResponse {
CircularProgressView()
}
}
.buttonStyle(RoundedBlueButtonStyle())
.padding()
}
PayPalVaultResultView(viewModel: paypalVaultViewModel)
if let paypalVaultResult = paypalVaultViewModel.state.paypalVaultToken {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,25 @@ struct PayPalWebButtonsView: View {
Text("Pay Later").tag(PayPalWebCheckoutFundingSource.paylater)
}
.pickerStyle(SegmentedPickerStyle())

switch selectedFundingSource {
case .paypalCredit:
PayPalCreditButton.Representable(color: .black, size: .full) {
payPalWebViewModel.paymentButtonTapped(funding: .paypalCredit)
}
case .paylater:
PayPalPayLaterButton.Representable(color: .silver, edges: .softEdges, size: .full) {
payPalWebViewModel.paymentButtonTapped(funding: .paylater)
ZStack {
switch selectedFundingSource {
case .paypalCredit:
PayPalCreditButton.Representable(color: .black, size: .full) {
payPalWebViewModel.paymentButtonTapped(funding: .paypalCredit)
}
case .paylater:
PayPalPayLaterButton.Representable(color: .silver, edges: .softEdges, size: .full) {
payPalWebViewModel.paymentButtonTapped(funding: .paylater)
}
case .paypal:
PayPalButton.Representable(color: .blue, size: .full) {
payPalWebViewModel.paymentButtonTapped(funding: .paypal)
}
}
case .paypal:
PayPalButton.Representable(color: .blue, size: .full) {
payPalWebViewModel.paymentButtonTapped(funding: .paypal)
if payPalWebViewModel.state == .loading &&
payPalWebViewModel.checkoutResult == nil &&
payPalWebViewModel.orderID != nil {
CircularProgressView()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct PayPalWebCreateOrderView: View {
}
}
.buttonStyle(RoundedBlueButtonStyle())
if payPalWebViewModel.state == .loading && payPalWebViewModel.checkoutResult == nil {
if payPalWebViewModel.state == .loading && payPalWebViewModel.checkoutResult == nil && payPalWebViewModel.orderID == nil {
CircularProgressView()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import CorePayments
import PayPalWebPayments
import FraudProtection

class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
class PayPalWebViewModel: ObservableObject {

@Published var state: CurrentState = .idle
@Published var intent: Intent = .authorize
Expand Down Expand Up @@ -62,16 +62,28 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
func paymentButtonTapped(funding: PayPalWebCheckoutFundingSource) {
Task {
do {
self.updateState(.loading)
payPalWebCheckoutClient = try await getPayPalClient()
payPalWebCheckoutClient?.delegate = self
guard let payPalWebCheckoutClient else {
print("Error initializing PayPalWebCheckoutClient")
return
}

if let orderID {
let payPalRequest = PayPalWebCheckoutRequest(orderID: orderID, fundingSource: funding)
payPalWebCheckoutClient.start(request: payPalRequest)
payPalWebCheckoutClient.start(request: payPalRequest) { result, error in
if let error {
if PayPalError.isCheckoutCanceled(error) {
print("Canceled")
self.updateState(.idle)
} else {
self.updateState(.error(message: error.localizedDescription))
}
} else {
self.updateState(.success)
self.checkoutResult = result
}
}
}
updateState(.success)
} catch {
Expand Down Expand Up @@ -131,22 +143,4 @@ class PayPalWebViewModel: ObservableObject, PayPalWebCheckoutDelegate {
self.state = state
}
}

// MARK: - PayPalWeb Checkout Delegate

func payPal(
_ payPalClient: PayPalWebCheckoutClient,
didFinishWithResult result: PayPalWebCheckoutResult
) {
updateState(.success)
checkoutResult = result
}

func payPal(_ payPalClient: PayPalWebCheckoutClient, didFinishWithError error: CoreSDKError) {
updateState(.error(message: error.localizedDescription))
}

func payPalDidCancel(_ payPalClient: PayPalWebCheckoutClient) {
print("PayPal Checkout Canceled")
}
}
Loading
Loading