Monitor checkout lifecycle
When a buyer completes, cancels, or encounters an error during checkout, your app needs to respond. Checkout Kit provides lifecycle callbacks to reset cart state, show order confirmation, handle failures, and forward analytics events to third-party providers.
Anchor to RequirementsRequirements
- Checkout Kit installed in your app.
- A valid
checkoutUrlfrom Build a mobile storefront or a cart permalink.
Anchor to Register lifecycle callbacksRegister lifecycle callbacks
Implement the delegate or event listener so your app can respond when checkout completes, fails, or the buyer cancels. The callbacks are where you reset cart state, dismiss the sheet, surface errors to the buyer, and forward web pixel events to your analytics tools.
Register lifecycle callbacks
Swift
extension MyViewController: CheckoutDelegate {
func checkoutDidComplete(event: CheckoutCompletedEvent) {
// The buyer completed checkout.
// Use this to update UI and reset cart state.
}
func checkoutDidCancel() {
// The buyer canceled checkout.
// Use this to call `dismiss(animated:)`.
}
func checkoutDidFail(error: CheckoutError) {
// Checkout encountered an error.
switch error {
// Internal error: exception within the Checkout SDK code.
// Inspect and log the underlying Error and stacktrace to identify the problem.
case .sdkError(let underlying):
break
// The checkout URL points to a misconfigured store.
// The SDK only supports stores migrated to Shopify Extensions in checkout.
case .configurationError(let message):
break
// Network or server error prevented checkout from loading.
case .checkoutUnavailable(let message):
break
// The checkout session for this URL has expired.
case .checkoutExpired(let message):
break
}
}
func checkoutDidClickLink(url: URL) {
// The buyer tapped a link in checkout (mailto:, tel:, or http:).
// Open the URL in the appropriate handler.
}
func checkoutDidEmitWebPixelEvent(event: PixelEvent) {
switch event {
case .standardEvent(let standardEvent):
recordAnalyticsEvent(standardEvent)
case .customEvent(let customEvent):
recordAnalyticsEvent(customEvent)
}
}
}Swift (SwiftUI)
CheckoutSheet(checkout: url)
.colorScheme(.automatic)
.onComplete { event in
print("Order ID: \(event.orderDetails.id)")
CartManager.shared.resetCart()
showCheckoutSheet = false
}
.onCancel {
showCheckoutSheet = false
}
.onFail { error in
handleCheckoutError(error)
showCheckoutSheet = false
}
.onLinkClick { url in
openURL(url)
}
.onPixelEvent { event in
if hasPermissionToTrack {
sendEventToAnalytics(event)
}
}Kotlin
val processor = object : DefaultCheckoutEventProcessor(activity) {
override fun onCheckoutCompleted(checkoutCompletedEvent: CheckoutCompletedEvent) {
// The buyer completed checkout.
// Use this to update UI and reset cart state.
}
override fun onCheckoutCanceled() {
// The buyer canceled checkout.
}
override fun onCheckoutFailed(error: CheckoutException) {
// Checkout encountered an error.
}
override fun onCheckoutLinkClicked(uri: Uri) {
// The buyer tapped a link in checkout (mailto:, tel:, http:, or a deep link).
// Open the URI in the appropriate handler.
}
override fun onWebPixelEvent(event: PixelEvent) {
// Called when a web pixel event is emitted in checkout.
// Use this to submit events to your analytics system.
}
}React Native
const shopifyCheckout = useShopifyCheckoutSheet();
useEffect(() => {
const close = shopifyCheckout.addEventListener('close', () => {
// Do something on checkout close
});
const completed = shopifyCheckout.addEventListener(
'completed',
(event) => {
// Lookup order on checkout completion
const orderId = event.orderDetails.id;
},
);
const error = shopifyCheckout.addEventListener(
'error',
(error) => {
// Do something on checkout error
},
);
const pixel = shopifyCheckout.addEventListener(
'pixel',
(event) => {
// Dispatch web pixel events to third-party services
if (hasPermissionToTrack) {
sendEventToAnalyticsProvider(event);
}
},
);
return () => {
close?.remove();
completed?.remove();
error?.remove();
pixel?.remove();
};
}, [shopifyCheckout]);The cancel event fires when the buyer closes the checkout, whether or not they completed the purchase. Listen for the completed event to determine checkout success before resetting cart state.
The cancel event fires when the buyer closes the checkout, whether or not they completed the purchase. Listen for the completed event to determine checkout success before resetting cart state.
Anchor to Handle file uploads, geolocation, and permissions on AndroidHandle file uploads, geolocation, and permissions on Android
iOS and React Native handle file uploads, geolocation, and permissions automatically. On Android, you implement them through DefaultCheckoutEventProcessor callbacks:
Android-specific callbacks
On Android 11+, deep links require a queries element in your AndroidManifest.xml declaring which apps your app interacts with. Without it, onCheckoutLinkClicked might not resolve external URLs. See the Android queries documentation.
On Android 11+, deep links require a queries element in your AndroidManifest.xml declaring which apps your app interacts with. Without it, onCheckoutLinkClicked might not resolve external URLs. See the Android queries documentation.
Anchor to Integrate with web pixelsIntegrate with web pixels
Web pixels are Shopify's analytics event system. Checkout Kit relays standard and custom web pixel events through the lifecycle callbacks. You can forward these events to your analytics provider to track checkout behavior.
Forward these events only with the buyer's consent and in line with the store's privacy policy. Check Apple's App Store Review Guidelines and Google Play's User Data policy for the markets you operate in:
Integrate with web pixels
Swift
extension MyViewController: CheckoutDelegate {
func checkoutDidEmitWebPixelEvent(event: PixelEvent) {
guard hasPermissionToCaptureEvents() else { return }
switch event {
case .standardEvent(let standardEvent):
sendEventToAnalytics(event: standardEvent)
case .customEvent(let customEvent):
sendEventToAnalytics(event: customEvent)
}
}
}Kotlin
fun onWebPixelEvent(event: PixelEvent) {
if (!hasPermissionToCaptureEvents()) {
return
}
when (event) {
is StandardPixelEvent -> processStandardEvent(event)
is CustomPixelEvent -> processCustomEvent(event)
}
}
fun processStandardEvent(event: StandardPixelEvent) {
val endpoint = "https://example.com/pixel?id=${accountID}&uid=${userId}"
val payload = AnalyticsPayload(
eventTime = event.timestamp,
action = event.name,
details = event.data.checkout
)
// Send events to third-party servers
httpClient.post(endpoint, payload)
}For React Native, the pixel listener registered in Register lifecycle callbacks already gates forwarding behind a consent flag. Reuse that listener and route events to your analytics provider from the same callback.
Checkout Kit returns the customData attribute of a CustomPixelEvent as a string because the data structure varies by web pixel implementation. Define a custom data type in your app and deserialize the customData string into that type.