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

@filanodev/paygate-next

v1.0.2

Published

Plugin Next.js pour l'intégration de PayGateGlobal - Support FLOOZ et T-Money

Readme

@filanodev/paygate-next

npm version

Plugin Next.js pour l'intégration de PayGateGlobal - Support FLOOZ et T-Money.

📝 Package communautaire développé par Filano pour aider les développeurs Next.js à intégrer plus rapidement PayGateGlobal.

Fonctionnalités

  • Next.js 12-15 - Support des versions modernes
  • 🔄 SSR/SSG/ISR - Compatible avec tous les modes de rendu
  • API Routes - Helpers prêts à l'emploi
  • 🎯 TypeScript - Support complet avec types
  • 🛠 React Hooks - Client-side moderne
  • 🔧 Server Utils - Utilitaires serveur
  • 🌐 App Router - Support Next.js 13+ App Directory

Installation

npm install @filanodev/paygate-next
# ou
yarn add @filanodev/paygate-next
# ou  
pnpm add @filanodev/paygate-next

Configuration

Variables d'environnement

Créez un fichier .env.local :

PAYGATE_TOKEN=your-paygate-token-here

Provider dans l'App (App Router)

// app/layout.tsx
import { PayGateProvider } from '@filanodev/paygate-next/client'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="fr">
      <body>
        <PayGateProvider
          authToken={process.env.NEXT_PUBLIC_PAYGATE_TOKEN!}
          verifySSL={false} // pour le développement uniquement
        >
          {children}
        </PayGateProvider>
      </body>
    </html>
  )
}

Provider dans Pages Router

// pages/_app.tsx
import type { AppProps } from 'next/app'
import { PayGateProvider } from '@filanodev/paygate-next/client'

export default function App({ Component, pageProps }: AppProps) {
  return (
    <PayGateProvider
      authToken={process.env.NEXT_PUBLIC_PAYGATE_TOKEN!}
      verifySSL={false}
    >
      <Component {...pageProps} />
    </PayGateProvider>
  )
}

Usage Client-side

Hook principal

// app/payment/page.tsx
'use client'

import { usePayGate } from '@filanodev/paygate-next/client'

export default function PaymentPage() {
  const { 
    initiatePayment, 
    loading, 
    error, 
    lastPayment, 
    clearError 
  } = usePayGate()

  const handlePayment = async () => {
    const result = await initiatePayment({
      phoneNumber: '+22890123456',
      amount: 1000,
      identifier: `ORDER_${Date.now()}`,
      network: 'FLOOZ',
      description: 'Test paiement Next.js'
    })
    
    if (result) {
      console.log('Paiement initié:', result.txReference)
    }
  }

  return (
    <div>
      <h1>Paiement PayGate</h1>
      
      <button onClick={handlePayment} disabled={loading}>
        {loading ? 'Traitement...' : 'Payer 1000 FCFA'}
      </button>

      {error && (
        <div className="error">
          {error}
          <button onClick={clearError}>×</button>
        </div>
      )}

      {lastPayment && (
        <div className="success">
          Paiement initié: {lastPayment.txReference}
        </div>
      )}
    </div>
  )
}

Composant PaymentForm

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

import { PaymentForm } from '@filanodev/paygate-next/client'
import { useRouter } from 'next/navigation'

export default function CheckoutPage() {
  const router = useRouter()

  const handleSuccess = (result: any) => {
    console.log('Paiement réussi:', result)
    router.push(`/success?ref=${result.txReference}`)
  }

  const handleError = (error: string) => {
    console.error('Erreur paiement:', error)
    // Afficher une notification d'erreur
  }

  return (
    <div>
      <h1>Finaliser votre commande</h1>
      
      <PaymentForm 
        onSuccess={handleSuccess}
        onError={handleError}
        submitLabel="Payer maintenant"
        showReset={true}
        defaultDescription="Commande e-commerce"
        identifierPrefix="SHOP"
      />
    </div>
  )
}

Hook spécialisé pour les statuts

// app/payment/[reference]/page.tsx
'use client'

import { usePaymentStatus } from '@filanodev/paygate-next/client'
import { useParams } from 'next/navigation'

export default function PaymentStatusPage() {
  const params = useParams()
  const reference = params.reference as string

  const { 
    status, 
    loading, 
    error, 
    isPolling, 
    check, 
    startPolling, 
    stopPolling 
  } = usePaymentStatus(reference, 5000)

  return (
    <div>
      <h1>Statut du paiement</h1>
      <p>Référence: {reference}</p>
      
      <div>
        <button onClick={() => check()} disabled={loading}>
          Vérifier maintenant
        </button>
        
        <button onClick={startPolling} disabled={isPolling}>
          📡 Surveillance auto
        </button>
        
        <button onClick={stopPolling} disabled={!isPolling}>
          ⏹ Arrêter
        </button>
      </div>

      {status && (
        <div className={`status-${status.status === 0 ? 'success' : 'pending'}`}>
          <h3>{status.message}</h3>
          <p>Montant: {status.amount} FCFA</p>
          <p>Téléphone: {status.phoneNumber}</p>
          <p>Méthode: {status.paymentMethod}</p>
        </div>
      )}

      {isPolling && (
        <p>🔄 Surveillance en cours...</p>
      )}
    </div>
  )
}

API Routes

App Router - Route Handlers

// app/api/payments/initiate/route.ts
import { NextRequest } from 'next/server'
import { createInitiatePaymentHandler } from '@filanodev/paygate-next/server'

const handler = createInitiatePaymentHandler({
  authToken: process.env.PAYGATE_TOKEN!
})

export async function POST(request: NextRequest) {
  return handler(request)
}
// app/api/payments/status/[reference]/route.ts
import { NextRequest } from 'next/server'
import { createStatusHandler } from '@filanodev/paygate-next/server'

const handler = createStatusHandler()

export async function GET(
  request: NextRequest,
  { params }: { params: { reference: string } }
) {
  return handler(request, { params })
}
// app/api/payments/balance/route.ts
import { NextRequest } from 'next/server'
import { createBalanceHandler } from '@filanodev/paygate-next/server'

const handler = createBalanceHandler()

export async function GET(request: NextRequest) {
  return handler(request)
}

Pages Router - API Routes

// pages/api/payments/initiate.ts
import type { NextApiRequest, NextApiResponse } from 'next'
import { serverInitiatePayment, validatePaymentData } from '@filanodev/paygate-next/server'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Méthode non autorisée' })
  }

  try {
    const paymentData = validatePaymentData(req.body)
    const result = await serverInitiatePayment(paymentData)
    
    res.status(200).json({
      success: true,
      data: result
    })
  } catch (error) {
    res.status(400).json({
      success: false,
      error: error.message
    })
  }
}
// pages/api/payments/status/[reference].ts
import type { NextApiRequest, NextApiResponse } from 'next'
import { serverCheckPaymentStatus } from '@filanodev/paygate-next/server'

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'GET') {
    return res.status(405).json({ error: 'Méthode non autorisée' })
  }

  try {
    const { reference } = req.query
    const status = await serverCheckPaymentStatus(reference as string)
    
    res.status(200).json({
      success: true,
      data: status
    })
  } catch (error) {
    res.status(404).json({
      success: false,
      error: 'Paiement non trouvé'
    })
  }
}

Webhook Handler

// app/api/webhooks/paygate/route.ts
import { NextRequest, NextResponse } from 'next/server'
import { createWebhookHandler } from '@filanodev/paygate-next/server'

const webhookHandler = createWebhookHandler(
  async (payload) => {
    // Traiter la mise à jour du paiement
    console.log('Paiement mis à jour:', payload)
    
    // Exemple: mettre à jour la base de données
    // await updatePaymentInDatabase(payload.identifier, payload.status)
    
    // Exemple: envoyer une notification
    // await sendNotification(payload)
  },
  process.env.PAYGATE_WEBHOOK_SECRET
)

export async function POST(request: NextRequest) {
  try {
    const payload = await request.json()
    const success = await webhookHandler(payload)
    
    if (success) {
      return NextResponse.json({ received: true })
    } else {
      return NextResponse.json({ error: 'Invalid webhook' }, { status: 400 })
    }
  } catch (error) {
    return NextResponse.json({ error: 'Webhook error' }, { status: 500 })
  }
}

Utilisation Server-side

Dans les Server Components

// app/orders/[id]/page.tsx
import { serverCheckPaymentStatus } from '@filanodev/paygate-next/server'

interface Props {
  params: { id: string }
}

export default async function OrderPage({ params }: Props) {
  let paymentStatus = null
  
  try {
    // Récupérer le statut côté serveur
    paymentStatus = await serverCheckPaymentStatus(params.id)
  } catch (error) {
    console.error('Erreur lors de la récupération du statut:', error)
  }

  return (
    <div>
      <h1>Commande #{params.id}</h1>
      
      {paymentStatus ? (
        <div className={`status-${paymentStatus.status === 0 ? 'success' : 'pending'}`}>
          <p>Statut: {paymentStatus.message}</p>
          <p>Montant: {paymentStatus.amount} FCFA</p>
        </div>
      ) : (
        <p>Statut du paiement non disponible</p>
      )}
    </div>
  )
}

Dans les Server Actions

// app/payment/actions.ts
'use server'

import { serverInitiatePayment } from '@filanodev/paygate-next/server'
import { revalidatePath } from 'next/cache'

export async function processPayment(formData: FormData) {
  try {
    const result = await serverInitiatePayment({
      phoneNumber: formData.get('phoneNumber') as string,
      amount: Number(formData.get('amount')),
      identifier: `ORDER_${Date.now()}`,
      network: formData.get('network') as 'FLOOZ' | 'TMONEY',
      description: 'Paiement via Server Action'
    })
    
    // Revalider les données de la page
    revalidatePath('/payments')
    
    return {
      success: true,
      data: result
    }
  } catch (error) {
    return {
      success: false,
      error: error.message
    }
  }
}

Middleware et sécurité

Middleware avec CORS

// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
import { withCors } from '@filanodev/paygate-next/server'

const corsHandler = withCors(['https://your-domain.com'])

export function middleware(request: NextRequest) {
  // Appliquer CORS aux routes API PayGate
  if (request.nextUrl.pathname.startsWith('/api/payments')) {
    return corsHandler((req) => NextResponse.next())(request)
  }
  
  return NextResponse.next()
}

export const config = {
  matcher: '/api/payments/:path*'
}

Configuration avancée

// lib/paygate.ts
import { createPayGateApiClient, ensurePayGateConfig } from '@filanodev/paygate-next/server'

// Vérifier la configuration au démarrage
ensurePayGateConfig()

// Client global pour l'application
export const paygateClient = createPayGateApiClient({
  authToken: process.env.PAYGATE_TOKEN!,
  verifySSL: process.env.NODE_ENV === 'production'
})

Exemple d'application complète

// app/page.tsx
import { PaymentDemo } from './components/PaymentDemo'

export default function HomePage() {
  return (
    <main>
      <h1>Demo PayGate Next.js</h1>
      <PaymentDemo />
    </main>
  )
}
// app/components/PaymentDemo.tsx
'use client'

import { useState } from 'react'
import { usePayGate, PaymentForm } from '@filanodev/paygate-next/client'

export function PaymentDemo() {
  const [paymentReference, setPaymentReference] = useState<string | null>(null)
  const { checkPaymentStatus, loading, lastStatus } = usePayGate()

  const handlePaymentSuccess = (result: any) => {
    setPaymentReference(result.txReference)
  }

  const checkStatus = async () => {
    if (paymentReference) {
      await checkPaymentStatus(paymentReference)
    }
  }

  return (
    <div style={{ maxWidth: '600px', margin: '0 auto', padding: '20px' }}>
      <h2>Initier un paiement</h2>
      
      <PaymentForm
        onSuccess={handlePaymentSuccess}
        onError={(error) => console.error(error)}
        identifierPrefix="DEMO"
      />

      {paymentReference && (
        <div style={{ marginTop: '30px', padding: '20px', background: '#f5f5f5' }}>
          <h3>Vérifier le statut</h3>
          <p>Référence: {paymentReference}</p>
          
          <button onClick={checkStatus} disabled={loading}>
            {loading ? 'Vérification...' : 'Vérifier le statut'}
          </button>

          {lastStatus && (
            <div style={{ marginTop: '10px' }}>
              <strong>Statut:</strong> {lastStatus.message}<br />
              <strong>Montant:</strong> {lastStatus.amount} FCFA<br />
              <strong>Méthode:</strong> {lastStatus.paymentMethod}
            </div>
          )}
        </div>
      )}
    </div>
  )
}

API

Hooks Client-side

  • usePayGate() - Hook principal avec toutes les fonctionnalités
  • usePaymentInitiation() - Spécialisé pour l'initiation de paiements
  • usePaymentStatus(reference?, pollInterval?) - Vérification de statut avec polling

Composants

  • <PayGateProvider> - Provider context pour l'application
  • <PaymentForm> - Formulaire de paiement complet

Utilitaires Server-side

  • getServerPayGateClient(config?) - Obtenir le client serveur
  • serverInitiatePayment(params, config?) - Initier un paiement
  • serverCheckPaymentStatus(reference, config?) - Vérifier le statut
  • createInitiatePaymentHandler(config?) - Handler API prêt à l'emploi
  • createStatusHandler(config?) - Handler de vérification de statut
  • createWebhookHandler(onUpdated, secret?) - Handler de webhook

Helpers API

  • withPayGateErrorHandling() - Middleware de gestion d'erreurs
  • validatePaymentData() - Validation des données de paiement
  • createApiResponse() - Créer une réponse API standardisée
  • withCors() - Middleware CORS

Support TypeScript

Le package inclut tous les types TypeScript :

import type { 
  PayGateConfig,
  InitiatePaymentParams,
  PaymentResponse,
  PaymentStatus,
  WebhookPayload
} from '@filanodev/paygate-next'

Gestion des erreurs

'use client'

import { usePayGate, PayGateError } from '@filanodev/paygate-next/client'

export default function PaymentComponent() {
  const { initiatePayment } = usePayGate()

  const handlePayment = async () => {
    try {
      await initiatePayment(params)
    } catch (error) {
      if (error instanceof PayGateError) {
        console.error('Erreur PayGate:', error.status, error.message)
      } else {
        console.error('Erreur générale:', error)
      }
    }
  }

  return <button onClick={handlePayment}>Payer</button>
}

Support

Pour toute question sur ce package, créez une issue sur GitHub.

Pour le support PayGateGlobal officiel :

Licence

MIT