Intégrer Wajub avec React
L'emplacement de la clé secrète dans une application React ou Next.js, et pourquoi elle ne change jamais de place.
Toutes les intégrations React et Next.js suivent la même structure, quel que soit le mode choisi. Une fois cette structure comprise, les différences entre la redirection, l'intégration et les champs personnalisés ne relèvent plus de l'architecture, mais seulement de l'affichage.
Cette page présente cette structure. Le code complet de chaque mode se trouve sur la page React et Next.js. Une recette complète avec un véritable formulaire et une page de retour est disponible dans Checkout avec Next.js App Router.
La règle commune à tous les modes
La clé secrète ne quitte jamais le serveur. Elle ne figure ni dans une prop, ni dans une constante intégrée au bundle, ni dans un composant client qui « s'exécute uniquement lors du build ».
Il ne s'agit pas d'un simple conseil. Wajub applique cette règle à l'entrée de la plateforme.
Une clé secrète envoyée depuis un navigateur est refusée et signalée
Si une requête associe une clé sk. à un en-tête Origin ou Referer, l'API répond avec une erreur 403 qui vous demande d'utiliser une clé publique. Elle place aussi une alerte de sécurité dans la file d'attente pour l'adresse e-mail associée à la clé. Vous n'obtenez pas un échec silencieux et une clé divulguée, mais un échec explicite et un avertissement concernant l'exposition de la clé.
Le navigateur ne détient donc jamais la clé et n'en a pas besoin. Voici ce qu'il reçoit à la place.
Les quatre étapes, identiques dans chaque mode
Relisez la dernière ligne. Lorsque le client vous annonce une réussite, il ne s'agit que d'une affirmation. Le webhook constitue le fait. La livraison de la commande dépend toujours du webhook, jamais d'un callback onSuccess.
Implémentation avec Next.js
Une Server Action constitue la version correcte la plus courte. La directive 'use server' définit la frontière. Le corps de la fonction n'est jamais intégré au bundle du navigateur. La clé ne peut donc pas lui parvenir.
'use server';
import { Wajub } from '@wajub/node';
const wajub = new Wajub({ apiKey: process.env.WAJUB_SECRET_KEY! });
export async function startCheckout(orderId: string) {
const order = await db.orders.find(orderId);
const payment = await wajub.payments.create(
{
amount: order.amount,
currency: order.currency,
customer: { email: order.email },
reference: order.reference,
callback: `${process.env.APP_URL}/orders/${order.id}/return`,
},
{ idempotencyKey: order.reference },
);
await db.orders.update(order.id, { payment_id: payment.id });
return { url: payment.authorization_url };
}Notez que l'action accepte uniquement un identifiant de commande. Le montant provient de votre base de données, pas de l'argument. Un client qui peut définir son propre prix finira par le faire.
Le composant qui appelle cette action est un composant client ordinaire. Il n'importe jamais le SDK.
'use client';
import { useTransition } from 'react';
import { startCheckout } from '@/app/actions/checkout';
export function PayButton({ orderId }: { orderId: string }) {
const [pending, start] = useTransition();
return (
<button
disabled={pending}
onClick={() =>
start(async () => {
const { url } = await startCheckout(orderId);
window.location.href = url;
})
}
>
{pending ? 'Starting…' : 'Pay'}
</button>
);
}Si vous utilisez le Pages Router ou React avec votre propre backend, remplacez la Server Action par une route POST. Le reste de la structure ne change pas.
Le piège des variables d'environnement
Next.js détermine ce qui est envoyé au navigateur grâce à un préfixe. Il est facile d'ajouter ce préfixe par réflexe.
| Variable | Destination |
|---|---|
WAJUB_SECRET_KEY | Serveur uniquement. Correct |
NEXT_PUBLIC_WAJUB_SECRET_KEY | Intégrée au bundle JavaScript. Ne faites jamais cela |
NEXT_PUBLIC_WAJUB_PUBLIC_KEY | Correct, c'est précisément le rôle d'une clé publique |
`NEXT_PUBLIC_` n'est pas une convention de nommage
Il s'agit d'une instruction destinée à l'outil de création du bundle. Toute variable qui porte ce préfixe est remplacée dans le bundle client au moment du build et devient lisible par toute personne qui ouvre la page. Les clés secrètes Wajub restent toujours de simples variables du serveur.
Si vous pensez qu'une clé a déjà été divulguée, révoquez-la depuis Settings › Developer › API Keys. Le renouvellement est immédiat et n'affecte pas vos autres clés.
Les différences réelles entre les modes
La partie serveur décrite plus haut est identique dans les trois modes. Seule la dernière ligne change : l'action du client sur la valeur reçue.
| Mode | Réponse de votre serveur | Action du client |
|---|---|---|
| Redirection | authorization_url | window.location.href = url |
| Intégré | authorization_token | Affiche <CheckoutEmbed sessionId={...} /> avec ce jeton |
| Champs personnalisés | authorization_token | Affiche <PaymentComponent /> et confirme avec useConfirmPayment |
Commencez par la redirection. Wajub gère la liste des opérateurs, le texte de l'invite et chaque écran d'échec. Vous évitez ainsi de construire et maintenir une grande partie de l'interface.
Un jeton de session n'est pas une petite clé secrète
authorization_token sert uniquement à permettre au navigateur de terminer un paiement précis. Il ne peut ni lister, ni rembourser, ni lire quoi que ce soit d'autre. C'est précisément pourquoi vous pouvez l'envoyer à un client en toute sécurité. La page Sessions et sécurité définit cette frontière en détail.
Passez ensuite au code
Cette page s'arrête volontairement avant les détails internes des composants, car ils sont correctement documentés ailleurs, en un seul endroit.
Pages associées
- React et Next.js, trois modesLa page de référence : redirection, intégration et champs personnalisés, avec le code complet.
- Checkout avec Next.js App RouterUne recette complète : formulaire, Server Action, page de retour et webhook.
- Sessions et sécuritéCe qu'un jeton de session peut et ne peut pas faire.
- Accepter un paiement, guide completLe cycle de vie de la commande derrière le bouton.
- Authentification de l'APITypes de clés, préfixes et autorisations de chacune.