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

@droplinked_inc/payment-intent-react

v0.3.0

Published

React Stripe-Elements wrapper for @droplinked_inc/payment-intent. Port of the <DroplinkedPaymentIntent> client surface from [email protected]. Pairs with the server-side @droplinked_inc/payment-intent state machine.

Readme

@droplinked_inc/payment-intent-react

React Stripe-Elements wrapper for @droplinked_inc/payment-intent. Drop-in replacement for the <DroplinkedPaymentIntent> component that the legacy [email protected] package shipped.

Pairs with the server-side state machine in @droplinked_inc/payment-intent.

Why a separate package

The server package (@droplinked_inc/payment-intent) is intentionally Node-only — state machine, idempotency store, zod schemas. Bundling React into the same package would force every server consumer to pull in react, react-dom, @stripe/stripe-js, etc.

Splitting the React surface into its own package keeps the dependency graph honest: server callers depend on @droplinked_inc/payment-intent, storefront callers depend on @droplinked_inc/payment-intent-react.

Install

pnpm add @droplinked_inc/payment-intent-react @stripe/react-stripe-js @stripe/stripe-js

Peer deps: react >=18, react-dom >=18, @stripe/react-stripe-js >=2, @stripe/stripe-js >=2.

Usage

Mode A — clientSecret (Next-ShopFront pattern)

import { DroplinkedPaymentIntent } from '@droplinked_inc/payment-intent-react';

<DroplinkedPaymentIntent
  clientSecret={stripe.client_secret}
  type="stripe"
  isTestnet={process.env.NODE_ENV !== 'production'}
  return_url={`${window.location.origin}/orders/${orderId}`}
  publishableKey={process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY}
  onSuccess={(pi) => toast.success(`Payment ${pi.status}`)}
  onError={(err) => toast.error('Something went wrong')}
  onCancel={() => toast.info('Payment cancelled')}
  commonStyle={{
    backgroundBody: '#fff',
    colorContainer: '#fff',
    textColorLabel: '#000',
    colorInput: '#fff',
    textColorInput: '#000',
    colorBorderInput: '#F2F2F2',
    borderRadius: '8px',
    cancelButton: { backgroundColor: '#F2F2F2', borderRadius: '8px', textColor: '#000' },
    submitButton: { backgroundColor: '#000', borderRadius: '8px', textColor: '#fff' },
    verticalPadding: '1rem',
    theme: 'light',
  }}
/>

Mode B — orderId (droplinked-checkout pattern)

The caller supplies a mintClientSecret(orderId) async callback. This keeps the API-base-URL out of the component:

<DroplinkedPaymentIntent
  type="STRIPE"
  orderId={orderId}
  isTestnet={appDevelopment}
  publishableKey={process.env.STRIPE_PUBLISHABLE_KEY}
  mintClientSecret={async (id) => {
    const res = await fetch(`/api/orders/${id}/intent`, { method: 'POST' });
    const { client_secret } = await res.json();
    return client_secret;
  }}
  onSuccess={() => navigate(`/success-payment/${orderId}`, { replace: true })}
  onError={(err) => toast.error((err as Error)?.message ?? 'Payment failed')}
  onCancel={() => {}}
  commonStyle={{ cancelButton: { display: 'none' }, submitButton: { width: '100%' } }}
/>

Migration from [email protected]

| Legacy | Rebuild | | ---------------------------------------------- | ------------------------------------------------ | | import { DroplinkedPaymentIntent } from 'droplinked-payment-intent' | import { DroplinkedPaymentIntent } from '@droplinked_inc/payment-intent-react' | | Implicit Stripe publishable key | Pass publishableKey prop or set NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | | onSuccess: () => void | onSuccess: (pi: StripePaymentIntentLike) => void (legacy ()=>void still accepted) | | onError: () => void | onError: (err: unknown) => void (legacy ()=>void still accepted) | | orderId mode w/ implicit API base | orderId mode + explicit mintClientSecret callback |

Security notes

  • The package never embeds a Stripe publishable key. The caller supplies it explicitly (publishableKey) or via env var.
  • confirmPayment is invoked with redirect: 'if_required' so we surface paymentIntent status to the consumer when no redirect is necessary. The consumer's return_url is still honoured when a 3DS redirect is required.
  • No external network calls beyond Stripe's own loadStripe resolution and confirmPayment. No telemetry. No phone-home.

Dual ESM / CJS output

The package emits both ESM (dist/esm/) and CJS (dist/cjs/) outputs so that jest+babel consumers that don't have full ESM support can still require it from CommonJS. The exports field routes resolvers to the right entry automatically.