UNPKG

ynkap-payment

Version:

Module de paiement Y-Nkap pour Angular - Intégration simple des paiements mobiles (Orange Money, MTN Mobile Money)

1,382 lines (1,110 loc) 37.5 kB
# 💳 Y-Nkap Payment Module for Angular [![npm version](https://badge.fury.io/js/ynkap-payment.svg)](https://badge.fury.io/js/ynkap-payment) [![Angular](https://img.shields.io/badge/Angular-16%2B-red.svg)](https://angular.io/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue.svg)](https://www.typescriptlang.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) Le module Y-Nkap pour Angular offre une **intégration simple et robuste** des paiements mobiles (Orange Money, MTN Mobile Money) dans vos applications Angular. Développé par **SIEWE FORTUNE**, ce module fournit une solution complète avec gestion avancée des erreurs, retry automatique, notifications élégantes, et interface utilisateur optimisée. ## **Fonctionnalités principales** **Intégration en une ligne** : Composant `<ynkap-pay-button>` prêt à l'emploi **Interface moderne** : Modale responsive avec thèmes light/dark **Retry intelligent** : Gestion automatique des erreurs avec backoff exponentiel **Notifications élégantes** : Cards de notification positionnées à droite **Confirmations d'annulation** : Interface de confirmation pour les annulations **Messages user-friendly** : Séparation messages techniques/utilisateur **Sécurisé** : Authentification par clés API, validation stricte **Mobile-first** : Optimisé pour Orange Money et MTN Mobile Money **TypeScript** : Support complet avec types stricts **Architecture modulaire** : Services séparés et réutilisables ## **Table des matières** - [Installation](#-installation) - [Configuration](#-configuration) - [Utilisation rapide](#-utilisation-rapide) - [Composants disponibles](#-composants-disponibles) - [Services et API](#-services-et-api) - [Gestion des erreurs](#-gestion-des-erreurs) - [Notifications et confirmations](#-notifications-et-confirmations) - [Personnalisation](#-personnalisation) - [Exemples avancés](#-exemples-avancés) - [Architecture](#-architecture) - [Support](#-support) --- ## 📦 **Installation** ### Prérequis - Angular 16+ - TypeScript 5.0+ - Node.js 18+ ### Installation via npm ```bash npm install ynkap-payment --save ``` ### Installation via yarn ```bash yarn add ynkap-payment ``` --- ## ⚙️ **Configuration** ### 1. Import du module Importez `YnkapModule` dans votre module principal : ```typescript // app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { YnkapModule } from 'ynkap-payment'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, BrowserAnimationsModule, // Requis pour les animations // Configuration Y-Nkap YnkapModule.forRoot({ apiKey: 'your-api-key', apiSecret: 'your-api-secret', merchantId: 'your-merchant-id', environment: 'sandbox' // 'sandbox' | 'production' }) ], bootstrap: [AppComponent] }) export class AppModule { } ``` ### 2. Configuration des environnements ```typescript // environments/environment.ts export const environment = { production: false, ynkap: { apiKey: 'sandbox-api-key', apiSecret: 'sandbox-api-secret', merchantId: 'sandbox-merchant-id', environment: 'sandbox' as const } }; // environments/environment.prod.ts export const environment = { production: true, ynkap: { apiKey: 'prod-api-key', apiSecret: 'prod-api-secret', merchantId: 'prod-merchant-id', environment: 'production' as const } }; ``` ### 3. Configuration dynamique ```typescript import { ConfigurationService } from 'ynkap-payment'; constructor(private ynkapConfig: ConfigurationService) {} ngOnInit() { // Configuration à l'exécution this.ynkapConfig.initialize({ apiKey: 'dynamic-api-key', apiSecret: 'dynamic-api-secret', merchantId: 'dynamic-merchant-id', environment: 'production' }); } ``` --- ## 🚀 **Utilisation rapide** ### Exemple minimal ```html <!-- Utilisation la plus simple --> <ynkap-pay-button [amount]="1000" [currency]="'XAF'" merchantReference="ORDER-123" description="Achat produit" (paymentSuccess)="onSuccess($event)" (paymentError)="onError($event)" (paymentCancel)="onCancel()"> <img src="assets/logo-y-nkap.jpg" alt="Y-Nkap" class="ynkap-logo"> Payer 1000 XAF </ynkap-pay-button> ``` ```typescript import { Component } from '@angular/core'; import { PaymentResponse, YnkapError } from 'ynkap-payment'; @Component({ selector: 'app-payment', template: ` <div class="payment-container"> <h2>Paiement sécurisé</h2> <ynkap-pay-button [amount]="1000" [currency]="'XAF'" merchantReference="ORDER-123" description="Achat d'un produit de démonstration" [theme]="'light'" (paymentSuccess)="onSuccess($event)" (paymentError)="onError($event)" (paymentCancel)="onCancel()"> <img src="assets/logo-y-nkap.jpg" alt="Y-Nkap" class="ynkap-logo"> Payer avec Y-Nkap </ynkap-pay-button> </div> ` }) export class PaymentComponent { onSuccess(response: PaymentResponse): void { console.log('Paiement réussi:', response); // Redirection vers page de succès // this.router.navigate(['/success']); } onError(error: YnkapError): void { console.error('Erreur de paiement:', error); // Les notifications d'erreur s'affichent automatiquement // Pas besoin d'action supplémentaire } onCancel(): void { console.log('Paiement annulé par l\'utilisateur'); // Gérer l'annulation si nécessaire } } ``` --- ## 🧩 **Composants disponibles** ### 1. **YnkapPayButtonComponent** Le composant principal qui affiche un bouton de paiement avec modale intégrée. ```html <ynkap-pay-button [amount]="montant" [currency]="'XAF'" [merchantReference]="reference" [description]="description" [theme]="'light'" [primaryColor]="'#007bff'" (paymentSuccess)="onSuccess($event)" (paymentError)="onError($event)" (paymentCancel)="onCancel()"> <!-- Contenu personnalisé du bouton --> <span class="custom-button-content"> <i class="fas fa-credit-card"></i> Payer maintenant </span> </ynkap-pay-button> ``` #### **Propriétés d'entrée (Inputs)** | Propriété | Type | Requis | Description | |-----------|------|--------|-------------| | `amount` | `number` | | Montant à payer | | `currency` | `string` | | Devise (défaut: 'XAF') | | `merchantReference` | `string` | | Référence unique du marchand | | `description` | `string` | | Description du paiement | | `theme` | `'light' \| 'dark'` | | Thème de l'interface (défaut: 'light') | | `primaryColor` | `string` | | Couleur principale personnalisée | #### **Événements de sortie (Outputs)** | Événement | Type | Description | |-----------|------|-------------| | `paymentSuccess` | `PaymentResponse` | Émis lors d'un paiement réussi | | `paymentError` | `YnkapError` | Émis lors d'une erreur de paiement | | `paymentCancel` | `void` | Émis lors de l'annulation du paiement | ### 2. **PaymentComponent** (Interne) Composant de formulaire de paiement utilisé à l'intérieur de la modale. Généralement pas utilisé directement. --- ## 🔧 **Services et API** ### 1. **PaymentService** Service principal pour gérer les paiements. ```typescript import { PaymentService, PaymentRequest } from 'ynkap-payment'; constructor(private paymentService: PaymentService) {} // Initier un paiement initiatePayment() { const request: PaymentRequest = { amount: 1000, currency: 'XAF', merchantReference: 'ORDER-123', description: 'Achat produit', customer: { phone: '677123456', name: 'John Doe', email: 'john@example.com' } }; this.paymentService.initiatePayment(request).subscribe({ next: (response) => console.log('Paiement initié:', response), error: (error) => console.error('Erreur:', error) }); } // Obtenir les méthodes de paiement disponibles getPaymentMethods() { this.paymentService.availablePaymentMethods$.subscribe( methods => console.log('Méthodes disponibles:', methods) ); } // Historique des transactions getTransactionHistory() { this.paymentService.transactionHistory$.subscribe( history => console.log('Historique:', history) ); } ``` ### 2. **ConfigurationService** Service pour gérer la configuration de l'API. ```typescript import { ConfigurationService } from 'ynkap-payment'; constructor(private configService: ConfigurationService) {} // Vérifier si le module est initialisé checkInitialization() { if (this.configService.isInitialized()) { console.log('Y-Nkap est configuré'); } else { console.log('Configuration requise'); } } // Obtenir la configuration actuelle getCurrentConfig() { const config = this.configService.currentConfig; console.log('Configuration actuelle:', config); } // Mettre à jour la configuration updateConfig() { this.configService.updateConfig({ environment: 'production' }); } ``` ### 3. **NotificationService** Service pour afficher des notifications élégantes. ```typescript import { NotificationService } from 'ynkap-payment'; constructor(private notificationService: NotificationService) {} // Afficher une notification de succès showSuccess() { this.notificationService.showSuccess( 'Paiement réussi', 'Votre transaction a été traitée avec succès.' ); } // Afficher une notification d'erreur showError() { this.notificationService.showError( 'Paiement échoué', 'Une erreur est survenue lors du traitement.' ); } // Afficher une notification d'information showInfo() { this.notificationService.showInfo( 'Information', 'Votre paiement est en cours de traitement.' ); } ``` ### 4. **ConfirmationService** Service pour afficher des dialogues de confirmation. ```typescript import { ConfirmationService } from 'ynkap-payment'; constructor(private confirmationService: ConfirmationService) {} // Confirmation d'annulation de paiement confirmCancelPayment() { this.confirmationService.confirmCancelPayment().subscribe(confirmed => { if (confirmed) { console.log('Paiement annulé'); } else { console.log('Annulation annulée'); } }); } // Confirmation personnalisée customConfirmation() { this.confirmationService.confirm({ title: 'Confirmer l\'action', message: 'Êtes-vous sûr de vouloir continuer ?', confirmText: 'Oui, continuer', cancelText: 'Annuler' }).subscribe(confirmed => { console.log('Réponse:', confirmed); }); } ``` --- ## ⚠️ **Gestion des erreurs** ### Types d'erreurs Le module Y-Nkap utilise une classe `YnkapError` personnalisée qui sépare les messages techniques des messages utilisateur : ```typescript interface YnkapError extends Error { code: string; // Code d'erreur technique message: string; // Message technique (pour les logs) userMessage: string; // Message convivial pour l'utilisateur retryable?: boolean; // Indique si l'erreur est retryable transactionId?: string; // ID de transaction si disponible details?: any; // Détails supplémentaires } ``` ### Codes d'erreur courants | Code | Description | Retryable | Message utilisateur | |------|-------------|-----------|-------------------| | `AUTH_ERROR` | Clé API non configurée | | "Paiement échoué, veuillez réessayer" | | `NETWORK_ERROR` | Problème de connexion | | "Problème de connexion, veuillez réessayer" | | `PAYMENT_ERROR` | Erreur générique de paiement | | "Paiement échoué, veuillez réessayer" | | `INSUFFICIENT_FUNDS` | Solde insuffisant | | "Solde insuffisant" | | `PAYMENT_DECLINED` | Paiement refusé | | "Paiement refusé par votre opérateur" | | `INVALID_PHONE` | Numéro invalide | | "Numéro de téléphone invalide" | ### Gestion avancée des erreurs ```typescript import { YnkapError, ErrorCategory } from 'ynkap-payment'; export class PaymentComponent { handleError(error: YnkapError): void { // Log du message technique pour debugging console.error('Technical Error:', error.getTechnicalMessage()); // Affichage du message utilisateur console.log('User Message:', error.getUserMessage()); // Gestion par catégorie switch (error.code) { case 'AUTH_ERROR': // Erreur de configuration - notifier l'équipe technique this.notifyTechnicalTeam(error); break; case 'NETWORK_ERROR': // Erreur réseau - retry automatique géré par le module break; case 'PAYMENT_DECLINED': // Paiement refusé - proposer une autre méthode this.suggestAlternativeMethod(); break; default: // Erreur générique break; } // Les notifications d'erreur s'affichent automatiquement // Pas besoin d'action supplémentaire } private notifyTechnicalTeam(error: YnkapError): void { // Envoyer l'erreur technique à votre système de monitoring this.monitoringService.logError({ message: error.getTechnicalMessage(), code: error.code, timestamp: new Date(), context: 'Y-Nkap Payment' }); } } ``` ### Système de retry automatique Le module inclut un système de retry intelligent : ```typescript // Configuration du retry (automatique) const retryConfig = { maxRetries: 3, baseDelayMs: 1000, maxDelayMs: 10000, backoffMultiplier: 2 }; // Le retry est automatique pour les erreurs retryables // L'utilisateur voit un bouton "Réessayer" après que la notification ait disparu ``` --- ## 🔔 **Notifications et confirmations** ### Notifications automatiques Le module affiche automatiquement des notifications élégantes pour tous les événements : - **Succès** : Notification verte à droite de l'écran - **Erreur** : Notification rouge à droite de l'écran - **Information** : Notification bleue à droite de l'écran ```typescript // Les notifications s'affichent automatiquement // Aucune configuration supplémentaire requise // Pour des notifications personnalisées : import { NotificationService } from 'ynkap-payment'; constructor(private notificationService: NotificationService) {} showCustomNotification() { this.notificationService.showSuccess( 'Commande validée', 'Votre commande a été enregistrée avec succès.', 7000 // Durée en ms (optionnel) ); } ``` ### Confirmations d'annulation Le module demande automatiquement confirmation avant d'annuler un paiement : ```typescript // Confirmation automatique lors de : // - Clic sur le bouton X de fermeture // - Clic sur "Retour" avec des données saisies // - Événement d'annulation // Pour des confirmations personnalisées : import { ConfirmationService } from 'ynkap-payment'; constructor(private confirmationService: ConfirmationService) {} showCustomConfirmation() { this.confirmationService.confirm({ title: 'Supprimer l\'élément', message: 'Cette action est irréversible. Continuer ?', confirmText: 'Supprimer', cancelText: 'Annuler' }).subscribe(confirmed => { if (confirmed) { // Action confirmée } }); } ``` ### Timing des notifications Le module gère intelligemment l'affichage des éléments : 1. **Erreur de paiement** Notification d'erreur apparaît à droite 2. **Immédiatement** Section d'erreur dans le formulaire masquée 3. **Après 5 secondes** Notification disparaît automatiquement 4. **Après 5.5 secondes** Section d'erreur avec bouton "Réessayer" apparaît Cela évite les conflits visuels et offre une expérience utilisateur fluide. --- ## 🎨 **Personnalisation** ### Thèmes Le module supporte deux thèmes prédéfinis : ```html <!-- Thème clair (défaut) --> <ynkap-pay-button [theme]="'light'" [amount]="1000"> Payer avec thème clair </ynkap-pay-button> <!-- Thème sombre --> <ynkap-pay-button [theme]="'dark'" [amount]="1000"> Payer avec thème sombre </ynkap-pay-button> ``` ### Couleurs personnalisées ```html <ynkap-pay-button [amount]="1000" [primaryColor]="'#28a745'" [theme]="'light'"> Payer avec couleur personnalisée </ynkap-pay-button> ``` ### Contenu du bouton personnalisé ```html <ynkap-pay-button [amount]="1000"> <!-- Contenu HTML personnalisé --> <div class="custom-button-content"> <img src="assets/payment-icon.svg" alt="Paiement"> <span class="amount">{{ amount | currency:'XAF' }}</span> <span class="text">Payer maintenant</span> </div> </ynkap-pay-button> ``` ### Styles CSS personnalisés ```css /* Personnalisation du bouton */ ynkap-pay-button .ynkap-pay-button { border-radius: 25px; font-weight: bold; text-transform: uppercase; letter-spacing: 1px; } /* Personnalisation de la modale */ ynkap-pay-button .ynkap-modal { border-radius: 20px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); } /* Personnalisation des notifications */ .ynkap-notification-card { border-radius: 15px; backdrop-filter: blur(10px); } ``` --- ## 📋 **Interfaces TypeScript** ### PaymentRequest ```typescript interface PaymentRequest { amount: number; // Montant en centimes currency: string; // Code devise (XAF, EUR, USD) merchantReference: string; // Référence unique du marchand description?: string; // Description du paiement customer?: { phone: string; // Numéro de téléphone name?: string; // Nom du client email?: string; // Email du client }; metadata?: Record<string, any>; // Métadonnées personnalisées } ``` ### PaymentResponse ```typescript interface PaymentResponse { status: 'success' | 'pending' | 'failed'; transaction?: PaymentTransaction; error?: YnkapError; message?: string; } ``` ### PaymentTransaction ```typescript interface PaymentTransaction { id: string; // ID unique de la transaction merchantReference: string; // Référence du marchand amount: number; // Montant currency: string; // Devise status: TransactionStatus; // Statut de la transaction paymentMethod: PaymentMethod; // Méthode de paiement utilisée customer: { phone: string; name?: string; email?: string; }; createdAt: Date; // Date de création updatedAt: Date; // Dernière mise à jour metadata?: Record<string, any>; // Métadonnées } ``` ### PaymentMethod ```typescript interface PaymentMethod { id: string; // Identifiant unique name: string; // Nom affiché type: 'mobile_money'; // Type de paiement provider: 'mtn' | 'orange'; // Fournisseur icon: string; // URL de l'icône enabled: boolean; // Disponibilité fees?: { fixed?: number; // Frais fixes percentage?: number; // Pourcentage }; } ``` ### ApiConfig ```typescript interface ApiConfig { apiKey: string; // Clé API Y-Nkap apiSecret: string; // Secret API Y-Nkap merchantId: string; // ID du marchand environment: 'sandbox' | 'production'; // Environnement baseUrl?: string; // URL de base personnalisée timeout?: number; // Timeout des requêtes (ms) } ``` ### YnkapError ```typescript interface YnkapError extends Error { code: string; // Code d'erreur message: string; // Message technique userMessage: string; // Message pour l'utilisateur retryable?: boolean; // Peut être retryé transactionId?: string; // ID de transaction details?: any; // Détails supplémentaires // Méthodes getUserMessage(): string; // Message utilisateur getTechnicalMessage(): string; // Message technique } ``` ``` --- ## 💡 **Exemples avancés** ### 1. Intégration avec un panier e-commerce ```typescript import { Component } from '@angular/core'; import { PaymentResponse, YnkapError } from 'ynkap-payment'; @Component({ selector: 'app-checkout', template: ` <div class="checkout-container"> <div class="order-summary"> <h3>Résumé de la commande</h3> <div class="items"> <div *ngFor="let item of cartItems" class="item"> <span>{{ item.name }}</span> <span>{{ item.price | currency:'XAF' }}</span> </div> </div> <div class="total"> <strong>Total: {{ getTotal() | currency:'XAF' }}</strong> </div> </div> <div class="payment-section"> <ynkap-pay-button [amount]="getTotal()" [currency]="'XAF'" [merchantReference]="orderId" [description]="getOrderDescription()" [theme]="'light'" (paymentSuccess)="onPaymentSuccess($event)" (paymentError)="onPaymentError($event)" (paymentCancel)="onPaymentCancel()"> <div class="payment-button-content"> <i class="fas fa-lock"></i> Paiement sécurisé </div> </ynkap-pay-button> </div> </div> ` }) export class CheckoutComponent { cartItems = [ { name: 'Produit 1', price: 5000 }, { name: 'Produit 2', price: 3000 }, { name: 'Livraison', price: 1000 } ]; orderId = `ORDER-${Date.now()}`; getTotal(): number { return this.cartItems.reduce((sum, item) => sum + item.price, 0); } getOrderDescription(): string { return `Commande ${this.orderId} - ${this.cartItems.length} article(s)`; } onPaymentSuccess(response: PaymentResponse): void { // 1. Sauvegarder la transaction this.saveOrder(response.transaction); // 2. Vider le panier this.clearCart(); // 3. Envoyer email de confirmation this.sendConfirmationEmail(response.transaction); // 4. Rediriger vers page de succès this.router.navigate(['/order-success'], { queryParams: { orderId: this.orderId } }); } onPaymentError(error: YnkapError): void { // Analytics pour tracking des erreurs this.analytics.track('payment_error', { error_code: error.code, order_id: this.orderId, amount: this.getTotal() }); } onPaymentCancel(): void { // Analytics pour tracking des abandons this.analytics.track('payment_cancelled', { order_id: this.orderId, amount: this.getTotal() }); } } ``` ### 2. Gestion des abonnements récurrents ```typescript @Component({ selector: 'app-subscription', template: ` <div class="subscription-plans"> <div *ngFor="let plan of plans" class="plan-card"> <h3>{{ plan.name }}</h3> <div class="price">{{ plan.price | currency:'XAF' }}/mois</div> <ynkap-pay-button [amount]="plan.price" [merchantReference]="generateSubscriptionRef(plan)" [description]="'Abonnement ' + plan.name" (paymentSuccess)="onSubscriptionPayment($event, plan)"> S'abonner </ynkap-pay-button> </div> </div> ` }) export class SubscriptionComponent { plans = [ { id: 'basic', name: 'Basic', price: 5000 }, { id: 'premium', name: 'Premium', price: 10000 }, { id: 'enterprise', name: 'Enterprise', price: 20000 } ]; generateSubscriptionRef(plan: any): string { return `SUB-${plan.id}-${this.userId}-${Date.now()}`; } onSubscriptionPayment(response: PaymentResponse, plan: any): void { // Créer l'abonnement this.subscriptionService.createSubscription({ userId: this.userId, planId: plan.id, transactionId: response.transaction?.id, startDate: new Date(), status: 'active' }).subscribe(() => { // Programmer les paiements récurrents this.scheduleRecurringPayments(plan); }); } } ``` ### 3. Intégration avec un système de wallet ```typescript @Component({ selector: 'app-wallet', template: ` <div class="wallet-container"> <div class="balance"> <h3>Solde actuel</h3> <div class="amount">{{ balance | currency:'XAF' }}</div> </div> <div class="recharge-section"> <h4>Recharger le wallet</h4> <div class="amount-buttons"> <button *ngFor="let amount of rechargeAmounts" (click)="rechargeWallet(amount)" class="amount-btn"> {{ amount | currency:'XAF' }} </button> </div> <div class="custom-amount"> <input [(ngModel)]="customAmount" type="number" placeholder="Montant personnalisé"> <ynkap-pay-button [amount]="customAmount" [merchantReference]="generateRechargeRef()" [description]="'Recharge wallet'" (paymentSuccess)="onRechargeSuccess($event)"> Recharger </ynkap-pay-button> </div> </div> </div> ` }) export class WalletComponent { balance = 0; customAmount = 0; rechargeAmounts = [1000, 5000, 10000, 25000, 50000]; rechargeWallet(amount: number): void { const ref = this.generateRechargeRef(); // Utiliser le service directement pour plus de contrôle this.paymentService.initiatePayment({ amount: amount, currency: 'XAF', merchantReference: ref, description: `Recharge wallet - ${amount} XAF`, customer: { phone: this.userService.currentUser.phone, name: this.userService.currentUser.name } }).subscribe({ next: (response) => this.handleRechargeResponse(response), error: (error) => this.handleRechargeError(error) }); } onRechargeSuccess(response: PaymentResponse): void { // Mettre à jour le solde this.balance += response.transaction?.amount || 0; // Sauvegarder en base this.walletService.updateBalance(this.balance); // Notification de succès this.notificationService.showSuccess( 'Recharge réussie', `Votre wallet a été rechargé de ${response.transaction?.amount} XAF` ); } generateRechargeRef(): string { return `WALLET-${this.userId}-${Date.now()}`; } } ``` --- ## 🏗️ **Architecture** ### Structure modulaire ``` ynkap-payment/ ├── src/ ├── lib/ ├── ynkap.module.ts # Module principal ├── configuration/ # Configuration API ├── configuration.service.ts └── models/ ├── payment/ # Services de paiement ├── payment.service.ts ├── payment/ # Composant formulaire ├── retry/ # Système de retry └── models/ ├── pay-button/ # Composant bouton ├── pay-button.component.ts └── pay-button.component.html ├── notification/ # Système de notifications ├── notification.service.ts └── notification.component.ts ├── confirmation/ # Dialogues de confirmation ├── confirmation.service.ts └── confirmation.component.ts ├── auth/ # Authentification └── auth.service.ts └── error-handling/ # Gestion d'erreurs ├── error-handling.service.ts └── models/ └── public-api.ts # Exports publics ``` ### Flux de données ```mermaid graph TD A[PayButtonComponent] --> B[PaymentService] B --> C[AuthService] B --> D[ConfigurationService] B --> E[API Y-Nkap] F[PaymentComponent] --> B F --> G[NotificationService] F --> H[ConfirmationService] I[RetryService] --> B J[ErrorHandlingService] --> G E --> K[PaymentResponse] K --> L[Success/Error Events] ``` ### Services principaux | Service | Responsabilité | Singleton | |---------|----------------|-----------| | `ConfigurationService` | Gestion de la configuration API | | | `PaymentService` | Logique métier des paiements | | | `AuthService` | Authentification avec l'API | | | `NotificationService` | Affichage des notifications | | | `ConfirmationService` | Dialogues de confirmation | | | `RetryService` | Gestion des tentatives | | | `ErrorHandlingService` | Traitement des erreurs | | ### Cycle de vie d'un paiement 1. **Initialisation** : Configuration du module avec les clés API 2. **Déclenchement** : Clic sur le bouton de paiement 3. **Authentification** : Vérification des credentials 4. **Sélection méthode** : Choix MTN/Orange Money 5. **Saisie données** : Numéro de téléphone 6. **Validation** : Contrôles côté client 7. **Envoi API** : Requête vers Y-Nkap 8. **Traitement** : Gestion de la réponse 9. **Notification** : Affichage du résultat 10. **Retry** : En cas d'erreur retryable --- ## 🔧 **Configuration avancée** ### Variables d'environnement ```typescript // environment.ts export const environment = { production: false, ynkap: { apiKey: process.env['YNKAP_API_KEY'] || 'sandbox-key', apiSecret: process.env['YNKAP_API_SECRET'] || 'sandbox-secret', merchantId: process.env['YNKAP_MERCHANT_ID'] || 'sandbox-merchant', environment: 'sandbox' as const, // Configuration avancée timeout: 30000, // 30 secondes retryAttempts: 3, retryDelay: 1000, enableLogging: true, enableAnalytics: false } }; ``` ### Configuration du module ```typescript // app.module.ts import { YnkapModule } from 'ynkap-payment'; import { environment } from './environments/environment'; @NgModule({ imports: [ YnkapModule.forRoot({ ...environment.ynkap, // Intercepteurs personnalisés interceptors: [ CustomAuthInterceptor, LoggingInterceptor ], // Configuration des notifications notifications: { position: 'top-right', duration: 5000, enableSound: false }, // Configuration des confirmations confirmations: { theme: 'modern', enableBackdropClick: false } }) ] }) export class AppModule { } ``` ### Personnalisation des styles ```scss // styles.scss // Variables Y-Nkap :root { --ynkap-primary-color: #007bff; --ynkap-success-color: #28a745; --ynkap-error-color: #dc3545; --ynkap-warning-color: #ffc107; --ynkap-border-radius: 8px; --ynkap-box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); --ynkap-transition: all 0.3s ease; } // Thème sombre [data-theme="dark"] { --ynkap-bg-color: #1a1a1a; --ynkap-text-color: #ffffff; --ynkap-border-color: #333333; } // Personnalisation du bouton .ynkap-pay-button { background: linear-gradient(135deg, var(--ynkap-primary-color), #0056b3); border: none; border-radius: var(--ynkap-border-radius); box-shadow: var(--ynkap-box-shadow); transition: var(--ynkap-transition); &:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); } } // Personnalisation de la modale .ynkap-modal { border-radius: 16px; backdrop-filter: blur(10px); .ynkap-modal-header { background: linear-gradient(135deg, #f8f9fa, #e9ecef); } } // Personnalisation des notifications .ynkap-notification-card { border-radius: 12px; backdrop-filter: blur(20px); border: 1px solid rgba(255, 255, 255, 0.2); &.ynkap-notification-success { background: linear-gradient(135deg, #d4edda, #c3e6cb); } &.ynkap-notification-error { background: linear-gradient(135deg, #f8d7da, #f5c6cb); } } ``` --- ## 🧪 **Tests et développement** ### Tests unitaires Le module Y-Nkap inclut une suite de tests complète : ```bash # Lancer tous les tests npm test # Tests avec couverture npm run test:coverage # Tests en mode watch npm run test:watch ``` ### Tests d'intégration ```typescript import { TestBed } from '@angular/core/testing'; import { YnkapModule, PaymentService } from 'ynkap-payment'; describe('Y-Nkap Integration Tests', () => { let paymentService: PaymentService; beforeEach(() => { TestBed.configureTestingModule({ imports: [ YnkapModule.forRoot({ apiKey: 'test-api-key', apiSecret: 'test-api-secret', merchantId: 'test-merchant', environment: 'sandbox' }) ] }); paymentService = TestBed.inject(PaymentService); }); it('should initiate payment successfully', (done) => { const request = { amount: 1000, currency: 'XAF', merchantReference: 'TEST-123', description: 'Test payment' }; paymentService.initiatePayment(request).subscribe({ next: (response) => { expect(response.status).toBe('success'); done(); }, error: done.fail }); }); }); ``` ### Mode développement ```typescript // Activer les logs détaillés YnkapModule.forRoot({ // ... configuration enableDebugMode: true, logLevel: 'verbose' }); // Les logs apparaîtront dans la console : // [Y-Nkap] Payment initiated: {...} // [Y-Nkap] API Request: POST /payments // [Y-Nkap] API Response: 200 {...} ``` --- ## 📚 **Migration et compatibilité** ### Versions supportées | Version Y-Nkap | Angular | TypeScript | Node.js | |-----------------|---------|------------|---------| | 1.x.x | 16+ | 5.0+ | 18+ | | 2.x.x | 17+ | 5.2+ | 18+ | ### Migration depuis v1.x ```typescript // Avant (v1.x) import { YnkapPaymentModule } from '@yaba-in/ynkap-payment'; YnkapPaymentModule.forRoot({ apiKey: 'key', environment: 'sandbox' }); // Après (v2.x) import { YnkapModule } from 'ynkap-payment'; YnkapModule.forRoot({ apiKey: 'key', apiSecret: 'secret', // Nouveau requis merchantId: 'id', // Nouveau requis environment: 'sandbox' }); ``` ### Breaking changes v2.0 - **Ajout** : `apiSecret` et `merchantId` requis - **Ajout** : Système de notifications automatiques - **Ajout** : Confirmations d'annulation - **Ajout** : Messages user-friendly vs techniques - **Amélioration** : Retry intelligent avec timing - ⚠️ **Changement** : Structure des événements d'erreur - ⚠️ **Suppression** : Propriété `webhookUrl` (déplacée vers backend) --- ## 🆘 **Support et communauté** ### Documentation officielle - 📖 **Documentation complète** : [docs.y-nkap.com](https://docs.y-nkap.com) - 🎯 **Guide d'intégration** : [integration.y-nkap.com](https://integration.y-nkap.com) - 🔧 **API Reference** : [api.y-nkap.com](https://api.y-nkap.com) ### Support technique - 💬 **Discord** : [discord.gg/ynkap](https://discord.gg/ynkap) - 📧 **Email** : support@y-nkap.com - 🐛 **Issues GitHub** : [github.com/ynkap/angular-sdk/issues](https://github.com/ynkap/angular-sdk/issues) - 📞 **Support téléphonique** : +237 6XX XXX XXX (heures ouvrables) ### Ressources développeurs - 🎥 **Tutoriels vidéo** : [youtube.com/ynkap](https://youtube.com/ynkap) - 📝 **Blog technique** : [blog.y-nkap.com](https://blog.y-nkap.com) - 💻 **Exemples de code** : [github.com/ynkap/examples](https://github.com/ynkap/examples) - 🚀 **Starter templates** : [github.com/ynkap/starters](https://github.com/ynkap/starters) ### Contribution ```bash # Cloner le repository git clone https://github.com/ynkap/angular-sdk.git # Installer les dépendances npm install # Lancer en mode développement npm run dev # Lancer les tests npm test # Build de production npm run build ``` ### Roadmap - 🔄 **Q1 2024** : Support des paiements par QR Code - 💳 **Q2 2024** : Intégration cartes bancaires - 🌍 **Q3 2024** : Support multi-devises avancé - 📱 **Q4 2024** : SDK React Native --- ## 📄 **Licence** Ce projet est sous licence **MIT**. Voir le fichier [LICENSE](LICENSE) pour plus de détails. --- ## 👨‍💻 **Auteur** **SIEWE FORTUNE** - 🌐 Website: [fortune-siewe.dev](https://fortune-siewe.dev) - 📧 Email: fortune.siewe@example.com - 💼 LinkedIn: [linkedin.com/in/fortune-siewe](https://linkedin.com/in/fortune-siewe) - 🐦 Twitter: [@fortune_siewe](https://twitter.com/fortune_siewe) --- ## 🙏 **Remerciements** - L'équipe **Y-Nkap** pour l'API robuste - La communauté **Angular** pour les outils exceptionnels - Les **contributeurs** qui améliorent continuellement ce module - Les **développeurs** qui utilisent et font confiance à cette solution --- <div align="center"> <p><strong>Fait avec ❤️ pour la communauté des développeurs africains</strong></p> <p> <a href="https://y-nkap.com">🌐 Y-Nkap</a> <a href="https://docs.y-nkap.com">📖 Documentation</a> <a href="https://github.com/ynkap/angular-sdk">💻 GitHub</a> <a href="https://discord.gg/ynkap">💬 Discord</a> </p> </div>