geniuspay-react
v1.0.0
Published
React SDK pour intégrer les paiements GeniusPay (Wave, Orange Money, MTN Money, Carte)
Maintainers
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.
Installation
npm install @geniuspay/reactyarn add @geniuspay/reactDé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
- Documentation API : pay.genius.ci/docs
- Email : [email protected]
- Site : pay.genius.ci
Licence
MIT © GeniusPay
