ynkap-payment
v1.0.5
Published
Module de paiement Y-Nkap pour Angular - Intégration simple des paiements mobiles (Orange Money, MTN Mobile Money)
Maintainers
Readme
💳 Y-Nkap Payment Module for Angular
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
- Configuration
- Utilisation rapide
- Composants disponibles
- Services et API
- Gestion des erreurs
- Notifications et confirmations
- Personnalisation
- Exemples avancés
- Architecture
- Support
📦 Installation
Prérequis
- Angular 16+
- TypeScript 5.0+
- Node.js 18+
Installation via npm
npm install ynkap-payment --saveInstallation via yarn
yarn add ynkap-payment⚙️ Configuration
1. Import du module
Importez YnkapModule dans votre module principal :
// 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
// 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
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
<!-- 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>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.
<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.
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: '[email protected]'
}
};
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.
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.
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.
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 :
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
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 :
// 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
// 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 :
// 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 :
- Erreur de paiement → Notification d'erreur apparaît à droite
- Immédiatement → Section d'erreur dans le formulaire masquée
- Après 5 secondes → Notification disparaît automatiquement
- 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 :
<!-- 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
<ynkap-pay-button
[amount]="1000"
[primaryColor]="'#28a745'"
[theme]="'light'">
Payer avec couleur personnalisée
</ynkap-pay-button>Contenu du bouton personnalisé
<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
/* 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
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
interface PaymentResponse {
status: 'success' | 'pending' | 'failed';
transaction?: PaymentTransaction;
error?: YnkapError;
message?: string;
}PaymentTransaction
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
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
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
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
@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
@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 publicsFlux de données
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
- Initialisation : Configuration du module avec les clés API
- Déclenchement : Clic sur le bouton de paiement
- Authentification : Vérification des credentials
- Sélection méthode : Choix MTN/Orange Money
- Saisie données : Numéro de téléphone
- Validation : Contrôles côté client
- Envoi API : Requête vers Y-Nkap
- Traitement : Gestion de la réponse
- Notification : Affichage du résultat
- Retry : En cas d'erreur retryable
🔧 Configuration avancée
Variables d'environnement
// 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
// 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
// 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 :
# Lancer tous les tests
npm test
# Tests avec couverture
npm run test:coverage
# Tests en mode watch
npm run test:watchTests d'intégration
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
// 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
// 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 :
apiSecretetmerchantIdrequis - ✅ 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
- 🎯 Guide d'intégration : integration.y-nkap.com
- 🔧 API Reference : api.y-nkap.com
Support technique
- 💬 Discord : discord.gg/ynkap
- 📧 Email : [email protected]
- 🐛 Issues GitHub : 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
- 📝 Blog technique : blog.y-nkap.com
- 💻 Exemples de code : github.com/ynkap/examples
- 🚀 Starter templates : github.com/ynkap/starters
Contribution
# 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 buildRoadmap
- 🔄 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 pour plus de détails.
👨💻 Auteur
SIEWE FORTUNE
- 🌐 Website: fortune-siewe.dev
- 📧 Email: [email protected]
- 💼 LinkedIn: linkedin.com/in/fortune-siewe
- 🐦 Twitter: @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
