Sache quel canal te rapporte de l’argent.
Kauri relie chaque paiement de ton agrégateur au visiteur qui l’a fait : sa source, ses pages, son pays. En FCFA, installé en 5 minutes.
D’où vient l’argent
| Source | Conversion | Revenus FCFA |
|---|---|---|
| TikTok | 1,6 % | 290 000 |
| Direct | 1,7 % | 210 000 |
| 1,6 % | 105 000 | |
| 1,0 % | 100 000 | |
| 1,0 % | 55 000 | |
| 1,6 % | 40 000 | |
| Non attribué | — | 110 000 |
| Total | 1,5 % | 910 000 |
Compatible avec ton agrégateur de paiement
- KkiaPay
- FedaPay
- CinetPay
Chaque paiement, relié à sa source.
Google Analytics compte des visites. Kauri suit l’argent : chaque transaction réussie est reliée au visiteur qui l’a faite, donc à son canal, ses pages et son pays. Tu sais enfin si tes vidéos TikTok rapportent plus que tes messages WhatsApp.
Voir la comparaison- WhatsApp10 000 FCFA20:06/Moov
- TikTok5 000 FCFAHier 17:24/Wallet
- WhatsApp5 000 FCFAHier 02:40/fonctionnalitesMoov
- Direct15 000 FCFA28/10 14:20/Mobile money (inconnu)
- Direct5 000 FCFA28/10 08:51/blog/dividendes-brvmMoov
Quand 80 % lâchent au paiement.
Le problème n’est pas toujours ta page. Kauri reçoit aussi les paiements échoués et te montre où ça casse : MTN, Moov, carte ou wallet, et pourquoi. Aucun outil d’analytics occidental ne voit les échecs mobile money.
Lire la documentation d’intégrationInstallé en 5 minutes par ton agent IA.
Tu codes avec un agent IA ? Kauri génère un prompt pour ton site. Donne-le à ton agent : il ajoute la balise et relie ton widget de paiement. Ensuite, colle l’URL de webhook Kauri dans ton agrégateur, fais un paiement test, et l’écran confirme : « Paiement attribué à la source TikTok ».
Lire le guide de démarrageAjoute l’analytics Kauri à mon site brvm-tracker.com.
Avant toute modification, cherche « k.js » et « data-site » dans le projet : si la balise Kauri est déjà présente, ne l’ajoute pas une seconde fois.
1. Ajoute la balise sur toutes les pages :
- Vite ou HTML statique : dans le <head> d’index.html, juste avant </head> :
<script defer src="https://kauridata.app/k.js" data-site="ks_8f2a91c4"></script>
- Next.js (App Router) : dans app/layout.tsx, ajoute
import Script from "next/script";
puis, dans <body>, après {children} :
<Script src="https://kauridata.app/k.js" data-site="ks_8f2a91c4" {...(process.env.NODE_ENV === "development" && { "data-debug": "" })} strategy="afterInteractive" />
Pour passer du local à la production sans modifier le code, lis l’origine de Kauri (https://kauridata.app) dans une variable d’environnement (NEXT_PUBLIC_KAURI_URL ou VITE_KAURI_URL) au lieu de l’écrire en dur dans src :
--- a/index.html
+++ b/index.html
@@ <head> @@
- <script defer src="<origine de Kauri>/k.js" …></script>
+ <script defer src="%VITE_KAURI_URL%/k.js" …></script>
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ <body> @@
- <Script src="<origine de Kauri>/k.js" … />
+ <Script src={`${process.env.NEXT_PUBLIC_KAURI_URL}/k.js`} … />
Sans ces variables, l’app se comporte comme avant.
2. Pour que mes visites de développement arrivent (la balise ignore localhost sinon), ajoute l’attribut data-debug en développement seulement, jamais en production, et jamais d’après l’URL de Kauri :
- Next.js : c’est la partie {...(process.env.NODE_ENV === "development" && { "data-debug": "" })} de la balise ci-dessus.
- Vite : ajoute l’attribut data-debug uniquement quand le serveur de développement tourne (pas au build), par exemple avec ce plugin :
--- a/vite.config.ts
+++ b/vite.config.ts
@@ plugins @@
+ {
+ name: "kauri-debug",
+ transformIndexHtml: (html, ctx) =>
+ ctx.server ? html.replace(/<script\b(?=[^>]*\bdata-site=)/, "<script data-debug") : html,
+ },
3. Si le projet a une CSP (en-tête ou balise Content-Security-Policy), ajoute https://kauridata.app à script-src (chargement de k.js) et à connect-src (envoi des pages vues), seulement quand l’origine de Kauri est configurée :
--- a/<fichier de la CSP>
+++ b/<fichier de la CSP>
@@ Content-Security-Policy @@
- script-src 'self';
- connect-src 'self';
+ script-src 'self' https://kauridata.app;
+ connect-src 'self' https://kauridata.app;
Sans CSP, n’en crée pas.
4. Là où le widget de paiement est ouvert, passe l’identifiant visiteur dans le champ de référence (partnerId pour KkiaPay) :
partnerId: window.kauri?.visitorId?.() ?? ""
Si partnerId sert déjà à autre chose (identifiant de commande, par exemple), ne le modifie pas : mes abonnements payés doivent continuer d’être livrés. Passe à l’étape 5.
5. Chemin de secours, seulement si partnerId est déjà pris : attribue le paiement par l’API d’attribution de Kauri.
- À la création de commande, envoie l’identifiant visiteur (window.kauri?.visitorId?.() ?? null) avec la commande. Côté serveur, ne le stocke que s’il respecte /^kv_[0-9A-Za-z]{22}$/, sinon null. Un identifiant absent ou invalide ne doit jamais faire échouer la création de la commande :
--- a/<code client qui crée la commande>
+++ b/<code client qui crée la commande>
@@ corps de la requête @@
+ visitorId: window.kauri?.visitorId?.() ?? null,
--- a/<route de création de commande>
+++ b/<route de création de commande>
@@ création de commande @@
+ const kauriVisitorId = /^kv_[0-9A-Za-z]{22}$/.test(body.visitorId) ? body.visitorId : null;
await db.order.create({ data: { ...order,
+ kauriVisitorId,
} });
- Dans le webhook de paiement, après la vérification de signature (inchangée), appelle POST https://kauridata.app/api/v1/attribution avec l’en-tête authorization: Bearer <KAURI_SITE_SECRET> et le corps { visitorId, transactionId }. Appel non bloquant (after() ou équivalent), AbortSignal.timeout(3000), erreurs avalées et journalisées sans le secret. Un paiement échoué est attribué lui aussi, mais réponds 200 sans livrer : le webhook ne doit pas traiter l’échec comme une livraison, pour qu’un client qui réessaie soit encore activé :
--- a/<route du webhook de paiement>
+++ b/<route du webhook de paiement>
@@ après la vérification de signature @@
+ if (process.env.KAURI_URL && process.env.KAURI_SITE_SECRET && order?.kauriVisitorId) {
+ after(() =>
+ fetch(`${process.env.KAURI_URL}/api/v1/attribution`, {
+ method: "POST",
+ headers: { "content-type": "application/json", authorization: `Bearer ${process.env.KAURI_SITE_SECRET}` },
+ body: JSON.stringify({ visitorId: order.kauriVisitorId, transactionId }),
+ signal: AbortSignal.timeout(3000),
+ }).catch((e) => console.error("kauri attribution", e?.name)),
+ );
+ }
+ if (paiementEchoue) return new Response(null, { status: 200 }); // attribué, mais sans livrer
await fulfillOrder(order);
- Variables : KAURI_URL=https://kauridata.app, KAURI_SITE_ID=<demande-le-moi : je le copie depuis Kauri, Réglages > Agrégateur de paiement>, et KAURI_SITE_SECRET (secret serveur du site, côté serveur uniquement : jamais dans une variable NEXT_PUBLIC_ ou VITE_, jamais journalisé). Tu ne connais pas le secret : demande-moi KAURI_SITE_SECRET ; je le copie depuis Kauri (Réglages > Agrégateur de paiement) et je le mets moi-même dans le .env, sans le coller dans cette conversation. Sans ces variables, l’app se comporte comme avant.
6. Tester un paiement en local : KkiaPay ne peut pas joindre localhost. Expose ton serveur local par un tunnel (ngrok, cloudflared) pour recevoir le webhook de KkiaPay, puis fais-le suivre à Kauri en mode relais (relaie le corps brut avec l’en-tête x-kkiapay-secret) : voir « Ton webhook KkiaPay est déjà utilisé par ton serveur ? » à l’étape 3 de l’installation Kauri.
7. Ne modifie rien d’autre. Montre-moi le diff avant d’appliquer.
8. Après le déploiement, vérifie : ouvre https://brvm-tracker.com puis exécute window.kauri.visitorId() dans la console du navigateur. Il doit renvoyer un identifiant qui commence par kv_ (null en local sans l’attribut data-debug).Les autres outils s’arrêtent avant ton argent.
| Critère | Kauri | Google Analytics | Plausible, Fathom |
|---|---|---|---|
| Relie le trafic aux revenus | Oui | Non | Non |
| Voit les paiements des agrégateurs africains | Oui | Non | Non |
| Montre les paiements mobile money échoués | Oui | Non | Non |
| Prix et paiement en FCFA | Oui | Non | Non |
| Une réponse en 30 secondes | Oui | Usine à gaz | Oui |
Relie le trafic aux revenus
- Kauri
- Oui
- Google Analytics
- Non
- Plausible, Fathom
- Non
Voit les paiements des agrégateurs africains
- Kauri
- Oui
- Google Analytics
- Non
- Plausible, Fathom
- Non
Montre les paiements mobile money échoués
- Kauri
- Oui
- Google Analytics
- Non
- Plausible, Fathom
- Non
Prix et paiement en FCFA
- Kauri
- Oui
- Google Analytics
- Non
- Plausible, Fathom
- Non
Une réponse en 30 secondes
- Kauri
- Oui
- Google Analytics
- Usine à gaz
- Plausible, Fathom
- Oui
En FCFA, payé en mobile money.
14 jours d’essai. Prépaie 3, 6 ou 12 mois pour ne plus penser à l’échéance — l’annuel t’offre 2 mois.
Voir le détail des tarifsQuestions avant d’installer.
Ça marche avec un site codé par un agent IA ?
Oui. Kauri génère un prompt d’installation propre à ton site : tu le donnes à ton agent, il ajoute la balise et l’identifiant visiteur à ton widget de paiement.
Quels agrégateurs de paiement sont compatibles ?
KkiaPay au lancement, puis FedaPay et CinetPay. Tu en utilises un autre ? Dis-le-nous : les demandes décident de l’ordre.
Le champ de référence de mon widget est déjà utilisé.
Ton serveur envoie l’identifiant visiteur et l’identifiant de la transaction à l’API Kauri après le paiement. Une seule requête, documentée pendant l’installation.
Kauri collecte-t-il des données personnelles ?
Aucun nom, téléphone, e-mail ni adresse IP stocké. Un identifiant aléatoire dans un cookie de ton domaine ; le pays est déduit de l’IP, qui n’est pas stockée. Un paragraphe prêt à coller dans ta politique de confidentialité est fourni.
Et si je dépasse mon quota ?
La collecte continue et tu es prévenu. Sans changement de plan sous 14 jours, le tableau de bord se verrouille — tes données ne sont jamais perdues.
Comment je paie Kauri ?
En mobile money ou par carte, en FCFA. Prépayé sur 3, 6 ou 12 mois, ou au mois avec un rappel avant l’échéance.