Skip to content

Supported per-presentation event provenance for completed/close/error (RN 3.9.0) #523

Description

@kareemsmara

Description

Environment

  • React Native package: @shopify/checkout-sheet-kit@3.9.0
  • iOS native dependency: ShopifyCheckoutSheetKit 3.8.2
  • Android native dependency: 3.6.3
  • Storefront API: 2026-07
  • Integration: Storefront cart checkoutUrl → present(checkoutUrl)
  • Preloading disabled

Feature request

We are building a mobile commerce app and need a supported way to associate every checkout lifecycle callback with the specific presentation and original cart that produced it.

From the installed SDK source, present() returns void, the React Native event emitter is shared, close has no payload, and completed/error do not include a presentation identifier. We could not find a documented reset or drain acknowledgment guaranteeing that callbacks from an earlier presentation cannot reach a later listener.

This creates an ambiguity for safe repeat checkout. A synthetic reproduction demonstrates how an old callback could be assigned to a newer session; we have not claimed to reproduce this ordering on a physical device.

Minimal scenario

  1. Present checkout A.
  2. A closes with an unknown outcome.
  3. The buyer starts a new cart and presents checkout B.
  4. A delayed or duplicate completed event originating from A arrives through the shared emitter.
  5. Without a reliable source identifier, the app cannot safely determine whether that event belongs to A or B.

We currently use a conservative barrier to prevent a second presentation while ownership remains ambiguous. This avoids incorrect cart clearing but is not a usable long-term repeat-checkout experience.

Questions for the maintainers

  1. Is there a supported per-presentation identifier or immutable event ownership mechanism for completed, close, and error, including callbacks already queued before cached WebView reuse or processor rebinding?
  2. Is there a supported teardown, reset, or drain acknowledgment after which no event from a previous presentation can reach a later owner? What guarantees apply to dismissal, Fast Refresh, JavaScript reload, and surviving native Activities/ViewControllers?
  3. Is there a documented, stable relationship between completed.orderDetails.cart.token and the original Storefront Cart.id? The pinned native implementations include fallback completion paths with an empty cart token. What supported identity should applications use in those cases? We do not want to infer token formats or parse GIDs.
  4. For offsite/3DS payments, what state is restored automatically after process death, and how should a return URL be bound to its original checkout without associating it with a newly created cart?
  5. Is an upstream per-presentation event ID, supported source isolation, or equivalent mechanism planned? We would be happy to test a pre-release.

A secondary concern: the SDK's event-parsing error path appears to log raw serialized event data. Is there a supported way to suppress or redact this payload?

We are looking for a supported contract that permits safe repeat in-app checkout without relying on timers, callback counts, or restarting the application.

Rationale

A reliable checkout integration must never interpret a delayed event from one checkout as confirmation of another. Incorrect attribution could clear a customer's active cart, display a false purchase confirmation, or leave the buyer uncertain about whether an order was placed.

The current anonymous event contract makes it difficult to support repeat purchases and robust recovery after dismissal, JavaScript reloads, or offsite payment returns without imposing restrictive application-level workarounds.

A supported per-presentation identity or verified event-source isolation mechanism would allow developers to preserve the original cart/session ownership, handle duplicate and delayed events safely, and offer normal repeat checkout while keeping payment processing within Shopify's hosted checkout.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions