{"id":22427226,"url":"https://github.com/shopify/checkout-sheet-kit-react-native","last_synced_at":"2025-04-05T11:08:26.610Z","repository":{"id":217348670,"uuid":"716182239","full_name":"Shopify/checkout-sheet-kit-react-native","owner":"Shopify","description":"Shopify's Checkout Sheet Kit for React Native - simplifying the process of adding checkout to your native apps.","archived":false,"fork":false,"pushed_at":"2025-02-20T15:30:39.000Z","size":8582,"stargazers_count":46,"open_issues_count":7,"forks_count":6,"subscribers_count":91,"default_branch":"main","last_synced_at":"2025-04-02T22:39:59.231Z","etag":null,"topics":["checkout","react-native","shopify"],"latest_commit_sha":null,"homepage":"https://shopify.dev/docs/custom-storefronts/mobile-apps","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Shopify.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-08T15:54:50.000Z","updated_at":"2025-03-13T13:14:49.000Z","dependencies_parsed_at":"2024-01-30T11:43:36.738Z","dependency_job_id":"d7c999c8-d4c8-40f9-a162-ff0f037668cf","html_url":"https://github.com/Shopify/checkout-sheet-kit-react-native","commit_stats":null,"previous_names":["shopify/checkout-sheet-kit-react-native"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fcheckout-sheet-kit-react-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fcheckout-sheet-kit-react-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fcheckout-sheet-kit-react-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Shopify%2Fcheckout-sheet-kit-react-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Shopify","download_url":"https://codeload.github.com/Shopify/checkout-sheet-kit-react-native/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325693,"owners_count":20920714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["checkout","react-native","shopify"],"created_at":"2024-12-05T20:10:34.707Z","updated_at":"2025-04-05T11:08:26.578Z","avatar_url":"https://github.com/Shopify.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shopify Checkout Sheet Kit - React Native\n\n[![GitHub license](https://img.shields.io/badge/license-MIT-lightgrey.svg?style=flat)](https://github.com/Shopify/checkout-sheet-kit-react-native/blob/main/LICENSE)\n[![GitHub Release](https://img.shields.io/github/release/shopify/checkout-sheet-kit-react-native.svg?style=flat)]()\n\n![image](https://github.com/Shopify/checkout-sheet-kit-react-native/assets/2034704/73246cc6-bd39-4130-a7df-69b06907b897)\n\n**Shopify Checkout Sheet Kit** is a Native Module that enables React Native apps\nto provide the world’s highest converting, customizable, one-page checkout\nwithin the app. The presented experience is a fully-featured checkout that\npreserves all of the store customizations: Checkout UI extensions, Functions,\nbranding, and more. It also provides platform idiomatic defaults such as support\nfor light and dark mode, and convenient developer APIs to embed, customize, and\nfollow the lifecycle of the checkout experience.\n\nCheck out our blog to\n[learn how and why we built the Shopify Checkout Sheet Kit](https://www.shopify.com/partners/blog/mobile-checkout-sdks-for-ios-and-android).\n\nThe React Native SDK is part of\n[Shopify's Mobile Kit](https://shopify.dev/docs/custom-storefronts/mobile-kit)\nwhich enables developers to delivery best-in-class iOS and Android commerce\nexperiences.\n\n- [Platform Requirements](#platform-requirements)\n- [Getting Started](#getting-started)\n  - [1. Installation](#1-installation)\n  - [2. Minimum Android requirements](#2-minimum-android-requirements)\n  - [3. Minimum iOS requirements](#3-minimum-ios-requirements)\n- [Basic Usage](#basic-usage)\n- [Programmatic Usage](#programmatic-usage)\n- [Usage with the Shopify Storefront API](#usage-with-the-shopify-storefront-api)\n- [Configuration](#configuration)\n  - [Colors](#colors)\n  - [Localization](#localization)\n    - [Checkout Sheet title](#checkout-sheet-title)\n      - [iOS - Localization](#ios---localization)\n      - [Android - Localization](#android---localization)\n    - [Currency](#currency)\n    - [Language](#language)\n- [Preloading](#preloading)\n  - [Important considerations](#important-considerations)\n  - [Flash Sales](#flash-sales)\n  - [When to preload](#when-to-preload)\n  - [Cache invalidation](#cache-invalidation)\n- [Checkout lifecycle](#checkout-lifecycle)\n  - [`addEventListener(eventName, callback)`](#addeventlistenereventname-callback)\n  - [`removeEventListeners(eventName)`](#removeeventlistenerseventname)\n- [Behavioral data - Web pixels](#behavioral-data---web-pixels)\n- [Identity \\\u0026 customer accounts](#identity--customer-accounts)\n  - [Cart: buyer bag, identity, and preferences](#cart-buyer-bag-identity-and-preferences)\n    - [Multipass](#multipass)\n    - [Shop Pay](#shop-pay)\n    - [Customer Account API](#customer-account-api)\n- [Offsite Payments](#offsite-payments)\n  - [Universal Links - iOS](#universal-links---ios)\n- [Pickup points / Pickup in store](#pickup-points--pickup-in-store)\n  - [Geolocation - iOS](#geolocation---ios)\n  - [Geolocation - Android](#geolocation---android)\n    - [Opting out of the default behavior](#opting-out-of-the-default-behavior)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Platform Requirements\n\n- **React Native** - Minimum version `0.70`\n- **iOS** - Minimum version iOS 13\n- **Android** - Minimum Java 11 \u0026 Android SDK version `23`\n- **Shopify** - This package is _**not**_ compatible with checkout.liquid. Your\n  Shopify Store must be migrated for extensibility.\n\n## Getting Started\n\nShopify Checkout Sheet Kit is an open-source NPM package.\n\nUse the following steps to get started with adding it to your React Native\napplication:\n\n### 1. Installation\n\nInstall the Shopify Checkout Sheet Kit package dependency:\n\n```sh\nyarn add @shopify/checkout-sheet-kit\n\n# or using npm\nnpm install @shopify/checkout-sheet-kit\n```\n\n### 2. Minimum Android requirements\n\nCheck the `minSdkVersion` property in your `android/build.gradle` file is at\nleast `23`.\n\n```diff\n// android/build.gradle\nbuildscript {\n    ext {\n        buildToolsVersion = \"33.0.0\"\n-       minSdkVersion = 21\n+       minSdkVersion = 23\n        compileSdkVersion = 33\n        targetSdkVersion = 33\n    }\n  // ...\n}\n```\n\n### 3. Minimum iOS requirements\n\nCheck the `platform :ios` property of your `ios/Podfile` to ensure that the\nminimum version number is at least `13`.\n\n```diff\n# ios/Podfile\n- platform :ios, min_ios_version_supported\n+ platform :ios, 13\n```\n\n## Basic Usage\n\nOnce the SDK has been added as a package dependency and the minimum platform\nrequirements have been checked, you can begin by importing the library in your\napplication code:\n\n```tsx\nimport {ShopifyCheckoutSheetProvider} from '@shopify/checkout-sheet-kit';\n\nfunction AppWithContext() {\n  return (\n    \u003cShopifyCheckoutSheetProvider\u003e\n      \u003cApp /\u003e\n    \u003c/ShopifyCheckoutSheetProvider\u003e\n  );\n}\n```\n\nDoing so will now allow you to access the Native Module anywhere in your\napplication using React hooks:\n\n```tsx\nimport {useShopifyCheckoutSheet} from '@shopify/checkout-sheet-kit';\n\nfunction App() {\n  const shopifyCheckout = useShopifyCheckoutSheet();\n\n  // Present the checkout\n  shopifyCheckout.present(checkoutUrl);\n}\n```\n\nSee [usage with the Storefront API](#usage-with-the-storefront-api) below for details on how\nto obtain a checkout URL to pass to the kit.\n\n\u003e [!NOTE]\n\u003e The recommended usage of the library is through a\n\u003e `ShopifyCheckoutSheetProvider` Context provider, but see\n\u003e [Programmatic usage](#programamatic-usage) below for details on how to use the\n\u003e library without React context.\n\n## Programmatic Usage\n\nTo use the library without React context, import the `ShopifyCheckoutSheet`\nclass from the package and instantiate it. We recommend to instantiating the\nclass at a relatively high level in your application, and exporting it for use\nthroughout your app.\n\n```tsx\n// shopify.ts\nimport {ShopifyCheckoutSheet} from '@shopify/checkout-sheet-kit';\n\nexport const shopifyCheckout = new ShopifyCheckoutSheet({\n  // optional configuration\n});\n```\n\nSimilar to the context approach, you can consume the instance as you would using\nhooks.\n\n```tsx\nimport {shopifyCheckout} from './shopify.ts';\n\nshopifyCheckout.present(checkoutUrl);\n```\n\n## Usage with the Shopify Storefront API\n\nTo present a checkout to the buyer, your application must first obtain a\ncheckout URL. The most common way is to use the\n[Storefront GraphQL API](https://shopify.dev/docs/api/storefront), to create a\ncart, add line items, and retrieve a\n[checkoutUrl](https://shopify.dev/docs/api/storefront/2023-10/objects/Cart#field-cart-checkouturl)\nvalue.\n\nYou can use any GraphQL client to accomplish this - but as an example, our\n[sample app](./sample) uses Apollo.\n\nHere's an example of how to get started with Apollo:\n\n```tsx\nimport {ApolloClient, gql, ApolloProvider} from '@apollo/client';\nimport {STOREFRONT_NAME, STOREFRONT_ACCESS_TOKEN} from '@env';\n\n// Create a new instance of the ApolloClient\nconst client = new ApolloClient({\n  uri: `https://${STOREFRONT_NAME}.myshopify.com/api/2024-01/graphql.json`,\n  headers: {\n    'X-Shopify-Storefront-Access-Token': STOREFRONT_ACCESS_TOKEN,\n  },\n});\n\n// Create Cart Mutation\nconst createCartMutation = gql`\n  mutation CreateCart {\n    cartCreate {\n      cart {\n        id\n        checkoutUrl\n      }\n    }\n  }\n`;\n\n// Add to Cart Mutation\nconst addToCartMutation = gql`\n  mutation AddToCart($cartId: ID!, $lines: [CartLineInput!]!) {\n    cartLinesAdd(cartId: $cartId, lines: $lines) {\n      cart {\n        id\n        checkoutUrl\n      }\n    }\n  }\n`;\n\nfunction YourReactNativeApp() {\n  return (\n    \u003cApolloProvider client={client}\u003e\n      \u003cApp /\u003e\n    \u003c/ApolloProvider\u003e\n  );\n}\n```\n\nThe `checkoutUrl` object is a standard web checkout URL that can be opened in\nany browser. To present a native checkout sheet in your application, provide the\n`checkoutUrl` alongside optional runtime configuration settings to the\n`present(checkoutUrl)` function provided by the SDK:\n\n```tsx\nfunction App() {\n  const [createCart] = useMutation(createCartMutation)\n  const [addToCart] = useMutation(addToCartMutation)\n\n  return (\n    // React native app code\n  )\n}\n```\n\nThe `checkoutUrl` value is a standard web checkout URL that can be opened in any\nbrowser. To present a native checkout sheet in your application, provide the\n`checkoutUrl` to the `present(checkoutUrl)` function provided by the SDK:\n\n```tsx\nfunction App() {\n  const shopifyCheckout = useShopifyCheckoutSheet()\n  const checkoutUrl = useRef\u003cstring\u003e(null)\n  const [createCart] = useMutation(createCartMutation)\n  const [addToCart] = useMutation(addToCartMutation)\n\n  const handleAddToCart = useCallback((merchandiseId) =\u003e {\n    // Create a cart\n    const {data: cartCreateResponse} = await createCart()\n    // Add an item to the cart\n    const {data: addToCartResponse} = await addToCart({\n      variables: {\n        cartId: cartCreateResponse.cartCreate.cart.id,\n        lines: [{quantity: 1, merchandiseId}]\n      }\n    })\n    // Retrieve checkoutUrl from the Storefront response\n    checkoutUrl.current = addToCartResponse.cartLinesAdd.cart.checkoutUrl\n\n    // Preload the checkout in the background for faster presentation\n    shopifyCheckout.preload(checkoutUrl.current)\n  }, []);\n\n  const handleCheckout = useCallback(() =\u003e {\n    if (checkoutURL.current) {\n      // Present the checkout to the buyer\n      shopifyCheckout.present(checkoutURL.current)\n    }\n  }, [])\n\n  return (\n    \u003cCatalog\u003e\n      \u003cProduct onAddToCart={handleAddToCart} /\u003e\n      \u003cButton onPress={handleCheckout}\u003e\n        \u003cText\u003eCheckout\u003c/Text\u003e\n      \u003c/Button\u003e\n    \u003cCatalog\u003e\n  )\n}\n```\n\n\u003e [!TIP]\n\u003e To help optimize and deliver the best experience the SDK also provides\n\u003e a [preloading API](#preloading) that can be used to initialize the checkout\n\u003e session in the background and ahead of time.\n\n## Configuration\n\nThe SDK provides a way to customize the presented checkout experience through a\n`configuration` object in the Context Provider or a `setConfig` method on an\ninstance of the `ShopifyCheckoutSheet` class.\n\n| Name          | Required | Default     | Description                                                                                                                                                    |\n| ------------- | -------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `colorScheme` |          | `automatic` | Sets the color scheme for the checkout.                                                                                                                        |\n| `preloading`  |          | `true`      | Enable/disable [preloading](#preloading).                                                                                                                      |\n| `colors`      |          | `{}`        | An object with `ios` and `android` properties to override the colors for iOS and Android platforms individually. See [`colors`](#colors) for more information. |\n\nHere's an example of how a fully customized configuration object might look:\n\n```tsx\nimport {\n  ColorScheme,\n  Configuration,\n  ShopifyCheckoutSheetProvider,\n} from '@shopify/checkout-sheet-kit';\n\nconst config: Configuration = {\n  colorScheme: ColorScheme.web,\n  preloading: true,\n  colors: {\n    ios: {\n      backgroundColor: '#f0f0e8',\n      tintColor: '#2d2a38',\n    },\n    android: {\n      backgroundColor: '#f0f0e8',\n      progressIndicator: '#2d2a38',\n      headerBackgroundColor: '#f0f0e8',\n      headerTextColor: '#2d2a38',\n    },\n  },\n};\n\n// If using React Context\nfunction AppWithContext() {\n  return (\n    \u003cShopifyCheckoutSheetProvider configuration={config}\u003e\n      \u003cApp /\u003e\n    \u003c/ShopifyCheckoutSheetProvider\u003e\n  );\n}\n\n// If using ShopifyCheckoutSheet directly\nconst shopifyCheckout = new ShopifyCheckoutSheet(config);\n```\n\n### Colors\n\nThe SDK defaults to the `automatic` color scheme option, will switches between\nidiomatic `light` and `dark` themes depending on the users preference. This\nbehavior can be customized via the `colorScheme` property:\n\n| Name        | Default | Description                                                                                      |\n| ----------- | ------- | ------------------------------------------------------------------------------------------------ |\n| `automatic` | ✔      | Alternates between an idiomatic light and dark theme - depending on the users device preference. |\n| `light`     |         | Force the idomatic light theme.                                                                  |\n| `dark`      |         | Force the idomatic dark theme.                                                                   |\n| `web`       |         | Force your storefront web theme, as rendered by a mobile browser.                                |\n\nThe `colors` configuration property can be used to provide overrides for iOS and\nAndroid applications separately.\n\n```tsx\nconst config: Configuration = {\n  colorScheme: ColorScheme.light,\n  colors: {\n    ios: {\n      backgroundColor: '#ffffff',\n      tintColor: '#000000',\n    },\n    android: {\n      backgroundColor: '#ffffff',\n      progressIndicator: '#2d2a38',\n      headerBackgroundColor: '#ffffff',\n      headerTextColor: '#000000',\n    },\n  },\n};\n```\n\nNote that when using the `automatic` option, the `colors.android` interface is\nslightly different, as you can specify different overrides for `light` and\n`dark` modes:\n\n```tsx\nimport {\n  ColorScheme,\n  Configuration,\n  ShopifyCheckoutSheetProvider,\n} from '@shopify/checkout-sheet-kit';\n\nconst config: Configuration = {\n  colorScheme: ColorScheme.automatic,\n  colors: {\n    // Custom light/dark overrides for Android\n    android: {\n      light: {\n        backgroundColor: '#ffffff',\n        progressIndicator: '#2d2a38',\n        headerBackgroundColor: '#ffffff',\n        headerTextColor: '#000000',\n      },\n      dark: {\n        backgroundColor: '#000000',\n        progressIndicator: '#0087ff',\n        headerBackgroundColor: '#000000',\n        headerTextColor: '#ffffff',\n      },\n    },\n  },\n};\n\nfunction AppWithContext() {\n  return (\n    \u003cShopifyCheckoutSheetProvider configuration={config}\u003e\n      \u003cApp /\u003e\n    \u003c/ShopifyCheckoutSheetProvider\u003e\n  );\n}\n```\n\n### Localization\n\n#### Checkout Sheet title\n\n##### iOS - Localization\n\nOn iOS, you can set a localized value on the `title` attribute of the\nconfiguration.\n\nAlternatively, use a Localizable.xcstrings file in your app by doing the\nfollowing:\n\n1. Create a `Localizable.xcstrings` file under \"ios/{YourApplicationName}\"\n2. Add an entry for the key `\"shopify_checkout_sheet_title\"`\n\n##### Android - Localization\n\nOn Android, you can add a string entry for the key `\"checkout_web_view_title\"`\nto the \"android/app/src/res/values/strings.xml\" file for your application.\n\n```diff\n\u003cresources\u003e\n    \u003cstring name=\"app_name\"\u003eYour App Name\u003c/string\u003e\n+    \u003cstring name=\"checkout_web_view_title\"\u003eCheckout\u003c/string\u003e\n\u003c/resources\u003e\n```\n\n\u003e [!IMPORTANT]\n\u003e The `title` configuration attribute will only affect iOS. For Android you **must** use\n\u003e `res/values/strings.xml`.\n\n#### Currency\n\nTo set an appropriate currency for a given cart, the Storefront API offers an\n`@inContext(country)` directive which will ensure the correct currency is\npresented.\n\n```tsx\nconst CREATE_CART_MUTATION = gql`\n  mutation CreateCart($input: CartInput, $country: CountryCode = CA)\n  @inContext(country: $country) {\n    cartCreate(input: $input) {\n      cart {\n        id\n        checkoutUrl\n      }\n    }\n  }\n`;\n```\n\nSee [Storefront Directives](https://shopify.dev/docs/api/storefront#directives)\nfor more information.\n\n#### Language\n\nSimilarly to currency, you can use an `@inContext(language)` directive to set\nthe language for your checkout.\n\n```tsx\nconst CREATE_CART_MUTATION = gql`\n  mutation CreateCart($input: CartInput, $language: Language = EN)\n  @inContext(language: $language) {\n    cartCreate(input: $input) {\n      cart {\n        id\n        checkoutUrl\n      }\n    }\n  }\n`;\n```\n\nSee [Storefront Directives](https://shopify.dev/docs/api/storefront#directives)\nfor more information.\n\n## Preloading\n\nInitializing a checkout session requires communicating with Shopify servers,\nthus depending on the network quality and bandwidth available to the buyer can\nresult in undesirable waiting time for the buyer. To help optimize and deliver\nthe best experience, the SDK provides a `preloading` \"hint\" that allows\ndevelopers to signal that the checkout session should be initialized in the\nbackground, ahead of time.\n\nPreloading is an advanced feature that can be disabled by setting the\n`preloading` configuration value to `false`. It is enabled by default.\n\nOnce enabled, preloading a checkout is as simple as calling\n`preload(checkoutUrl)` with a valid `checkoutUrl`.\n\n```tsx\n// using hooks\nconst shopifyCheckout = useShopifyCheckoutSheet();\nShopifyCheckout.preload(checkoutUrl);\n\n// using a class instance\nconst shopifyCheckout = new ShopifyCheckoutSheet();\nshopifyCheckout.preload(checkoutUrl);\n```\n\n### Important considerations\n\n1. Initiating preload results in background network requests and additional\n   CPU/memory utilization for the client, and should be used when there is a\n   high likelihood that the buyer will soon request to checkout—e.g. when the\n   buyer navigates to the cart overview or a similar app-specific experience.\n2. A preloaded checkout session reflects the cart contents at the time when\n   `preload` is called. If the cart is updated after `preload` is called, the\n   application needs to call `preload` again to reflect the updated checkout\n   session.\n3. Calling `preload(checkoutUrl)` is a hint, **not a guarantee**: the library\n   may debounce or ignore calls to this API depending on various conditions; the\n   preload may not complete before `present(checkoutUrl)` is called, in which\n   case the buyer may still see a spinner while the checkout session is\n   finalized.\n\n### Flash Sales\n\nIt is important to note that during Flash Sales or periods of high amounts of traffic, buyers may be entered into a queue system.\n\n**Calls to preload which result in a buyer being enqueued will be rejected.** This means that a buyer will never enter the queue without their knowledge.\n\n### When to preload\n\nCalling `preload()` each time an item is added to a buyer's cart can put significant strain on Shopify systems, which in return can result in rejected requests. Rejected requests will not result in a visual error shown to users, but will degrade the experience since they will need to load checkout from scratch.\n\nInstead, a better approach is to call `preload()` when you have a strong enough signal that the buyer intends to check out. In some cases this might mean a buyer has navigated to a \"cart\" screen.\n\n### Cache invalidation\n\nShould you wish to manually clear the preload cache, there is a `ShopifyCheckoutSheetKit.invalidate()` helper function to do so.\n\n## Checkout lifecycle\n\nThere are currently 3 checkout events exposed through the Native Module. You can\nsubscribe to these events using `addEventListener` and `removeEventListeners`\nmethods - available on both the context provider as well as the class instance.\n\n| Name        | Callback                                  | Description                                                  |\n| ----------- | ----------------------------------------- | ------------------------------------------------------------ |\n| `close`     | `() =\u003e void`                              | Fired when the checkout has been closed.                     |\n| `completed` | `(event: CheckoutCompletedEvent) =\u003e void` | Fired when the checkout has been successfully completed.     |\n| `error`     | `(error: {message: string}) =\u003e void`      | Fired when a checkout exception has been raised.             |\n| `pixel`     | `(event: PixelEvent) =\u003e void`             | Fired when a Web Pixel event has been relayed from checkout. |\n\n### `addEventListener(eventName, callback)`\n\nSubscribing to an event returns an `EmitterSubscription` object, which contains\na `remove()` function to unsubscribe. Here's an example of how you might create\nan event listener in a React `useEffect`, ensuring to remove it on unmount.\n\n```tsx\n// Using hooks\nconst shopifyCheckout = useShopifyCheckoutSheet();\n\nuseEffect(() =\u003e {\n  const close = shopifyCheckout.addEventListener('close', () =\u003e {\n    // Do something on checkout close\n  });\n\n  const completed = shopifyCheckout.addEventListener(\n    'completed',\n    (event: CheckoutCompletedEvent) =\u003e {\n      // Lookup order on checkout completion\n      const orderId = event.orderDetails.id;\n    },\n  );\n\n  const error = shopifyCheckout.addEventListener(\n    'error',\n    (error: CheckoutError) =\u003e {\n      // Do something on checkout error\n      // console.log(error.message)\n    },\n  );\n\n  const pixel = shopifyCheckout.addEventListener(\n    'pixel',\n    (event: PixelEvent) =\u003e {\n      // Dispatch web pixel events to third-party services\n      if (hasPermissionToTrack) {\n        sendEventToAnalyticsProvider(event);\n      }\n    },\n  );\n\n  return () =\u003e {\n    // It is important to clear the subscription on unmount to prevent memory leaks\n    close?.remove();\n    completed?.remove();\n    error?.remove();\n    pixel?.remove();\n  };\n}, [shopifyCheckout]);\n```\n\n### `removeEventListeners(eventName)`\n\nOn the rare occasion that you want to remove all event listeners for a given\n`eventName`, you can use the `removeEventListeners(eventName)` method.\n\n## Behavioral data - Web pixels\n\nApp developers can use\n[lifecycle events](#checkout-lifecycle) to monitor\nand log the status of a checkout session.\n\nFor behavioural monitoring,\n[\"standard\"](https://shopify.dev/docs/api/web-pixels-api/standard-events) and\n[\"custom\"](https://shopify.dev/docs/api/web-pixels-api#custom-web-pixels) Web\nPixel events will be relayed back to your application through the `\"pixel\"`\nevent listener. The responsibility then falls on the application developer to\nensure adherence to Apple's privacy policy and local regulations like GDPR and\nePrivacy directive before disseminating these events to first-party and\nthird-party systems.\n\n\u003e [!NOTE]\n\u003e You will likely need to augment these events with customer/session information derived from app state.\n\n\u003e [!NOTE]\n\u003e The `customData` attribute of CustomPixelEvent can take on any shape. As such, this attribute will be returned as a String. Client applications should define a custom data type and deserialize the customData string into that type.\n\n## Identity \u0026 customer accounts\n\nBuyer-aware checkout experience reduces friction and increases conversion.\nDepending on the context of the buyer (guest or signed-in), knowledge of buyer\npreferences, or account/identity system, the application can use one of the\nfollowing methods to initialize a personalized and contextualized buyer\nexperience.\n\n### Cart: buyer bag, identity, and preferences\n\nIn addition to specifying the line items, the Cart can include buyer identity\n(name, email, address, etc.), and delivery and payment preferences: see\n[guide](https://shopify.dev/docs/custom-storefronts/building-with-the-storefront-api/cart/manage).\nIncluded information will be used to present pre-filled and pre-selected choices\nto the buyer within checkout.\n\n#### Multipass\n\n[Shopify Plus](https://help.shopify.com/en/manual/intro-to-shopify/pricing-plans/plans-features/shopify-plus-plan)\nmerchants using\n[Classic Customer Accounts](https://help.shopify.com/en/manual/customers/customer-accounts/classic-customer-accounts)\ncan use [Multipass](https://shopify.dev/docs/api/multipass)\n([API documentation](https://shopify.dev/docs/api/multipass)) to integrate an\nexternal identity system and initialize a buyer-aware checkout session.\n\n```json\n{\n  \"email\": \"\u003cCustomer's email address\u003e\",\n  \"created_at\": \"\u003cCurrent timestamp in ISO8601 encoding\u003e\",\n  \"remote_ip\": \"\u003cClient IP address\u003e\",\n  \"return_to\": \"\u003cCheckout URL obtained from Storefront API\u003e\"\n}\n```\n\n1. Follow the [Multipass documentation](https://shopify.dev/docs/api/multipass)\n   to create a Multipass URL and set `return_to` to be the obtained\n   `checkoutUrl`\n2. Provide the Multipass URL to `present(checkoutUrl)`\n\n\u003e [!IMPORTANT]\n\u003e The above JSON omits useful customer attributes that should be\n\u003e provided where possible and encryption and signing should be done server-side\n\u003e to ensure Multipass keys are kept secret.\n\n#### Shop Pay\n\nTo initialize accelerated Shop Pay checkout, the cart can set a\n[walletPreference](https://shopify.dev/docs/api/storefront/latest/mutations/cartBuyerIdentityUpdate#field-cartbuyeridentityinput-walletpreferences)\nto 'shop_pay'. The sign-in state of the buyer is app-local. The buyer will be\nprompted to sign in to their Shop account on their first checkout, and their\nsign-in state will be remembered for future checkout sessions.\n\n#### Customer Account API\n\nWe are working on a library to provide buyer sign-in and authentication powered\nby the\n[new Customer Account API](https://www.shopify.com/partners/blog/introducing-customer-account-api-for-headless-stores)—stay\ntuned.\n\n## Offsite Payments\n\nCertain payment providers finalize transactions by redirecting customers to\nexternal banking apps. To enhance the user experience for your buyers, you can\nset up your storefront to support Universal Links on iOS and App links on\nAndroid, allowing customers to be redirected back to your app once the payment\nis completed.\n\n### Universal Links - iOS\n\nSee the\n[Universal Links guide](https://github.com/Shopify/checkout-sheet-kit-react-native/blob/main/documentation/universal_links_ios.md)\nfor information on how to get started with adding support for Offsite Payments\nin your app.\n\nIt is crucial for your app to be configured to handle URL clicks during the\ncheckout process effectively. By default, the kit includes the following\ndelegate method to manage these interactions. This code ensures that external\nlinks, such as HTTPS and deep-links, are opened correctly by iOS.\n\n```swift\npublic func checkoutDidClickLink(url: URL) {\n  if UIApplication.shared.canOpenURL(url) {\n    UIApplication.shared.open(url)\n  }\n}\n```\n\n## Pickup points / Pickup in store\n\n### Geolocation - iOS\n\nGeolocation permission requests are handled out of the box by iOS, provided you've added the required location usage description to your `Info.plist` file:\n\n```xml\n\u003ckey\u003eNSLocationWhenInUseUsageDescription\u003c/key\u003e\n\u003cstring\u003eYour location is required to locate pickup points near you.\u003c/string\u003e\n```\n\n\u003e [!TIP]\n\u003e Consider also adding `NSLocationAlwaysAndWhenInUseUsageDescription` if your app needs background location access for other features.\n\n### Geolocation - Android\n\nAndroid differs to iOS in that permission requests must be handled in two places:\n(1) in your `AndroidManifest.xml` and (2) at runtime.\n\n```xml\n\u003cuses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" /\u003e\n\u003cuses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\" /\u003e\n```\n\nThe Checkout Sheet Kit native module will emit a `geolocationRequest` event when the webview requests geolocation\ninformation. By default, the kit will listen for this event and request access to both coarse and fine access when\ninvoked.\n\nThe geolocation request flow follows this sequence:\n\n1. When checkout needs location data (e.g., to show nearby pickup points), it triggers a geolocation request.\n2. The native module emits a `geolocationRequest` event.\n3. If using default behavior, the module automatically handles the Android runtime permission request.\n4. The result is passed back to checkout, which then proceeds to show relevant pickup points if permission was granted.\n\n\u003e [!NOTE]\n\u003e If the user denies location permissions, the checkout will still function but will not be able to show nearby pickup points. Users can manually enter their location instead.\n\n#### Opting out of the default behavior\n\n\u003e [!NOTE]\n\u003e This section is only applicable for Android.\n\nIn order to opt-out of the default permission handling, you can set `features.handleGeolocationRequests` to `false`\nwhen you instantiate the `ShopifyCheckoutSheet` class.\n\nIf you're using the sheet programmatically, you can do so by specifying a `features` object as the second argument:\n\n```tsx\nconst checkoutSheetKit = new ShopifyCheckoutSheet(config, {handleGeolocationRequests: false});\n```\n\nIf you're using the context provider, you can pass the same `features` object as a prop to the `ShopifyCheckoutSheetProvider` component:\n\n```tsx\n\u003cShopifyCheckoutSheetProvider configuration={config} features={{handleGeolocationRequests: false}}\u003e\n  {children}\n\u003c/ShopifyCheckoutSheetProvider\u003e\n```\n\nWhen opting out, you'll need to implement your own permission handling logic and communicate the result back to the checkout sheet. This can be useful if you want to:\n\n- Customize the permission request UI/UX\n- Coordinate location permissions with other app features\n- Implement custom fallback behavior when permissions are denied\n\nThe steps here to implement your own logic are to:\n\n1. Listen for the `geolocationRequest`\n2. Request the desired permissions\n3. Invoke the native callback by calling `initiateGeolocationRequest` with the permission status\n\n```tsx\n// Listen for \"geolocationRequest\" events\nshopify.addEventListener('geolocationRequest', async (event: GeolocationRequestEvent) =\u003e {\n  const coarse = 'android.permission.ACCESS_COARSE_LOCATION';\n  const fine = 'android.permission.ACCESS_FINE_LOCATION';\n\n  // Request one or many permissions at once\n  const results = await PermissionsAndroid.requestMultiple([coarse, fine]);\n\n  // Check the permission status results\n  const permissionGranted = results[coarse] === 'granted' || results[fine] === 'granted';\n\n  // Dispatch an event to the native module to invoke the native callback with the permission status\n  shopify.initiateGeolocationRequest(permissionGranted);\n})\n```\n\n---\n\n## Contributing\n\nSee the [contributing documentation](CONTRIBUTING.md) for details on how to get started.\n\n## License\n\nShopify's Checkout Sheet Kit is provided under an [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshopify%2Fcheckout-sheet-kit-react-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshopify%2Fcheckout-sheet-kit-react-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshopify%2Fcheckout-sheet-kit-react-native/lists"}