Skip to content

[RN][Bug]: Forward accelerated checkout dismissal callbacks - #757

Draft
kieran-osgood-shopify wants to merge 3 commits into
mainfrom
swift-accelerated-checkout-dismissals
Draft

kieran-osgood-shopify wants to merge 3 commits into
mainfrom
swift-accelerated-checkout-dismissals

Conversation

@kieran-osgood-shopify

@kieran-osgood-shopify kieran-osgood-shopify commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

What changes are you making?

Forward accelerated checkout lifecycle events from every presentation layer to the existing EventHandlers callbacks.

  • Pass the accelerated checkout controller as the CheckoutDelegate when Shop Pay or Apple Pay presents Checkout Kit.
  • Forward Checkout Kit dismissal and terminal failure events from Shop Pay and Apple Pay.
  • Report checkoutDidDismiss when the buyer closes the native Apple Pay sheet before authorizing payment.
  • Add regression coverage that dismisses the actual presented Checkout Kit controllers and exercises native Apple Pay's dismissal state transition.

Accelerated Checkouts first shipped in v3.4. Through the end of v3, the behavior was:

Dismissal path v3.4–v3.8 behavior
Close/swipe the Shop Pay Checkout Sheet onCancel called
Close the Checkout Sheet shown as an Apple Pay fallback or thank-you page onCancel called
Tap Cancel on the native Apple Pay sheet onCancel not called

The first two paths were lost when the v4 presentation API stopped attaching a CheckoutDelegate, so restoring them repairs a v3 regression. Native Apple Pay used paymentAuthorizationControllerDidFinish(_:) to close its sheet but never forwarded that transition to the accelerated checkout callback.

That gap is now appropriate to close because v4 uses dismissal semantics rather than cancellation semantics. checkoutDidDismiss reports only that the buyer-facing accelerated checkout presentation has closed. It does not claim that a payment was cancelled, failed, or completed. When Apple Pay continues into a Checkout Kit fallback or thank-you page, dismissal is reported only after that final presentation closes.

How to test

GIVEN the Swift Accelerated Checkouts sample is configured with a test storefront, contains a cart item, and displays Shop Pay

WHEN the reviewer opens Shop Pay and closes or swipes down the Checkout Sheet

THEN the Xcode console should log 🚫 Checkout dismissed exactly once without logging a checkout failure


GIVEN the Swift Accelerated Checkouts sample is running on a physical iOS device with Apple Pay configured and contains an Apple Pay-eligible cart item

WHEN the reviewer opens the native Apple Pay sheet and taps Cancel before authorizing payment

THEN the Xcode console should log 🚫 Checkout dismissed exactly once without reporting payment completion or checkout failure


GIVEN the Swift Accelerated Checkouts sample is running on a physical iOS device with Apple Pay configured and Apple Pay continues into a Checkout Kit fallback or thank-you page

WHEN the reviewer closes that Checkout Kit presentation

THEN the Xcode console should log 🚫 Checkout dismissed exactly once when the final presentation closes


Simulator verification

Verified with the Swift sample (CheckoutKitSwiftDemo) on an iPhone Air simulator (iOS 26.2), with this PR and #932 applied. Debug-only instrumentation, not part of this stack, logs each SDK dismissal path and shows an alert naming the onDismiss callsite that fired.

Case SDK dismissal path onDismiss callsite Alert
Shop Pay → close button closeButton → ShopPayViewController.checkoutDidDismiss AcceleratedCheckoutButtons.onDismiss 1-shoppay-close-button
Shop Pay → swipe down interactiveSwipe → ShopPayViewController.checkoutDidDismiss AcceleratedCheckoutButtons.onDismiss 2-shoppay-swipe
Checkout in SwiftUI .sheet → close button closeButton ShopifyCheckout.onDismiss 3-swiftui-sheet-close-button
Checkout in SwiftUI .sheet → swipe down none none ⚠️ 4-swiftui-sheet-swipe-no-alert
Checkout via UIKit present → close button closeButton CheckoutDelegate.checkoutDidDismiss 5-uikit-present-close-button
Checkout via UIKit present → swipe down interactiveSwipe CheckoutDelegate.checkoutDidDismiss 6-uikit-present-swipe

Each passing case reported exactly one dismissal. ⚠️ Swiping down a ShopifyCheckout hosted in a SwiftUI .sheet closes checkout without any callback: the SDK sets the interactive-dismiss delegate on its own controller, but SwiftUI presents a hosting container. That code is unchanged by this stack and needs a separate fix.


Before you merge

Important

  • I've added tests to support my implementation
  • I have read and agree with the Contribution Guidelines
  • I have read and agree with the Code of Conduct
  • I've updated the relevant platform README (platforms/swift/README.md and/or platforms/android/README.md)

Releasing a new Swift version?
  • I have bumped the version in ShopifyCheckoutKit.podspec
  • I have bumped the version in platforms/swift/Sources/ShopifyCheckoutKit/ShopifyCheckoutKit.swift
  • I have updated the SwiftPM/CocoaPods version snippets in platforms/swift/README.md (major version only)
Releasing a new Embedded Checkout Protocol version?
  • I have bumped embeddedCheckoutProtocolAndroid in platforms/android/gradle/libs.versions.toml
  • I have updated protocol/languages/kotlin/embedded-checkout-protocol/api/embedded-checkout-protocol.api if the public API changed
Releasing a new Android version?
  • I have bumped checkoutKitAndroid in platforms/android/gradle/libs.versions.toml
  • I have updated the Gradle/Maven version snippets in platforms/android/README.md

Tip

See the Contributing documentation for the full release process per platform.

@github-actions github-actions Bot added the #gsd:50662 Rebase Checkout Kit on UCP label Sep 10, 2026
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the swift-accelerated-checkout-dismissals branch from df56213 to 5cc9fde Compare September 11, 2026 09:24
@kieran-osgood-shopify
kieran-osgood-shopify added this pull request to stack #763 September 11, 2026 09:24
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the swift-accelerated-checkout-dismissals branch from 8450ac7 to 97a1662 Compare September 11, 2026 14:51
@kieran-osgood-shopify kieran-osgood-shopify changed the title Forward accelerated checkout dismissal callbacks [RN][Bug]: Forward accelerated checkout dismissal callbacks Sep 14, 2026
Assisted-By: devx/3f0e7f93-212d-45d8-b056-138b2da8389f
Assisted-By: devx/3f0e7f93-212d-45d8-b056-138b2da8389f
Checkout completion resets the Apple Pay state machine to idle before the buyer
closes the confirmation page. The later dismissal attempted idle -> completed and
logged InvalidStateTransitionError.

Assisted-By: omp
@kieran-osgood-shopify
kieran-osgood-shopify force-pushed the swift-accelerated-checkout-dismissals branch from 97a1662 to b02476a Compare October 7, 2026 11:52
@github-actions

github-actions Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Bundle Size Budgets

Budget Size Limits Result
— — — ➖ No configured budgets affected

Bundle and package size

Web bundle sizes cover shipped runtime JavaScript. Package sizes cover the full published archive, including any source maps, declarations, and documentation it contains.

Platform Measurement Compression Base Head Delta
- - - - - -
How sizes are measured

Measured from the PR base SHA and PR head SHA. Web bundle rows sum shipped .js, .mjs, and .cjs files under dist/, excluding source maps and declarations. The gzip bundle size sums files compressed individually with gzip -n -9. npm package sizes are gzip-compressed .tgz archives; Android AAR sizes are ZIP archives. Package sizes are not final app binary sizes.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

#gsd:50662 Rebase Checkout Kit on UCP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant