Skip to content

Commit e5f8233

Browse files
feat: update accelerated checkouts event handlers to include event parameters
- Update onComplete to pass CheckoutCompletedEvent with order details - Update onFail to pass CheckoutError for better error handling - Rename ApplePay controller properties for clarity (e.g., onComplete → onCheckoutComplete) - Remove ShopifyCheckoutSheetKit namespace prefixes for cleaner code - Ensure thread safety with proper MainActor usage in delegate methods - Update all tests to match new event handler signatures
1 parent d8dfb45 commit e5f8233

File tree

10 files changed

+173
-140
lines changed

10 files changed

+173
-140
lines changed

Sources/ShopifyAcceleratedCheckouts/Wallets/AcceleratedCheckoutButtons.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,15 +136,15 @@ extension AcceleratedCheckoutButtons {
136136
///
137137
/// ```swift
138138
/// AcceleratedCheckoutButtons(cartID: cartId)
139-
/// .onComplete {
140-
/// // Navigate to success screen
141-
/// showSuccessView = true
139+
/// .onComplete { event in
140+
/// // Navigate to success screen with order ID
141+
/// showSuccessView(orderId: event.orderId)
142142
/// }
143143
/// ```
144144
///
145145
/// - Parameter action: The action to perform when checkout succeeds
146146
/// - Returns: A view with the checkout success handler set
147-
public func onComplete(_ action: @escaping () -> Void) -> AcceleratedCheckoutButtons {
147+
public func onComplete(_ action: @escaping (CheckoutCompletedEvent) -> Void) -> AcceleratedCheckoutButtons {
148148
var newView = self
149149
newView.eventHandlers.checkoutDidComplete = action
150150
return newView
@@ -156,15 +156,15 @@ extension AcceleratedCheckoutButtons {
156156
///
157157
/// ```swift
158158
/// AcceleratedCheckoutButtons(cartID: cartId)
159-
/// .onFail {
160-
/// // Show error alert
161-
/// showErrorAlert = true
159+
/// .onFail { error in
160+
/// // Show error alert with details
161+
/// showErrorAlert(error: error)
162162
/// }
163163
/// ```
164164
///
165165
/// - Parameter action: The action to perform when checkout fails
166166
/// - Returns: A view with the checkout error handler set
167-
public func onFail(_ action: @escaping () -> Void) -> AcceleratedCheckoutButtons {
167+
public func onFail(_ action: @escaping (CheckoutError) -> Void) -> AcceleratedCheckoutButtons {
168168
var newView = self
169169
newView.eventHandlers.checkoutDidFail = action
170170
return newView
@@ -205,7 +205,7 @@ extension AcceleratedCheckoutButtons {
205205
/// - Parameter action: The action to determine if recovery should be attempted
206206
/// - Returns: A view with the error recovery handler set
207207
public func onShouldRecoverFromError(
208-
_ action: @escaping (ShopifyCheckoutSheetKit.CheckoutError) -> Bool
208+
_ action: @escaping (CheckoutError) -> Bool
209209
) -> AcceleratedCheckoutButtons {
210210
var newView = self
211211
newView.eventHandlers.shouldRecoverFromError = action
@@ -246,7 +246,7 @@ extension AcceleratedCheckoutButtons {
246246
///
247247
/// - Parameter action: The action to perform when a pixel event is emitted
248248
/// - Returns: A view with the web pixel event handler set
249-
public func onWebPixelEvent(_ action: @escaping (ShopifyCheckoutSheetKit.PixelEvent) -> Void)
249+
public func onWebPixelEvent(_ action: @escaping (PixelEvent) -> Void)
250250
-> AcceleratedCheckoutButtons
251251
{
252252
var newView = self

Sources/ShopifyAcceleratedCheckouts/Wallets/ApplePay/ApplePayButton.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,12 @@ struct Internal_ApplePayButton: View {
121121
self.label = label
122122
self.cornerRadius = cornerRadius
123123
MainActor.assumeIsolated {
124-
controller.onComplete = eventHandlers.checkoutDidComplete
125-
controller.onFail = eventHandlers.checkoutDidFail
126-
controller.onCancel = eventHandlers.checkoutDidCancel
124+
controller.onCheckoutComplete = eventHandlers.checkoutDidComplete
125+
controller.onCheckoutFail = eventHandlers.checkoutDidFail
126+
controller.onCheckoutCancel = eventHandlers.checkoutDidCancel
127127
controller.onShouldRecoverFromError = eventHandlers.shouldRecoverFromError
128-
controller.onClickLink = eventHandlers.checkoutDidClickLink
129-
controller.onWebPixelEvent = eventHandlers.checkoutDidEmitWebPixelEvent
128+
controller.onCheckoutClickLink = eventHandlers.checkoutDidClickLink
129+
controller.onCheckoutWebPixelEvent = eventHandlers.checkoutDidEmitWebPixelEvent
130130
}
131131
}
132132

Sources/ShopifyAcceleratedCheckouts/Wallets/ApplePay/ApplePayViewController.swift

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -54,39 +54,39 @@ protocol PayController: AnyObject {
5454
///
5555
/// Example usage:
5656
/// ```swift
57-
/// applePayViewController.onComplete = { [weak self] in
57+
/// applePayViewController.onCheckoutComplete = { [weak self] event in
5858
/// self?.presentSuccessScreen()
59-
/// self?.logAnalyticsEvent(.checkoutCompleted)
59+
/// self?.logAnalyticsEvent(.checkoutCompleted, orderId: event.orderId)
6060
/// }
6161
/// ```
6262
@MainActor
63-
public var onComplete: (() -> Void)?
63+
public var onCheckoutComplete: ((CheckoutCompletedEvent) -> Void)?
6464

6565
/// Callback invoked when an error occurs during the checkout process.
66-
/// This closure is called on the main thread when the payment fails or is cancelled.
66+
/// This closure is called on the main thread when the payment fails.
6767
///
6868
/// Example usage:
6969
/// ```swift
70-
/// applePayViewController.onFail = { [weak self] in
71-
/// self?.showErrorAlert()
72-
/// self?.logAnalyticsEvent(.checkoutFailed)
70+
/// applePayViewController.onCheckoutFail = { [weak self] error in
71+
/// self?.showErrorAlert(for: error)
72+
/// self?.logAnalyticsEvent(.checkoutFailed, error: error)
7373
/// }
7474
/// ```
7575
@MainActor
76-
public var onFail: (() -> Void)?
76+
public var onCheckoutFail: ((CheckoutError) -> Void)?
7777

7878
/// Callback invoked when the checkout process is cancelled by the user.
7979
/// This closure is called on the main thread when the user dismisses the checkout.
8080
///
8181
/// Example usage:
8282
/// ```swift
83-
/// applePayViewController.onCancel = { [weak self] in
83+
/// applePayViewController.onCheckoutCancel = { [weak self] in
8484
/// self?.resetCheckoutState()
8585
/// self?.logAnalyticsEvent(.checkoutCancelled)
8686
/// }
8787
/// ```
8888
@MainActor
89-
public var onCancel: (() -> Void)?
89+
public var onCheckoutCancel: (() -> Void)?
9090

9191
/// Callback invoked to determine if checkout should recover from an error.
9292
/// This closure is called on the main thread when an error occurs.
@@ -100,33 +100,33 @@ protocol PayController: AnyObject {
100100
/// }
101101
/// ```
102102
@MainActor
103-
public var onShouldRecoverFromError: ((ShopifyCheckoutSheetKit.CheckoutError) -> Bool)?
103+
public var onShouldRecoverFromError: ((CheckoutError) -> Bool)?
104104

105105
/// Callback invoked when the user clicks a link during checkout.
106106
/// This closure is called on the main thread when a link is clicked.
107107
///
108108
/// Example usage:
109109
/// ```swift
110-
/// applePayViewController.onClickLink = { [weak self] url in
110+
/// applePayViewController.onCheckoutClickLink = { [weak self] url in
111111
/// self?.handleExternalLink(url)
112112
/// self?.logAnalyticsEvent(.linkClicked, url: url)
113113
/// }
114114
/// ```
115115
@MainActor
116-
public var onClickLink: ((URL) -> Void)?
116+
public var onCheckoutClickLink: ((URL) -> Void)?
117117

118118
/// Callback invoked when a web pixel event is emitted during checkout.
119119
/// This closure is called on the main thread when pixel events occur.
120120
///
121121
/// Example usage:
122122
/// ```swift
123-
/// applePayViewController.onWebPixelEvent = { [weak self] event in
123+
/// applePayViewController.onCheckoutWebPixelEvent = { [weak self] event in
124124
/// self?.trackPixelEvent(event)
125125
/// self?.logAnalyticsEvent(.pixelFired, event: event)
126126
/// }
127127
/// ```
128128
@MainActor
129-
public var onWebPixelEvent: ((ShopifyCheckoutSheetKit.PixelEvent) -> Void)?
129+
public var onCheckoutWebPixelEvent: ((PixelEvent) -> Void)?
130130

131131
/// Initialization workaround for passing self to ApplePayAuthorizationDelegate
132132
private var __authorizationDelegate: ApplePayAuthorizationDelegate!
@@ -186,7 +186,9 @@ protocol PayController: AnyObject {
186186
return try await handleStorefrontError(error)
187187
} catch {
188188
await authorizationDelegate.transition(to: .terminalError(error: error))
189-
await onFail?()
189+
if let checkoutError = error as? CheckoutError {
190+
await onCheckoutFail?(checkoutError)
191+
}
190192
throw error
191193
}
192194
}
@@ -241,30 +243,41 @@ protocol PayController: AnyObject {
241243

242244
@available(iOS 17.0, *)
243245
extension ApplePayViewController: CheckoutDelegate {
244-
@MainActor func checkoutDidComplete(event _: ShopifyCheckoutSheetKit.CheckoutCompletedEvent) {
245-
onComplete?()
246+
func checkoutDidComplete(event: CheckoutCompletedEvent) {
247+
Task { @MainActor in
248+
self.onCheckoutComplete?(event)
249+
}
246250
}
247251

248-
@MainActor func checkoutDidFail(error _: ShopifyCheckoutSheetKit.CheckoutError) {
249-
onFail?()
252+
func checkoutDidFail(error: CheckoutError) {
253+
Task { @MainActor in
254+
self.onCheckoutFail?(error)
255+
}
250256
}
251257

252-
@MainActor func checkoutDidCancel() {
253-
/// x right button on CSK doesn't dismiss automatically
254-
checkoutViewController?.dismiss(animated: true)
255-
256-
onCancel?()
258+
func checkoutDidCancel() {
259+
Task { @MainActor in
260+
/// x right button on CSK doesn't dismiss automatically
261+
checkoutViewController?.dismiss(animated: true)
262+
self.onCheckoutCancel?()
263+
}
257264
}
258265

259-
@MainActor func shouldRecoverFromError(error: ShopifyCheckoutSheetKit.CheckoutError) -> Bool {
260-
return onShouldRecoverFromError?(error) ?? false
266+
func shouldRecoverFromError(error: CheckoutError) -> Bool {
267+
return MainActor.assumeIsolated {
268+
self.onShouldRecoverFromError?(error) ?? false
269+
}
261270
}
262271

263-
@MainActor func checkoutDidClickLink(url: URL) {
264-
onClickLink?(url)
272+
func checkoutDidClickLink(url: URL) {
273+
Task { @MainActor in
274+
self.onCheckoutClickLink?(url)
275+
}
265276
}
266277

267-
@MainActor func checkoutDidEmitWebPixelEvent(event: ShopifyCheckoutSheetKit.PixelEvent) {
268-
onWebPixelEvent?(event)
278+
func checkoutDidEmitWebPixelEvent(event: PixelEvent) {
279+
Task { @MainActor in
280+
self.onCheckoutWebPixelEvent?(event)
281+
}
269282
}
270283
}

Sources/ShopifyAcceleratedCheckouts/Wallets/ShopPay/ShopPayViewController.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@ import SwiftUI
107107

108108
@available(iOS 17.0, *)
109109
extension ShopPayViewController: CheckoutDelegate {
110-
func checkoutDidComplete(event _: ShopifyCheckoutSheetKit.CheckoutCompletedEvent) {
111-
eventHandlers.checkoutDidComplete?()
110+
func checkoutDidComplete(event: CheckoutCompletedEvent) {
111+
eventHandlers.checkoutDidComplete?(event)
112112
}
113113

114-
func checkoutDidFail(error _: ShopifyCheckoutSheetKit.CheckoutError) {
114+
func checkoutDidFail(error: CheckoutError) {
115115
checkoutViewController?.dismiss(animated: true)
116-
eventHandlers.checkoutDidFail?()
116+
eventHandlers.checkoutDidFail?(error)
117117
}
118118

119119
func checkoutDidCancel() {
@@ -122,15 +122,15 @@ extension ShopPayViewController: CheckoutDelegate {
122122
eventHandlers.checkoutDidCancel?()
123123
}
124124

125-
func checkoutShouldRecoverFromError(error: ShopifyCheckoutSheetKit.CheckoutError) -> Bool {
125+
func shouldRecoverFromError(error: CheckoutError) -> Bool {
126126
return eventHandlers.shouldRecoverFromError?(error) ?? false
127127
}
128128

129129
func checkoutDidClickLink(url: URL) {
130130
eventHandlers.checkoutDidClickLink?(url)
131131
}
132132

133-
func checkoutDidEmitWebPixelEvent(event: ShopifyCheckoutSheetKit.PixelEvent) {
133+
func checkoutDidEmitWebPixelEvent(event: PixelEvent) {
134134
eventHandlers.checkoutDidEmitWebPixelEvent?(event)
135135
}
136136
}

Sources/ShopifyAcceleratedCheckouts/Wallets/Wallet.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,20 @@ public enum Wallet {
3232

3333
/// Event handlers for wallet buttons
3434
public struct EventHandlers {
35-
public var checkoutDidComplete: (() -> Void)?
36-
public var checkoutDidFail: (() -> Void)?
35+
public var checkoutDidComplete: ((CheckoutCompletedEvent) -> Void)?
36+
public var checkoutDidFail: ((CheckoutError) -> Void)?
3737
public var checkoutDidCancel: (() -> Void)?
38-
public var shouldRecoverFromError: ((ShopifyCheckoutSheetKit.CheckoutError) -> Bool)?
38+
public var shouldRecoverFromError: ((CheckoutError) -> Bool)?
3939
public var checkoutDidClickLink: ((URL) -> Void)?
40-
public var checkoutDidEmitWebPixelEvent: ((ShopifyCheckoutSheetKit.PixelEvent) -> Void)?
40+
public var checkoutDidEmitWebPixelEvent: ((PixelEvent) -> Void)?
4141

4242
public init(
43-
checkoutDidComplete: (() -> Void)? = nil,
44-
checkoutDidFail: (() -> Void)? = nil,
43+
checkoutDidComplete: ((CheckoutCompletedEvent) -> Void)? = nil,
44+
checkoutDidFail: ((CheckoutError) -> Void)? = nil,
4545
checkoutDidCancel: (() -> Void)? = nil,
46-
shouldRecoverFromError: ((ShopifyCheckoutSheetKit.CheckoutError) -> Bool)? = nil,
46+
shouldRecoverFromError: ((CheckoutError) -> Bool)? = nil,
4747
checkoutDidClickLink: ((URL) -> Void)? = nil,
48-
checkoutDidEmitWebPixelEvent: ((ShopifyCheckoutSheetKit.PixelEvent) -> Void)? = nil
48+
checkoutDidEmitWebPixelEvent: ((PixelEvent) -> Void)? = nil
4949
) {
5050
self.checkoutDidComplete = checkoutDidComplete
5151
self.checkoutDidFail = checkoutDidFail

0 commit comments

Comments
 (0)