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

medusa-unified-payment-react-test

v0.0.3

Published

Generic payment UI components for Medusa v2 storefronts

Downloads

298

Readme

@juspay/medusa-unified-payment-react

React UI components for Hyperswitch Prism payment connectors. Ships two layers of API:

  • High-level Medusa components — drop-in components for a Medusa v2 Next.js storefront checkout
  • Low-level connector wrappers — standalone React components for any custom checkout

Connector Support Matrix

| Connector | Connector Panel | Payment Button | Authorize Result | |-----------|:---------------:|:--------------:|:----------------:| | adyen | ✅ | ✅ | AUTHORIZED | | paypal | ✅ | ✅ | CAPTURED | | stripe | — | ✅ | AUTHORIZED | | globalpay | ✅ | ✅ | CAPTURED | | braintree | ○ | ○ | — | | cybersource | ○ | ○ | — | | mollie | ○ | ○ | — |

Legend

| Symbol | Meaning | |--------|---------| | ✅ | Supported — React component available | | ○ | No React component — connector has no client-side UI (wallet / redirect / server-side only) | | — | Not in HyperswitchPrismConnectorPanel; use StripeWrapper directly (Stripe handles its own Elements context) |

Authorize result

  • AUTHORIZED (adyen, stripe) — funds reserved; Capture or Void available as a next step
  • CAPTURED (paypal, globalpay) — funds collected immediately at authorize time; only Refund available afterward

Note: All UI flows and connector integrations in this matrix are tested and verified under the sandbox / test environment of each connector. Production behavior should be validated separately before go-live.

Installation

npm install @juspay/medusa-unified-payment-react
# peer dependencies
npm install @adyen/adyen-web @stripe/react-stripe-js @stripe/stripe-js

Local development (linked to this repo):

"@juspay/medusa-unified-payment-react": "file:/path/to/medusa-hyperswitch-prism/medusa-unified-payment-react"

After source changes, rebuild with:

cd medusa-unified-payment-react && npm run build
# then yarn install in your storefront

Environment Variables

Add the following to your storefront .env.local:

# Adyen — client key from your Adyen Customer Area (required for Adyen drop-in)
NEXT_PUBLIC_ADYEN_CLIENT_KEY=test_...

Exports

| Export | Type | Description | |--------|------|-------------| | HyperswitchPrismConnectorPanel | Component | Renders the correct connector UI (Adyen/PayPal/GlobalPay) for a selected payment method | | HyperswitchPrismPaymentButton | Component | Auto-dispatches to the correct place-order button based on providerId | | AdyenWrapper | Component | Low-level Adyen Web v6 drop-in wrapper | | PayPalWrapper | Component | Low-level PayPal Buttons SDK wrapper | | GlobalPayWrapper | Component | Low-level GlobalPay hosted card fields wrapper | | StripeWrapper | Component | Low-level Stripe Payment Element wrapper | | StripePaymentButton | Component | Place-order button for Stripe | | AdyenPaymentButton | Component | Place-order button for Adyen | | PayPalPaymentButton | Component | Place-order button for PayPal | | GlobalPayPaymentButton | Component | Place-order button for GlobalPay | | ManualTestPaymentButton | Component | Dev-only button for manual/test payment providers | | isHyperswitchPrism | Utility | Returns true for any Hyperswitch Prism provider ID | | isHyperswitchPrismStripe | Utility | Matches Stripe provider IDs (short and legacy forms) | | isHyperswitchPrismAdyen | Utility | Matches Adyen provider IDs | | isHyperswitchPrismPaypal | Utility | Matches PayPal provider IDs | | isHyperswitchPrismGlobalpay | Utility | Matches GlobalPay provider IDs | | HYPERSWITCH_PRISM_PROVIDER_IDS | Constant | Map of connector name → canonical provider ID |


High-level Medusa Components

HyperswitchPrismConnectorPanel

Renders the correct payment instrument UI for the selected Hyperswitch Prism provider. Returns null for Stripe (handled separately via @stripe/react-stripe-js) and unknown providers.

import { HyperswitchPrismConnectorPanel } from "@juspay/medusa-unified-payment-react"

<HyperswitchPrismConnectorPanel
  providerId={paymentMethod.id}
  sessionData={sessionForProvider(paymentMethod.id)?.data}
  adyenClientKey={process.env.NEXT_PUBLIC_ADYEN_CLIENT_KEY}
  onInitiateSession={async ({ paymentReference, id }) => {
    // GlobalPay: re-initiate to persist the tokenized card reference
    await initiatePaymentSession(cart, {
      provider_id: paymentMethod.id,
      data: { paymentReference, id },
    })
  }}
  onPaymentCompleted={() => router.push("...?step=review")}
  onError={(e) => setError(e.message)}
/>

| Prop | Type | Required | Description | |------|------|----------|-------------| | providerId | string | Yes | Provider ID of the selected method (e.g. pp_hyperswitch-prism_adyen) | | sessionData | Record<string, any> \| null | Yes | The .data field from the active Medusa payment session | | adyenClientKey | string | Yes (Adyen) | Adyen client key from process.env.NEXT_PUBLIC_ADYEN_CLIENT_KEY — required when Adyen is enabled | | onInitiateSession | (data: { paymentReference, id }) => Promise<void> | Yes | Called by GlobalPay after tokenization to persist the payment reference | | onPaymentCompleted | (result?: any) => void | No | Called after Adyen authorises or PayPal approves | | onError | (error: Error) => void | Yes | Called on any connector-level error | | environment | "sandbox" \| "production" | No | Defaults to "sandbox" |

HyperswitchPrismPaymentButton

Auto-dispatches to the correct connector place-order button. Returns null for non-Hyperswitch Prism providers.

import { HyperswitchPrismPaymentButton } from "@juspay/medusa-unified-payment-react"

<HyperswitchPrismPaymentButton
  providerId={paymentSession?.provider_id}
  cart={cart}
  notReady={notReady}
  onPlaceOrder={placeOrder}
  buttonComponent={Button}
  data-testid="submit-order-button"
/>

| Prop | Type | Required | Description | |------|------|----------|-------------| | providerId | string \| undefined | Yes | Active payment session provider ID | | cart | StoreCart | Yes | Medusa cart | | notReady | boolean | Yes | Disables the button when checkout prerequisites are incomplete | | onPlaceOrder | () => Promise<void> | Yes | Called to place the order | | buttonComponent | React.ComponentType | No | Custom button component | | data-testid | string | No | Test identifier forwarded to the rendered button |

Storefront predicates

Define these inline in your src/lib/constants.tsx — do not re-export from this package, as it causes a createContext error in Next.js server components.

const matchesPrismConnector = (id: string | undefined, connector: string) =>
  id === `pp_hyperswitch-prism_${connector}` ||
  id === `pp_hyperswitch-prism_hyperswitch-prism-${connector}`

export const isHyperswitchPrismStripe   = (id?: string) => matchesPrismConnector(id, "stripe")
export const isHyperswitchPrismAdyen    = (id?: string) => matchesPrismConnector(id, "adyen")
export const isHyperswitchPrismPaypal   = (id?: string) => matchesPrismConnector(id, "paypal")
export const isHyperswitchPrismGlobalpay = (id?: string) => matchesPrismConnector(id, "globalpay")

export const isHyperswitchPrism = (id?: string) =>
  isHyperswitchPrismStripe(id) || isHyperswitchPrismAdyen(id) ||
  isHyperswitchPrismPaypal(id) || isHyperswitchPrismGlobalpay(id)

The dual-match pattern handles both canonical short IDs (pp_hyperswitch-prism_stripe) and legacy long IDs (pp_hyperswitch-prism_hyperswitch-prism-stripe) for backward compatibility with older backend configurations.


Low-level Connector Wrappers

Use these when building a custom (non-Medusa) checkout or embedding an individual payment form.

AdyenWrapper

Renders the Adyen Web v6 drop-in.

import { AdyenWrapper } from "@juspay/medusa-unified-payment-react"

<AdyenWrapper
  sessionData={{
    clientKey: "test_xxx",
    session: { id: "CS...", sessionData: "Ab02b4c..." },
    currency: "EUR",
    minorAmount: 1000,
    countryCode: "GB",
  }}
  onPaymentCompleted={(result) => console.log("Authorised", result)}
  onPaymentFailed={(result) => console.error("Failed", result)}
  onError={(e) => console.error(e)}
/>

| Prop | Type | Required | Description | |------|------|----------|-------------| | sessionData | Record<string, any> | Yes | clientKey, session.id, session.sessionData, currency, minorAmount, countryCode | | onPaymentCompleted | (result: any) => void | No | Called on resultCode: "Authorised" / "Pending" / "Received" | | onPaymentFailed | (result: any) => void | No | Called on non-authorised result codes | | onSubmit | (paymentData: unknown) => void | No | Advanced flow only | | onError | (error: Error) => void | Yes | Called on SDK or network errors |

PayPalWrapper

Renders the PayPal Buttons SDK.

import { PayPalWrapper } from "@juspay/medusa-unified-payment-react"

<PayPalWrapper
  clientId="AYour_PayPal_Client_Id"
  currency="USD"
  amount={49.99}
  environment="sandbox"
  onCreateOrder={() => Promise.resolve(sessionData.paypalOrderId)}
  onSubmit={({ orderId, payerId }) => advanceToReview()}
  onError={(e) => setError(e.message)}
/>

| Prop | Type | Required | Description | |------|------|----------|-------------| | clientId | string | Yes | PayPal app client ID | | currency | string | Yes | ISO 4217 currency code | | amount | number | Yes | Amount in major units | | environment | "sandbox" \| "production" | No | Defaults to "production" | | onCreateOrder | () => Promise<string> | Yes | Must resolve to a PayPal order ID | | onSubmit | (data: { orderId, payerId }) => void | Yes | Called after PayPal approval | | onError | (error: Error) => void | Yes | Called on SDK or approval errors |

GlobalPayWrapper

Renders the GlobalPay hosted card fields. After tokenization, onSubmit is called with the paymentReference that must be persisted before place order.

import { GlobalPayWrapper } from "@juspay/medusa-unified-payment-react"

<GlobalPayWrapper
  accessToken={sessionData.accessToken}
  environment="sandbox"
  onSubmit={async ({ paymentReference }) => {
    await initiatePaymentSession(cart, {
      provider_id: providerId,
      data: { paymentReference },
    })
  }}
  onError={(e) => setError(e.message)}
/>

| Prop | Type | Required | Description | |------|------|----------|-------------| | accessToken | string | Yes | GlobalPay access token from the payment session | | environment | "sandbox" \| "production" | No | Defaults to "sandbox" | | onSubmit | (data: { paymentReference }) => Promise<void> | Yes | Called after successful card tokenization | | onError | (error: Error) => void | Yes | Called on tokenization or SDK errors |

StripeWrapper

Renders the Stripe Payment Element (standalone — does not require an <Elements> context).

import { StripeWrapper } from "@juspay/medusa-unified-payment-react"

<StripeWrapper
  publishableKey="pk_test_..."
  clientSecret={sessionData.client_secret}
  onSubmit={(paymentIntent) => advanceToReview()}
  onError={(e) => setError(e.message)}
/>

| Prop | Type | Required | Description | |------|------|----------|-------------| | publishableKey | string | Yes | Stripe publishable key | | clientSecret | string | Yes | PaymentIntent client secret from the session | | onSubmit | (paymentData: unknown) => void | Yes | Called after confirmPayment succeeds | | onError | (error: Error) => void | Yes | Called on Stripe errors |


Backend Plugin

For the Medusa backend plugin, see @juspay/medusa-unified-payment.

License

MIT