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

paytech-react-hooks

v2.1.0

Published

Hook React/Next.js pour PayTech. Appelle ton backend — n'expose jamais tes clés API dans le navigateur.

Readme

paytech-react-hooks

Hook React / Next.js pour déclencher un paiement PayTech — Wave, Orange Money, carte bancaire — sans jamais exposer tes clés API.

npm install paytech-react-hooks

React ≥ 18 (peer dependency).


⚠️ Rupture de compatibilité en 2.0.0

Les versions ≤ 1.0.7 acceptaient apiKey et apiSecret en arguments du hook et appelaient PayTech directement depuis le navigateur. C'était fautif sur deux plans :

  1. Le secret du marchand finissait dans le bundle JavaScript, extractible par n'importe quel visiteur via les outils de développement. Avec cette paire de clés, un tiers pouvait créer des paiements et déclencher des remboursements sur le compte PayTech du marchand.
  2. Ça ne pouvait pas fonctionner : PayTech désactive le CORS sur les routes authentifiées, donc le navigateur bloquait l'appel.

Si tu utilises une version ≤ 1.0.7 en production, considère tes clés PayTech comme compromises et régénère-les depuis ton tableau de bord.

Depuis la 2.0.0, le hook appelle une route de ton propre backend, seule détentrice des clés.


Côté client

"use client";
import { usePayTech } from "paytech-react-hooks";

export function BoutonAcheter({ productId }: { productId: string }) {
  const { createPayment, isLoading, error } = usePayTech();

  async function acheter() {
    const url = await createPayment({ productId });
    if (url) window.location.href = url;
  }

  return (
    <>
      <button onClick={acheter} disabled={isLoading}>
        {isLoading ? "Redirection…" : "Payer"}
      </button>
      {error && <p role="alert">{error}</p>}
    </>
  );
}

Avec redirect: true, le hook redirige lui-même :

const { createPayment } = usePayTech({ redirect: true });

Options : endpoint (défaut /api/paytech/checkout), headers, redirect. Le hook renvoie { createPayment, isLoading, error, data, reset }.


React Native, et partout où il n'y a pas de navigateur

redirect n'a d'effet que dans un navigateur. Ailleurs — React Native, rendu serveur — il est ignoré et createPayment renvoie l'URL comme d'habitude :

import { Linking } from "react-native";

const { createPayment, isLoading, error } = usePayTech({
  endpoint: "https://api.tonsite.com/api/paytech/checkout",
});

async function acheter() {
  const url = await createPayment({ productId });
  if (url) await Linking.openURL(url);
}

Deux points propres à React Native :

  • endpoint doit être une URL absolue : il n'y a pas d'origine implicite.
  • Le retour se fait par lien profond. success_url et cancel_url doivent pointer vers une adresse que ton application sait recevoir. Et comme toujours, c'est la notification IPN — pas ce retour — qui confirme le paiement.

Depuis la 2.1.0, redirect: true ne casse plus hors navigateur. React Native définit window mais pas window.location : les versions antérieures y levaient une erreur et perdaient l'URL de paiement pourtant obtenue.


Côté serveur

C'est ici que vivent les clés. Exemple avec le App Router de Next.js et paytech-node-ts-sdk :

// app/api/paytech/checkout/route.ts
import { NextResponse } from "next/server";
import { PayTech } from "paytech-node-ts-sdk";

const paytech = new PayTech({
  apiKey: process.env.PAYTECH_API_KEY!,
  apiSecret: process.env.PAYTECH_API_SECRET!,
});

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

  // Le prix vient de TA base, jamais du navigateur : tout ce qui arrive du
  // client est modifiable par le client.
  const product = await getProduct(productId);
  if (!product) {
    return NextResponse.json({ message: "Produit introuvable." }, { status: 404 });
  }

  const payment = await paytech.createPayment({
    item_name: product.name,
    item_price: product.price,
    currency: "XOF",
    env: process.env.NODE_ENV === "production" ? "prod" : "test",
    ipn_url: `${process.env.PUBLIC_URL}/api/paytech/ipn`,
    success_url: `${process.env.PUBLIC_URL}/merci`,
    cancel_url: `${process.env.PUBLIC_URL}/panier`,
    custom_field: { productId },
  });

  if (payment.success !== 1 || !payment.redirect_url) {
    return NextResponse.json(
      { message: payment.message ?? "Paiement indisponible." },
      { status: 502 }
    );
  }

  await saveOrder({ ref: payment.ref_command, token: payment.token, productId });

  return NextResponse.json({ redirect_url: payment.redirect_url });
}

Ta route doit répondre { redirect_url: string } en cas de succès, et un objet portant message en cas d'erreur.

Le paiement n'est pas confirmé par cette route — seulement initié. La confirmation arrive par notification IPN, qu'il faut vérifier cryptographiquement. Voir la section correspondante du README de paytech-node-ts-sdk.


Licence

MIT © Adramé Diakhaté