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

react-klasha

v1.0.0

Published

React hooks and components for accepting payments with the Klasha payment gateway

Readme

react-klasha

React hooks and components for accepting payments with the Klasha payment gateway.

npm license

Demo


⚠️ Version 0.0.x is completely non-functional — upgrade to 1.0.0

Two things were wrong with 0.0.x, and both are fatal:

  1. The script it loaded no longer exists. 0.0.x fetched https://klastatic.fra1.digitaloceanspaces.com/{test,prod}/js/klasha-integration.js. That bucket has been deleted; both URLs now return a 404. window.KlashaClient is therefore never defined and no payment can start at all. Klasha's current script is https://js.klasha.com/pay.js, which 1.0.0 loads.

  2. isTestMode was never sent to the gateway. The Klasha client takes the test flag as its 9th constructor argument; 0.0.x stopped at 8. Inside the Klasha script the flag then read as undefined, so the base URL, the iframe and the redirect URL all took the production branch. This matters now: the current pay.js serves one URL for both environments and decides which gateway to use from that argument alone, so repointing 0.0.x at the new script without adding it would route sandbox traffic to production. 1.0.0 passes it, coerced to a real boolean.

    To be clear about the past: while the old CDN still existed, 0.0.x picked /test/js/ or /prod/js/ correctly based on isTestMode, and that old script was environment-specific by URL. There is no reason to believe your historical sandbox payments went to production, and nothing to reconcile.

1.0.0 also fixes a silently dropped phone number, duplicate DOM ids, a load race that reported "ready" before the Klasha script had run, and console.log calls that printed your merchantKey to the browser console. See Migrating from 0.0.x.


Requirements

  • React 16.8 or later (17, 18 and 19 are supported)
  • Node 18+ to build from source

0.0.x declared support for React 15, but the library is built on hooks and has never worked below 16.8.

Install

npm install react-klasha
yarn add react-klasha

Quick start

import {KlashaButton} from 'react-klasha';

export default function Checkout() {
  return (
    <KlashaButton
      text="Make Payment"
      className="payButton"
      merchantKey="YOUR_MERCHANT_KEY"
      businessId="YOUR_BUSINESS_ID"
      amount={1000}
      sourceCurrency="USD"
      destinationCurrency="NGN"
      tx_ref={`tx-${Date.now()}`}
      fullname="John Doe"
      email="[email protected]"
      phone="+2348143108254"
      paymentDescription="Order #1234"
      isTestMode
      callBack={(response) => console.log('payment complete', response)}
    />
  );
}

isTestMode selects the environment

There is a single script — https://js.klasha.com/pay.js — for both test and live traffic. The environment is chosen entirely by isTestMode, which this library forwards as the 9th constructor argument:

| isTestMode | Gateway used | | --- | --- | | true | Klasha test environment | | false (default) | Klasha live environment |

Use your test merchant key with isTestMode, and your live key without it.

Usage

useKlashaPayment hook

import {useKlashaPayment} from 'react-klasha';

function DonateButton() {
  const config = {
    merchantKey: 'YOUR_MERCHANT_KEY',
    businessId: 'YOUR_BUSINESS_ID',
    amount: 1000,
    sourceCurrency: 'USD',
    destinationCurrency: 'NGN',
    tx_ref: `tx-${Date.now()}`,
    fullname: 'John Doe',
    email: '[email protected]',
    phone: '+2348143108254',
    isTestMode: true,
  };

  const initializePayment = useKlashaPayment(config);
  const callBack = (response) => console.log('payment complete', response);

  return <button onClick={() => initializePayment(callBack)}>Donate</button>;
}

initializePayment throws if it is called before the Klasha script has loaded, or if the script failed to load. Gate your button on the script state:

import {useKlashaScript, useKlashaPayment} from 'react-klasha';

function PayButton({config, callBack}) {
  const [ready, failed] = useKlashaScript(config.isTestMode);
  const initializePayment = useKlashaPayment(config);

  if (failed) return <p>Payment is unavailable right now.</p>;

  return (
    <button disabled={!ready} onClick={() => initializePayment(callBack)}>
      {ready ? 'Pay' : 'Loading…'}
    </button>
  );
}

useKlashaScript returns [loaded, error]. loaded only turns true once pay.js itself has executed — never merely because a load was started.

KlashaConsumer render prop

import {KlashaConsumer} from 'react-klasha';

<KlashaConsumer {...config} callBack={callBack}>
  {({initializePayment}) => <button onClick={initializePayment}>Pay with Klasha</button>}
</KlashaConsumer>;

KlashaConsumer forwards refs. The ref is handed to the render prop:

<KlashaConsumer {...config} ref={myRef}>
  {({initializePayment, ref}) => (
    <button ref={ref} onClick={initializePayment}>
      Pay
    </button>
  )}
</KlashaConsumer>;

KlashaProvider

Wrap a subtree so nested components share one payment configuration. Nested components read initializePayment and callBack from context.

import {KlashaProvider} from 'react-klasha';

<KlashaProvider {...config} callBack={callBack}>
  <Checkout />
</KlashaProvider>;

API

Payment options

Accepted by useKlashaPayment, KlashaButton, KlashaConsumer and KlashaProvider.

| Option | Type | Required | Description | | --- | --- | --- | --- | | merchantKey | string | ✅ | Merchant API key from the Klasha dashboard | | businessId | string \| number | ✅ | Merchant business id | | amount | number | ✅ | Amount to charge | | isTestMode | boolean | | Use the Klasha test environment. Defaults to false | | sourceCurrency | string | | Currency the customer is charged in. Defaults to NGN | | destinationCurrency | string | | Currency the merchant is settled in. Defaults to NGN | | tx_ref | string | | Your unique transaction reference. Generated when omitted | | fullname | string | | Customer's full name | | email | string | | Customer's email | | phone | string | | Customer's phone number | | phone_number | string | | Deprecated alias of phone | | callbackUrl | string | | URL the gateway calls when the transaction completes | | paymentDescription | string | | Description of what is being paid for | | metadata | object | | Extra data to keep alongside the transaction | | kit | KlashaKitOptions | | Extra fields forwarded to the Klasha client | | containerId | string | | Render the checkout into a specific element. One is created per component when omitted |

The kit object

kit is passed straight to the Klasha client. The keys pay.js actually reads are businessId, currency, redirect_url, email, phone, productType, amount, sourceAmount, callBack and tx_ref.

You rarely need to set any of them — this library fills in currency, email, fullname, phone, amount, tx_ref and callBack from the top-level options and builds a fresh kit for every payment (the Klasha script mutates the object it is given, so a shared one leaks state between transactions).

const config = {
  // …payment options…
  kit: {
    productType: 'digital',
    sourceAmount: 12,
  },
};

kit.phone is the key the gateway reads. 0.0.x set only kit.phone_number, which pay.js never looks at, so the customer's phone number was silently dropped from the exchange-rate request. 1.0.0 sets both.

KlashaButton props

Everything above, plus:

| Prop | Type | Description | | --- | --- | --- | | text | string | Button label | | children | ReactNode | Used when text is absent | | className | string | CSS class | | disabled | boolean | Disable the button | | type | 'button', 'submit' or 'reset' | Defaults to 'button' | | callBack | Function | Called when the payment flow completes |

Exports

import {
  useKlashaPayment,
  useKlashaScript,
  useKlashaContainer,
  KlashaButton,
  KlashaConsumer,
  KlashaProvider,
  ensureKlashaContainer,
  removeKlashaContainer,
  getKlashaScriptUrl,
  KLASHA_SDK_URL,
} from 'react-klasha';

TypeScript types KlashaOptionsProps, KlashaKitOptions, KlashaClientConstructor, KlashaClientInstance and KlashaRenderProps are exported too.

Migrating from 0.0.x

| Change | Impact | | --- | --- | | Loads https://js.klasha.com/pay.js | The old CDN bucket was deleted and returns 404, so 0.0.x cannot start a payment at all. | | isTestMode is forwarded to the gateway | Test-mode integrations no longer hit the live environment. Use your test merchant key when isTestMode is set. | | jQuery is no longer loaded | pay.js does not need it. If you relied on this library to provide window.$, load jQuery yourself. | | useKlashaScript reports loaded only once pay.js has executed | It used to resolve on whichever of jQuery/Klasha loaded first, so loaded was frequently true while window.KlashaClient was undefined. | | Script error no longer reports loaded: true | useKlashaScript returns [false, true] on failure instead of [true, true]. | | initializePayment throws instead of silently doing nothing when the script is not ready | Gate the call on useKlashaScript, or catch the error. | | The checkout container has a unique per-component id | The hardcoded <div id="ktest"> was appended on every effect run. Pass containerId if you need a specific element. | | kit.phone is populated | The phone number used to be dropped. kit.phone_number is still set for compatibility. | | tx_ref is generated when omitted | It is interpolated into the redirect URL and must not be empty. | | console.log of the options (including merchantKey) removed | Nothing is written to the console any more. | | KlashaConsumer ref actually reaches the render prop | It was always undefined before. | | Peer range is now react@^16.8 \|\| ^17 \|\| ^18 \|\| ^19 | React 15 was never actually supported. | | react-dom peer dependency removed | The library never imported it. | | Build output is dist/index.cjs + dist/index.mjs with an exports map | Deep imports into dist/ are no longer supported. |

Development

npm install
npm run typecheck
npm test
npm run build

Documentation

See the Klasha documentation for the full list of options and for how to verify a transaction server-side.

Always verify a payment on your server before fulfilling an order. Never trust the browser callback alone.

Contributing

  1. Fork it
  2. Create your feature branch: git checkout -b feature-name
  3. Commit your changes: git commit -am 'Some commit message'
  4. Push to the branch: git push origin feature-name
  5. Submit a pull request 😉

How can I thank you?

Star the repo, and share it! Don't forget to follow me on twitter.

Thanks! Adekanbi Dansteve.

License

MIT — see LICENSE.md.