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

geniuspay-react

v1.0.0

Published

React SDK pour intégrer les paiements GeniusPay (Wave, Orange Money, MTN Money, Carte)

Readme

@geniuspay/react

SDK React officiel pour intégrer les paiements GeniusPay dans votre application. Supporte Wave, Orange Money, MTN Money, Moov Money, Carte bancaire et Paystack.

npm version License: MIT


Installation

npm install @geniuspay/react
yarn add @geniuspay/react

Démarrage rapide

1. Envelopper votre application avec le Provider

// app/providers.tsx (Next.js App Router)
'use client';

import { GeniusPayProvider } from '@geniuspay/react';

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <GeniusPayProvider
      config={{
        apiKey: process.env.NEXT_PUBLIC_GENIUSPAY_KEY!,
        sandbox: true, // false en production
      }}
    >
      {children}
    </GeniusPayProvider>
  );
}
// app/layout.tsx
import { Providers } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}

2. Ajouter un bouton de paiement

'use client';

import { PaymentButton } from '@geniuspay/react';

export default function Page() {
  return (
    <PaymentButton
      amount={5000}
      currency="XOF"
      paymentMethod="wave"
      description="Commande #123"
      onSuccess={(payment) => console.log('Référence :', payment.reference)}
      onError={(error) => console.error(error.message)}
    >
      Payer 5 000 XOF
    </PaymentButton>
  );
}

Configuration

GeniusPayProvider

Le Provider doit encapsuler toute la partie de votre application qui utilise les paiements.

<GeniusPayProvider
  config={{
    apiKey: 'pk_sandbox_xxxxxxxxxxxx', // Obligatoire — clé publique (pk_)
    sandbox: true,                      // true = test, false = production
    currency: 'XOF',                    // Devise par défaut (défaut : 'XOF')
    onSuccess: (payment) => {},         // Callback global succès
    onError: (error) => {},             // Callback global erreur
  }}
>

Astuce : Utilisez une variable d'environnement pour basculer entre sandbox et live :

# .env.local
NEXT_PUBLIC_GENIUSPAY_KEY=pk_sandbox_xxxxxxxxxxxx

Composants

<PaymentButton>

Bouton de paiement prêt à l'emploi.

<PaymentButton
  amount={5000}                    // Montant en centimes (5000 = 50,00 XOF)
  currency="XOF"
  paymentMethod="wave"             // Voir méthodes disponibles ci-dessous
  description="Commande #123"
  customer={{
    name: 'Kouamé Kris',
    email: '[email protected]',
    phone: '+2250700000000',
  }}
  metadata={{ orderId: '123' }}    // Données récupérables dans les webhooks
  successUrl="https://monsite.com/success"
  errorUrl="https://monsite.com/error"
  onSuccess={(payment) => {}}
  onError={(error) => {}}
  onBeforePayment={() => true}     // Retourner false pour annuler
  disabled={false}
  className="mon-bouton"
>
  Payer maintenant
</PaymentButton>

<PaymentForm>

Formulaire complet avec sélection de méthode de paiement et champs client.

<PaymentForm
  amount={10000}
  currency="XOF"
  description="Abonnement Premium"
  allowedMethods={['wave', 'orange_money', 'card']}
  showCustomerFields={true}
  defaultCustomer={{ email: '[email protected]' }}
  onSuccess={(payment) => {}}
  onError={(error) => {}}
/>

<PaymentMethods>

Sélecteur de méthode de paiement à intégrer dans votre propre formulaire.

import { useState } from 'react';
import { PaymentMethods } from '@geniuspay/react';

const [method, setMethod] = useState('wave');

<PaymentMethods
  value={method}
  onChange={setMethod}
  allowedMethods={['wave', 'orange_money', 'mtn_money', 'card']}
/>

<PaymentStatus>

Affiche et suit le statut d'un paiement en temps réel.

<PaymentStatus
  reference="MTX-ABC123"
  pollInterval={3000}           // Vérifier toutes les 3 secondes
  showDetails={true}
  onCompleted={(payment) => {}} // Paiement validé
  onFailed={(payment) => {}}    // Paiement échoué
/>

Le polling s'arrête automatiquement dès que le paiement atteint un état terminal (completed, failed, cancelled, expired).


Hooks

usePayment()

Gestion complète d'un paiement avec état de chargement et gestion d'erreur.

'use client';

import { usePayment } from '@geniuspay/react';

function Checkout() {
  const { pay, payment, isLoading, error, reset } = usePayment();

  const handlePay = async () => {
    const p = await pay({
      amount: 5000,
      paymentMethod: 'wave',
      customer: { email: '[email protected]' },
      metadata: { orderId: '123' },
    });

    // Rediriger si l'opérateur retourne une URL (ex: carte bancaire)
    if (p.paymentUrl) {
      window.location.href = p.paymentUrl;
    }
  };

  if (isLoading) return <p>Traitement en cours...</p>;
  if (error) return <button onClick={reset}>Erreur — Réessayer</button>;

  return <button onClick={handlePay}>Payer 5 000 XOF</button>;
}

usePaymentStatus()

Suit le statut d'un paiement par référence avec polling automatique.

'use client';

import { usePaymentStatus } from '@geniuspay/react';

function SuiviPaiement({ reference }: { reference: string }) {
  const { payment, status, isLoading, refresh } = usePaymentStatus(reference, {
    pollInterval: 3000,
    onCompleted: (p) => console.log('Paiement validé :', p.reference),
    onFailed: (p) => console.log('Échec :', p.status),
  });

  return (
    <div>
      <p>Statut : {status}</p>
      <p>Montant : {payment?.amount} {payment?.currency}</p>
      <button onClick={refresh}>Actualiser</button>
    </div>
  );
}

Valeurs possibles de status :

| Valeur | Description | |---|---| | pending | En attente de validation | | processing | Validation en cours | | completed | Paiement validé ✅ | | failed | Paiement échoué ❌ | | cancelled | Annulé par le client | | expired | Délai dépassé |


useWebhooks()

Gère les webhooks de votre compte depuis l'interface (panneau d'administration).

'use client';

import { useWebhooks } from '@geniuspay/react';

function PanneauWebhooks() {
  const { webhooks, createWebhook, testWebhook, deleteWebhook, isLoading } = useWebhooks();

  const handleCreer = async () => {
    const webhook = await createWebhook({
      name: 'Webhook Production',
      url: 'https://monsite.com/api/webhooks/geniuspay',
      events: ['payment.success', 'payment.failed'],
    });

    // ⚠️ Sauvegarder le secret maintenant — il ne sera plus accessible ensuite
    console.log('Secret :', webhook.secret);
  };

  if (isLoading) return <p>Chargement...</p>;

  return (
    <div>
      <button onClick={handleCreer}>Créer un webhook</button>
      {webhooks.map(wh => (
        <div key={wh.id}>
          <p>{wh.name} — {wh.url}</p>
          <button onClick={() => testWebhook(wh.id)}>Tester</button>
          <button onClick={() => deleteWebhook(wh.id)}>Supprimer</button>
        </div>
      ))}
    </div>
  );
}

Webhooks

Les webhooks permettent à GeniusPay d'appeler votre serveur automatiquement quand un événement se produit (paiement réussi, échoué, etc.).

Événements disponibles

| Événement | Description | |---|---| | payment.success | Paiement validé | | payment.failed | Paiement échoué | | payment.cancelled | Annulé par le client | | payment.expired | Délai dépassé | | payment.refunded | Remboursé | | cashout.completed | Retrait effectué | | webhook.test | Événement de test |

Créer l'endpoint webhook (Next.js)

// app/api/webhooks/geniuspay/route.ts
import { parseWebhookEvent } from '@geniuspay/react/server';

export async function POST(req: Request) {
  // ⚠️ Lire le corps brut — ne pas utiliser req.json()
  const rawBody = await req.text();

  let event;
  try {
    event = await parseWebhookEvent(
      rawBody,
      {
        'x-webhook-signature': req.headers.get('x-webhook-signature') ?? '',
        'x-webhook-timestamp': req.headers.get('x-webhook-timestamp') ?? '',
      },
      process.env.GENIUSPAY_WEBHOOK_SECRET!,
    );
  } catch {
    return Response.json({ error: 'Unauthorized' }, { status: 401 });
  }

  switch (event.event) {
    case 'payment.success':
      // Ex : débloquer le contenu acheté, confirmer la commande...
      await confirmerCommande(event.data.metadata?.orderId as string);
      break;
    case 'payment.failed':
      // Ex : notifier le client, libérer le stock réservé...
      break;
  }

  return Response.json({ received: true });
}

Structure du payload reçu

{
  "id": "evt_01HXY2K3M4N5P6Q7R8S",
  "event": "payment.success",
  "timestamp": 1715000000,
  "environment": "sandbox",
  "data": {
    "reference": "MTX-ABC123",
    "amount": 5000,
    "currency": "XOF",
    "status": "completed",
    "payment_method": "wave",
    "customer_name": "Kouamé Kris",
    "metadata": { "orderId": "123" }
  }
}

Utilisation dans Next.js — Points d'entrée

Le SDK expose 3 points d'entrée pour s'adapter à l'architecture Next.js App Router.

| Import | Contenu | Où l'utiliser | |---|---|---| | @geniuspay/react | Composants + hooks React | Fichiers avec 'use client' | | @geniuspay/react/client | GeniusPayClient (HTTP pur) | Routes API, Server Actions | | @geniuspay/react/server | parseWebhookEvent, verifyWebhookSignature | Routes API webhook |

Exemple : Route API de création de paiement

// app/api/payments/route.ts
import { GeniusPayClient } from '@geniuspay/react/client';

const client = new GeniusPayClient({
  apiKey: process.env.GENIUSPAY_KEY!,
  sandbox: true,
});

export async function POST(req: Request) {
  const body = await req.json();

  const payment = await client.createPayment({
    amount: body.amount,
    currency: 'XOF',
    paymentMethod: body.method,
    customer: body.customer,
    metadata: body.metadata,
  });

  return Response.json({
    reference: payment.reference,
    paymentUrl: payment.paymentUrl ?? null,
    status: payment.status,
  });
}

Client API direct

Pour un contrôle total sans le Provider React.

import { GeniusPayClient } from '@geniuspay/react/client';

const client = new GeniusPayClient({
  apiKey: 'pk_sandbox_xxx',
  sandbox: true,
});

// Créer un paiement
const payment = await client.createPayment({ amount: 5000, currency: 'XOF' });

// Récupérer un paiement
const existing = await client.getPayment('MTX-ABC123');

// Lister les paiements
const { data } = await client.listPayments({ status: 'completed', perPage: 50 });

// Gérer les webhooks
const webhook = await client.createWebhook({
  name: 'Mon webhook',
  url: 'https://monsite.com/api/webhooks/geniuspay',
  events: ['payment.success', 'payment.failed'],
});

Méthodes de paiement

| Méthode | Code | Pays | |---|---|---| | Wave | wave | Sénégal, Côte d'Ivoire | | Orange Money | orange_money | Côte d'Ivoire, Sénégal, Mali | | MTN Money | mtn_money | Côte d'Ivoire, Ghana, Bénin | | Moov Money | moov_money | Côte d'Ivoire, Bénin, Togo | | Carte bancaire | card | International | | Paystack | paystack | Nigeria, Ghana |


Sandbox — Données de test

En mode sandbox (sandbox: true), aucune transaction réelle n'a lieu.

Cartes bancaires

| Numéro | Résultat | |---|---| | 4084 0841 1111 1111 | Succès | | 4084 0841 2222 2222 | Échec |

Mobile Money

| Opérateur | Numéro | Résultat | |---|---|---| | Wave | +221 77 000 0001 | Succès | | Orange Money | +225 07 000 0001 | Succès | | MTN Money | +225 05 000 0001 | Succès |


Types TypeScript

import type {
  GeniusPayConfig,
  PaymentData,
  Payment,
  PaymentMethod,
  PaymentStatus,
  Customer,
  GeniusPayError,
  WebhookEventType,
  WebhookPayload,
  WebhookConfig,
  Webhook,
} from '@geniuspay/react';

Exemple complet — E-commerce

// app/checkout/page.tsx
'use client';

import { useState } from 'react';
import { PaymentForm, PaymentStatus } from '@geniuspay/react';
import type { Payment } from '@geniuspay/react';

export default function CheckoutPage() {
  const [paiement, setPaiement] = useState<Payment | null>(null);

  if (paiement) {
    return (
      <PaymentStatus
        reference={paiement.reference}
        pollInterval={3000}
        showDetails={true}
        onCompleted={() => window.location.href = '/merci'}
        onFailed={() => setPaiement(null)}
      />
    );
  }

  return (
    <PaymentForm
      amount={15000}
      description="Commande #789"
      allowedMethods={['wave', 'orange_money', 'mtn_money', 'card']}
      showCustomerFields={true}
      onSuccess={setPaiement}
      onError={(err) => alert(err.message)}
    />
  );
}

Support

Licence

MIT © GeniusPay