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

@payenv/connector-kkiapay

v0.2.0

Published

Kkiapay connector for Payenv (mobile money via the Kkiapay widget, verified server-side).

Readme

@payenv/connector-kkiapay

Kkiapay connector for Payenv.

🚧 Pre-release (0.x).

Kkiapay payments are started by the customer in the Kkiapay widget (browser or mobile app), not by your server. Payenv returns what the widget needs, then verifies the transaction server-side with your private keys before trusting it.

Supported today: mobile money in Benin (XOF): MTN and Moov. Status verification, webhook verification and parsing.

1. Server

import { createPayenv } from '@payenv/core';
import { fedapay } from '@payenv/connector-fedapay';
import { KKIAPAY_WIDGET, kkiapay } from '@payenv/connector-kkiapay';

const payenv = createPayenv({
  connectors: [
    fedapay({ secretKey: process.env.FEDAPAY_SECRET_KEY! }), // server push, tried first
    kkiapay({
      publicKey: process.env.KKIAPAY_PUBLIC_KEY!,
      privateKey: process.env.KKIAPAY_PRIVATE_KEY!,
      secretKey: process.env.KKIAPAY_SECRET_KEY!,
      environment: 'sandbox', // or 'live'
    }),
  ],
});

const payment = await payenv.collect({
  amount: { value: 5000, currency: 'XOF' },
  method: { type: 'mobile_money', network: 'mtn', country: 'BJ', phone: '+22961000000' },
  idempotencyKey: 'order_1234',
  supportedWidgets: [KKIAPAY_WIDGET], // your front end can open the Kkiapay widget
});
// If Kkiapay is used (directly or as a fallback):
// payment.status === 'requires_action'
// payment.nextAction === { type: 'widget', provider: 'kkiapay', params: { key, amount, ... } }

Kkiapay is only used when the request lists it in supportedWidgets: Payenv never hands a widget to a front end that cannot open it.

2. Front end

<script src="https://cdn.kkiapay.me/k.js"></script>
<script>
  // payment.nextAction.params comes from your server
  openKkiapayWidget(payment.nextAction.params);
  addSuccessListener(({ transactionId }) => {
    // Send it to your server, which calls payenv.confirm
    fetch('/payments/' + payment.idempotencyKey + '/confirm', {
      method: 'POST',
      body: JSON.stringify({ transactionId }),
    });
  });
</script>

Only the public key is ever sent to the browser.

3. Confirm (server)

const confirmed = await payenv.confirm('order_1234', transactionId);

confirm asks Kkiapay for the transaction and checks that it carries this payment's reference (partnerId) and amount. A customer cannot confirm an order with another, cheaper transaction: REFERENCE_MISMATCH is thrown and the payment is left unchanged.

Webhooks

The widget's partnerId is the payment's idempotency key, so webhooks map directly:

import { parseKkiapayWebhook, verifyKkiapayWebhook } from '@payenv/connector-kkiapay';

if (verifyKkiapayWebhook(secretHeader, process.env.KKIAPAY_WEBHOOK_SECRET!)) {
  const event = parseKkiapayWebhook(rawBody); // { name, providerRef, merchantReference, status }
  if (event?.merchantReference) await payenv.confirm(event.merchantReference, event.providerRef);
}

Options

| Option | Default | Description | |---|---|---| | publicKey, privateKey, secretKey | — | Kkiapay API keys. Required. | | environment | 'sandbox' | 'sandbox' or 'live'. | | routes | { BJ: ['mtn', 'moov'] } | Mobile money networks per country. | | id | 'kkiapay' | Connector id. | | fetch | global fetch | Custom fetch implementation. |

See QUIRKS.md for what is verified and what remains to verify.

License: Apache-2.0