@inopay/web-react
v0.1.0-alpha.1
Published
Adapter React pour @inopay/web — composant <InopayInvest /> drop-in pour le parcours investisseur Inopay (BRVM/BVMAC/GSE).
Maintainers
Readme
@inopay/web-react
Adapter React pour @inopay/web/ui. Composant <InopayInvest /> drop-in pour embarquer le parcours d'investissement Inopay (14 écrans, BRVM/BVMAC/GSE) dans n'importe quelle app React.
Installation
npm install @inopay/web @inopay/web-react
# ou
pnpm add @inopay/web @inopay/web-react
# ou
yarn add @inopay/web @inopay/web-reactreact@>=17 est en peer dep.
Usage minimal
import { InopayInvest } from '@inopay/web-react';
export function InvestRoute() {
const userToken = useUserJwt(); // JWT de l'app partenaire pour l'utilisateur connecté
return (
<InopayInvest
userToken={userToken}
partnerKey="banque-atlas"
style={{ minHeight: 720 }}
/>
);
}C'est tout. Le SDK fetch automatiquement la config theming depuis https://api.getinopay.com/v1/embed-theme/banque-atlas, monte les 14 écrans dans un Web Component (Shadow DOM, isolation CSS totale), et gère le parcours complet jusqu'au reçu signé Ed25519.
Theming
Pour overrider la palette (sans aller-retour réseau au mount) :
<InopayInvest
userToken={token}
partnerKey="banque-atlas"
theme={{
primary: '#1B3A5C',
primaryDark: '#10243B',
accent: '#D4942F',
onPrimary: '#FFFFFF',
partnerName: 'Banque Atlas',
logoUrl: 'https://cdn.banque-atlas.com/logo.svg',
font: 'Inter, system-ui, sans-serif',
}}
/>Le composant re-fetch automatiquement le theme si la prop theme change (deep equality via JSON.stringify).
Callbacks
<InopayInvest
userToken={token}
partnerKey="banque-atlas"
onOrderPlaced={(order) => {
analytics.track('inopay_order_placed', { id: order.id, total: order.total });
showToast(`Ordre #${order.id} passé`);
}}
onConsentRevoked={() => router.push('/settings/broker')}
onComplete={(result) => {
if (result.reason === 'completed') router.push('/portfolio');
}}
/>Contrôle impératif (deep-link)
Pour naviguer en deep-link (depuis une notification, un bouton custom, etc.) :
import { useRef } from 'react';
import { InopayInvest, type FlowHandle } from '@inopay/web-react';
export function InvestRoute() {
const flowRef = useRef<FlowHandle | null>(null);
return (
<>
<button onClick={() => flowRef.current?.openTo('portfolio')}>
Voir mon portefeuille
</button>
<InopayInvest
flowRef={flowRef}
userToken={token}
partnerKey="banque-atlas"
initialScreen="markets" /* skip welcome pour user revenant */
/>
</>
);
}Méthodes exposées sur flowRef.current :
openTo(screen)— navigue immédiatement vers un écran (auto-populate ctx avec defaults si nécessaire)refreshTheme()— re-fetch/v1/embed-theme/:partnerKeyunmount()— teardown manuel
Écrans disponibles (14)
Golden path : welcome, risk-profile, kyc-accelere, consent, markets, instrument, order, confirmation, receipt, portfolio
Edge cases : kyc-incomplete, order-rejected, market-closed, revoke
Tous les écrans suivent le design Tangerine-inspired Inopay : KYC réutilisé visuellement (speed pill + import counter + chain Ed25519), frais ventilés systématiques, SGI exécutante nommée à 4 endroits, reçu signé Ed25519 avec lien vérification offline.
Props
interface InopayInvestProps {
// Required
userToken: string; // JWT utilisateur de l'app partenaire
partnerKey: string; // tenant code (ex : 'banque-atlas')
// Optional config
apiBaseUrl?: string; // default 'https://api.getinopay.com'
theme?: Partial<InopayTheme>; // override le fetch automatique
locale?: 'fr' | 'en' | 'pt'; // v0.2 ships 'fr' only
initialScreen?: ScreenId; // default 'welcome'
// Callbacks
onComplete?: (result: FlowResult) => void;
onOrderPlaced?: (order: Order) => void;
onConsentRevoked?: () => void;
// React-specific
className?: string;
style?: CSSProperties;
flowRef?: MutableRefObject<FlowHandle | null>;
}Architecture
<InopayInvest /> est un thin wrapper autour de mountInvest() exposé par @inopay/web/ui. La vraie UI est rendue par le Custom Element <inopay-invest> (Web Component avec Shadow DOM). React orchestre le mount/unmount + props propagation.
Avantages :
- Aucun risque de collision CSS entre Inopay et le reste de l'app partenaire (Shadow DOM)
- Aucune dépendance React dans le bundle Inopay (le partenaire l'importe via peer)
- ~1.5 KB minified pour ce package (toute la logique UI vit dans
@inopay/web/ui, ~62 KB)
Pattern inspiré de @stripe/react-stripe-js qui wrappe @stripe/stripe-js.
Server-side rendering (Next.js, Remix)
Le composant doit s'hydrater côté client uniquement (Web Components nécessitent customElements). Pour Next.js App Router :
'use client';
import { InopayInvest } from '@inopay/web-react';
// ...Pour Pages Router avec next/dynamic :
import dynamic from 'next/dynamic';
const InopayInvest = dynamic(
() => import('@inopay/web-react').then(m => m.InopayInvest),
{ ssr: false }
);Versions
0.1.0-alpha.1— première publication (matching@inopay/[email protected]).
License
MIT — © Inopay. Voir getinopay.com pour les ToS partenaires.
