npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ionicfi/react

v0.2.2

Published

React components for Ionic embedded checkout. <CheckoutEmbed> mounts a checkout session and manages the iframe lifecycle across re-renders.

Readme

@ionicfi/react

React components for Ionic embedded checkout.

Usage

Create a checkout session on your server with ui_mode: "embedded", hand the response to the component, and render it where the payment form should appear:

import { CheckoutEmbed, type EmbeddedCheckoutSession } from "@ionicfi/react";

function PayPage({ session }: { session: EmbeddedCheckoutSession }) {
  return <CheckoutEmbed session={session} />;
}

session is the create-session API response ({ id, client_secret, embed_url }). The component loads the Ionic SDK from Ionic's CDN on first mount — an existing window.Ionic (for example from a hand-placed script tag) is reused — so the card-handling runtime is never bundled into your app.

onComplete is a browser display signal. Your backend determines payment state from the API or verified events, including the expected merchant, mode, and session identity. Your application owns fulfillment policy. A completed payment session has status: "complete" and payment_status: "paid".

Pass onError if you want to own the failure UI. Without it, the two failures that leave nothing on the page — the SDK script not loading, and mount rejecting its options — render a built-in message. Everything the checkout itself reports (expired session, terminal payment failure) is already displayed inside the iframe, so the component does not add a second message for those.

Digital wallets are on by default (wallets defaults to "auto"): if the buyer's device and your account support one, it appears above the card form once Apple Pay setup is complete.

Don't render the component inside another iframe: the checkout document controls who may frame it, and payment methods that redirect can't complete inside a nested frame.

In a Next.js App Router project, import it from a client component. The published bundle carries the "use client" directive, so importing it from a server component tree works without extra annotation, but the surrounding page logic (state, callbacks) must itself be client-side.

Props

| Prop | Type | Description | |------|------|-------------| | session | EmbeddedCheckoutSession | Required. The create-session response. | | wallets | "auto" \| WalletId[] | Which digital wallets to offer above the card form. Defaults to "auto": every wallet the server reports eligible for the session. Pass an array to restrict the offer, or [] for card only. Eligibility (device, domain registration, amount) is decided server-side, so pass a static value — don't compute it from an async capability check. Changing which wallets are offered remounts the iframe. | | timeoutMs | number | How long to wait for checkout to become ready. Read at mount time; changing it later doesn't remount. | | iframeTitle | string | Accessible title for the checkout iframe. Applied in place; changing it doesn't remount. | | className | string | Applied to the host div the iframe mounts into. | | onReady | () => void | The form is visible and interactive. | | onComplete | (e) => void | Payment succeeded. Fulfill on your server via webhooks; use this to update the UI. | | onCancel | (e) => void | The buyer backed out. Not terminal — the form stays live. | | onError | (e) => void | A failure was reported. See the code list below for which ones are terminal. |

Error codes

onError receives { code, message, terminal }.

Branch on terminal, not on code. terminal: false means the iframe is still live and may yet succeed, so replacing it with an error screen would take a working checkout away from the buyer. New codes are added over time, so a switch on code needs a default branch; terminal never needs updating.

| Code | Source | terminal | |------|--------|-----------| | sdk_load_failed | This package: the CDN script failed to load | true — remount to retry (see below) | | mount_failed | This package: mount() rejected its options | true | | checkout_timeout | SDK: the iframe didn't become ready in timeoutMs | false — the iframe stays live and may still become ready on a slow connection | | init_timeout | Checkout: the handshake inside the iframe timed out | true | | payment_failed | Checkout: terminal payment failure | true | | expired | Checkout: the session expired | true — create a new session | | not_found | Checkout: the session doesn't exist | true | | tokenization_failed | Checkout: card tokenization failed terminally | true |

Retryable declines (an issuer saying no) never reach onError — the checkout handles them in the iframe and the buyer can try another card.

New codes may be added over time; always handle unknown codes in a default branch rather than treating the list as closed.

Retrying after a load failure

After sdk_load_failed, remount the component to retry — the loader clears the failed load, so a fresh mount requests the script again.

If your page supplies its own SDK script tag, remove or replace that tag after a load failure before remounting the component.

Re-render behavior

The iframe holds the buyer's in-progress card entry, so the component tears it down and remounts only when the values that define the mount change — the session's fields (id, client_secret, embed_url) or the set of wallets offered. New callback identities (inline arrow functions), new session object identities with unchanged values, timeoutMs, and iframeTitle never remount. Callbacks always fire with their latest render's identity, and never after the component unmounts.

Content Security Policy

If your page sends a Content-Security-Policy, it needs script-src https://js.ionicfi.com (the SDK is loaded at runtime, never bundled) and frame-src set to the origin of the session's embed_url. A blocked script renders no payment form. Wallets need additional origins — see Embedded checkout: Content Security Policy.

Module format

This package and @ionicfi/js ship ES modules. CommonJS applications can use require() on Node 20.19+ or 22.12+, or dynamic import() on older Node versions. Build and test environments must support ES modules; a CommonJS test transform must also transform the Ionic packages.

Security notes

The component passes session.client_secret to the SDK and never logs or stores it. It does live in React props, so tooling that captures props (React DevTools, error reporters configured to serialize component trees) can see it. The secret authorizes completing this one checkout session only.