Skip to Content
Nouvelle documentation Applite - JS SDK, Dart SDK & REST API
JavaScript SDKDuticotac React

Duticotac React

Composants React (Tailwind/Shadcn) pour integrer les paiements Duticotac dans vos applications.

Installation

pnpm add @applite/duticotac-react

C’est tout ! Le SDK core (@applite/duticotac) est inclus et re-exporte automatiquement. Pas besoin de l’installer separement.

Prerequis : React >= 18, Tailwind CSS configure, tokens de couleur Shadcn (primary, border, etc.).

Demarrage rapide

La maniere recommandee d’utiliser ce package est le hook useDuticotac :

import { DuticotacSDK, useDuticotac } from "@applite/duticotac-react"; const sdk = new DuticotacSDK({ apiKey: "your_api_key" }); function CheckoutPage() { const { pay, Dialog } = useDuticotac({ sdk, getTransactionId: async () => "unique-txn-id", }); return ( <> <button onClick={() => pay({ amount: 5000, onSuccess: (tx) => console.log("Confirme:", tx), })}> Acheter </button> {Dialog} </> ); }

Hook useDuticotac (recommande)

Le hook fournit un dialog responsive integre : modal centre sur desktop, bottom sheet sur mobile. Aucune configuration de modal necessaire.

import { DuticotacSDK } from "@applite/duticotac"; import { useDuticotac } from "@applite/duticotac-react"; const sdk = new DuticotacSDK({ apiKey: "your_api_key" }); function CheckoutPage() { const { pay, Dialog, isOpen, close } = useDuticotac({ sdk, providers: ["OM_CI", "MTN_CI", "MOOV_CI", "WAVE_CI"], getTransactionId: async () => { const res = await fetch("/api/init", { method: "POST" }); return (await res.json()).transactionId; }, name: "Jean Dupont", email: "jean@example.com", }); return ( <> <button onClick={() => pay({ amount: 5000, productReference: "premium-monthly", onSuccess: (tx) => console.log("Confirme:", tx), })}> Acheter — 5 000 FCFA </button> {Dialog} </> ); }

Comportement responsive

EcranComportement
Desktop (> 640px)Modal centre, max-width 440px, animation d’echelle
Mobile (<= 640px)Bottom sheet, slide-up depuis le bas, coins arrondis, poignee de drag

Inclus : fermeture par backdrop click, touche Escape, verrouillage du scroll, transitions CSS fluides.

Composants

Pour la plupart des cas, utilisez le hook useDuticotac plutot que les composants directement.

DuticotacPaymentModal

Modal complet : selection provider, telephone, OTP, polling, resultat.

<DuticotacPaymentModal open={open} onClose={() => setOpen(false)} sdk={sdk} amount={5000} providers={["OM_CI", "MTN_CI", "MOOV_CI", "WAVE_CI"]} getTransactionId={getTransactionId} productReference="product-ref" name="Jean Dupont" email="jean@example.com" onSuccess={(tx) => console.log(tx)} />

Integration Shadcn Dialog

import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; <DuticotacPaymentModal open={open} onClose={() => setOpen(false)} sdk={sdk} amount={5000} getTransactionId={getTransactionId} renderModal={({ open, onClose, title, children }) => ( <Dialog open={open} onOpenChange={(v) => { if (!v) onClose(); }}> <DialogContent className="sm:max-w-md"> <DialogHeader> <DialogTitle>{title}</DialogTitle> </DialogHeader> {children} </DialogContent> </Dialog> )} />

Integration Shadcn Drawer (mobile)

import { Drawer, DrawerContent, DrawerHeader, DrawerTitle } from "@/components/ui/drawer"; <DuticotacPaymentModal open={open} onClose={() => setOpen(false)} sdk={sdk} amount={5000} getTransactionId={getTransactionId} renderModal={({ open, onClose, title, children }) => ( <Drawer open={open} onOpenChange={(v) => { if (!v) onClose(); }}> <DrawerContent> <DrawerHeader> <DrawerTitle>{title}</DrawerTitle> </DrawerHeader> <div className="px-4 pb-6">{children}</div> </DrawerContent> </Drawer> )} />

ResponsiveDialog

Dialog responsive : modal centre sur desktop, bottom sheet sur mobile. Utilise par useDuticotac.

import { ResponsiveDialog } from "@applite/duticotac-react"; <ResponsiveDialog open={isOpen} onClose={() => setOpen(false)} title="Mon dialog" > <p>Contenu</p> </ResponsiveDialog>

ProviderSelector

Grille de selection de provider avec logos.

import { ProviderSelector } from "@applite/duticotac-react"; <ProviderSelector providers={["OM_CI", "MTN_CI", "MOOV_CI", "WAVE_CI"]} value={provider} onChange={setProvider} />

PhoneInput

Champ telephone avec prefixe +225 (Cote d’Ivoire).

import { PhoneInput } from "@applite/duticotac-react"; <PhoneInput value={phone} onChange={setPhone} error={phoneError} autoFocus />

OtpInput

Saisie de code OTP a 4 chiffres (Orange Money). Auto-focus, collage, navigation clavier.

import { OtpInput } from "@applite/duticotac-react"; <OtpInput value={otp} onChange={setOtp} />

TransactionStatus

Affichage du statut : polling (spinner + compteur), succes, ou erreur.

import { TransactionStatus } from "@applite/duticotac-react"; // Polling <TransactionStatus status="polling" elapsedSeconds={42} /> // Succes <TransactionStatus status="success" message="500 credits ajoutes." onClose={close} /> // Erreur <TransactionStatus status="error" errorMessage="Echec." onRetry={retry} onClose={close} />

Providers supportes

CodeNomOTPPrefixeParticularite
OM_CIOrange MoneyOui (4 chiffres)07#144*82# pour le code OTP
MTN_CIMTN MoMoNon05Confirmation sur telephone
MOOV_CIMoov (Flooz)Non01Confirmation sur telephone
WAVE_CIWaveNonTousOuvre un onglet navigateur
CREDIT_CARDCarte de creditNonA venir
CASHEspecesNonPaiement en main propre
IAPAchat IntegreNonIn-App Purchase

Utilitaires

import { validatePhone, // Validation telephone par provider normalizePhone, // "+2250701020304" getPhoneRegex, // Regex par provider needsOtp, // true pour OM_CI formatCFA, // 5000 → "5 000" cn, // Merge classes Tailwind } from "@applite/duticotac-react";

Comportement du polling

  • Backoff exponentiel : 1s → 2s → 3s → 5s → 8s
  • Timeout : 90s par defaut (configurable)
  • Tab-aware : Pause quand l’onglet est cache, reprend au retour
  • Compteur : “Verification en cours… 42s”
  • Wave : Ouvre automatiquement l’URL de paiement dans un nouvel onglet

Gestion des erreurs

Les erreurs du SDK sont automatiquement affichees en francais dans le modal :

CodeMessage
otp-requiredCode OTP requis pour les paiements Orange Money
payment-failedEchec du paiement
payment-cancelledPaiement annule
polling-timeoutTemps d’attente de la transaction expire
phone-requiredNumero de telephone requis
unknown-errorUne erreur inconnue est survenue
Last updated on