Skip to content

Commit f3b8fc0

Browse files
authored
v2 migration guide (#295)
* v2 migration guide * just cocoapods or SPM * fix typos * minor spacing changes * Update with simplified cancel errors * Steven PR feedback - diff to render green/red * include removal of delegate methods in delete block * update with cardClient threeDSecureCanceled error * change to threeDSecureCanceled in migration steps * add comment highlighting cancellation errors * typo fix * clarify separating cancel cases in errors * revert cancel handling instructions * add changes for cancellation helper methods * fix typo in PayPalError.isCheckoutCanceled * Steven PR feedback
1 parent 319894d commit f3b8fc0

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed

v2_MIGRATION_GUIDE.md

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Migrating from Delegates to Completion Handlers
2+
3+
## Overview
4+
Version 2.0 of the SDK transitions from delgate-based flows to completion handler-based flows. This change simplifies the integration and provides better compatibility with modern async/await patterns.
5+
6+
### Key Changes
7+
8+
### Important Change: Cancellation Handling
9+
In v2.0, cancellations (e.g., 3DS cancellations, PayPal web flow cancellations) are now returned as errors rather than as separate delegate methods. There are new helper static functions, to help you discern threeDSecure cancellation errors and PayPal web flow cancellation errors.
10+
- `CardError.threeDSecureCanceled(Error)` will return true for 3DS cancellation errors received during card payment or card vaulting flows.
11+
- `PayPalError.isCheckoutCanceled(Error)` will return true for user cancellation during PayPalWebCheckout session.
12+
- `PayPalError.isVaultCanceled(Error)` will return true for user cancellation during PayPal vault session.
13+
14+
### CardClient Changes
15+
16+
```swift
17+
// Old Delgate-based
18+
class MyViewController: CardDelegate {
19+
func setupPayment() {
20+
let cardClient = CardClient(config: config)
21+
cardClient.delegate = self
22+
cardClient.approveOrder(request: cardRequest)
23+
}
24+
25+
func card(_ cardClient: CardClient, didFinishWithResult result: CardResult) {
26+
// Handle success
27+
}
28+
29+
func card(_ cardClient: CardClient, didFinishWithError error: Error) {
30+
// Handle error
31+
}
32+
33+
func cardDidCancel(_ cardClient: CardClient) {
34+
// Handle cancellation
35+
}
36+
}
37+
38+
// New (Completion-based)
39+
class MyViewController {
40+
func setupPayment() {
41+
let cardClient = CardClient(config: config)
42+
cardClient.approveOrder(request: cardRequest) { [weak self] result, error in
43+
if let error = error {
44+
// if threeDSecure is canceled by user
45+
if CardError.isThreeDSecureCanceled(error) {
46+
// handle cancel error
47+
} else {
48+
// handle other errors
49+
}
50+
return
51+
}
52+
if let result = result {
53+
// handle success
54+
}
55+
}
56+
}
57+
}
58+
```
59+
60+
### PayPalWebCheckoutClient Changes
61+
62+
```Swift
63+
// Old (Delegate-based)
64+
class MyViewController: PayPalWebCheckoutDelegate {
65+
func startPayPalFlow() {
66+
let payPalClient = PayPalWebCheckoutClient(config: config)
67+
payPalClient.delegate = self
68+
payPalClient.approveOrder(request: paypalRequest)
69+
}
70+
71+
func payPal(_ payPalClient: PayPalWebCheckoutClient, didFinishWithResult result: PayPalWebCheckoutResult) {
72+
// Handle success
73+
}
74+
75+
func payPal(_ payPalClient: PayPalWebCheckoutClient, didFinishWithError error: Error) {
76+
// Handle error
77+
}
78+
79+
func payPalDidCancel(_ payPalClient: PayPalCheckoutClient) {
80+
// Handle cancellation
81+
}
82+
}
83+
84+
// New (Completion-based)
85+
class MyViewController {
86+
func setupPayment() {
87+
let payPalClient = PayPalWebCheckoutClient(config: config)
88+
payPalClient.start(request: paypalRequest) { [weak self] result, error in
89+
if let error = error {
90+
// if PayPal webflow is canceled by user
91+
if PayPalError.isCheckoutCanceled(error) {
92+
// handle cancel error
93+
} else {
94+
// handle all other errors
95+
}
96+
return
97+
}
98+
if let result = result {
99+
// handle success
100+
}
101+
}
102+
}
103+
}
104+
```
105+
106+
## Async/Await
107+
The SDK now provides async/await support, offering a more concise way to handle asynchronous operations.
108+
109+
### CardClient
110+
```swift
111+
class MyViewController {
112+
func setupPayment() async {
113+
let cardClient = CardClient(config: config)
114+
do {
115+
let result = try await cardClient.approveOrder(request: cardRequest)
116+
// payment successful
117+
handleSuccess(result)
118+
} catch {
119+
handleError(error)
120+
}
121+
}
122+
}
123+
```
124+
125+
### PayPalWebCheckoutClient
126+
```swift
127+
class MyViewController {
128+
func startPayPalFlow() async {
129+
let payPalClient = PayPalWebCheckoutClient(config: config)
130+
do {
131+
let result = try await payPalClient.start(request: paypalRequest)
132+
// Payment successful
133+
handleSuccess(result)
134+
} catch {
135+
handleError()
136+
}
137+
}
138+
}
139+
```
140+
141+
## Migration Steps
142+
143+
### 1. Update SDK Version
144+
- Update your dependency manager (CocoaPods or SPM) to the latest SDK version
145+
146+
### 2. Remove Delegate Implementation
147+
```diff
148+
// Remove delegate protocol conformance
149+
- class MyViewController: CardDelegate {
150+
+ class MyViewController {
151+
152+
// Remove delegate property assignment
153+
-cardClient.delegate = self
154+
155+
// Remove delegate methods
156+
- func card(_ cardClient: CardClient, didFinishWithResult result: CardResult) {
157+
- func card(_ cardClient: CardClient, didFinishWithError error: Error) {
158+
- func cardDidCancel(_ cardClient: CardClient ) {
159+
```
160+
161+
### 3. Update SDK Flow Implementation
162+
163+
Option 1: Using completion handlers
164+
```swift
165+
func processPayment() {
166+
showLoadingIndicator()
167+
168+
cardClient.approveOrder(request: cardRequest) { [weak self] result, error in
169+
guard let self = self else { return }
170+
removeLoadingIndicator()
171+
172+
if let error = error {
173+
handleError()
174+
return
175+
}
176+
177+
if let result = result {
178+
handleSuccess(result)
179+
}
180+
}
181+
}
182+
```
183+
Option 2: Using async/await
184+
```swift
185+
func processPayment() async {
186+
showLoadingIndicator()
187+
defer { removeLoadingIndicator() }
188+
189+
do {
190+
let result = try await cardClient.approveOrder(request: cardRequest)
191+
handleSuccess(result)
192+
} catch {
193+
handleError()
194+
}
195+
}
196+
```

0 commit comments

Comments
 (0)