📚 DOCUMENTATION COMPLÈTE API MODULE 6 - RETRAITS 📋 INFORMATIONS GÉNÉRALES Base URL : http://localhost:8000/api Authentification : Bearer Token (JWT) Format : JSON 🔐 PRÉ-REQUIS D'AUTHENTIFICATION Obtenir un token : http POST /api/auth/login Content-Type: application/json { "email": "votre@email.com", "password": "votre_mot_de_passe" } En-tĂȘte requis pour toutes les requĂȘtes : http Authorization: Bearer VOTRE_TOKEN_JWT Content-Type: application/json Accept: application/json đŸ‘€ ENDPOINTS UTILISATEURS 1. VÉRIFIER L'ÉLIGIBILITÉ AU RETRAIT http GET /withdrawals/check-eligibility Description : VĂ©rifie si l'utilisateur peut effectuer un retrait (KYC, solde, limites) Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/withdrawals/check-eligibility" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json" RĂ©ponse rĂ©ussie (200) : json { "success": true, "data": { "eligible": true, "reasons": [], "daily_limit": 1000000.00, "used_today": 150000.00, "available_today": 850000.00, "wallet_balance": 500000.00 } } RĂ©ponse Ă©chec KYC (403) : json { "success": false, "message": "VĂ©rification KYC requise pour les retraits", "kyc_status": "pending" } 2. CALCULER LES FRAIS DE RETRAIT http GET /withdrawals/fees-calculator?amount=50000&operator=mtn_money ParamĂštres : amount (required) : Montant en XAF (minimum 500) operator (required) : orange_money, mtn_money, ou moov_money Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/withdrawals/fees-calculator?amount=50000&operator=mtn_money" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "amount": 50000.00, "fees": 750.00, "net_amount": 49250.00, "fee_percentage": 1.5, "min_fee": 100.00, "max_fee": 5000.00, "description": "Frais MTN Money" } } 3. DEMANDER UN RETRAIT http POST /withdrawals/request Corps de la requĂȘte : json { "amount": 50000, "phone_number": "+237612345678", "operator": "mtn_money" } RĂšgles de validation : amount : Multiple de 100, min 500, max 500000 phone_number : Format camerounais (+2376xxxxxxxx) operator : orange_money, mtn_money, moov_money Exemple de requĂȘte : bash curl -X POST "http://localhost:8000/api/withdrawals/request" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "amount": 50000, "phone_number": "+237612345678", "operator": "mtn_money" }' RĂ©ponse rĂ©ussie (201) : json { "success": true, "message": "Code de retrait envoyĂ© au bĂ©nĂ©ficiaire", "data": { "withdrawal_id": 123, "reference": "WTH1733304458abc123", "code_expires_at": "2025-12-05 14:30:00", "amount": 50000.00, "fees": 750.00, "net_amount": 49250.00 } } RĂ©ponse Ă©chec (400) : json { "success": false, "message": "Solde insuffisant" } 4. VALIDER LE CODE DE RETRAIT http POST /withdrawals/{id}/validate ParamĂštres URL : id : ID du retrait Corps de la requĂȘte : json { "code": "123456" } Exemple de requĂȘte : bash curl -X POST "http://localhost:8000/api/withdrawals/123/validate" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "code": "123456" }' RĂ©ponse rĂ©ussie (200) : json { "success": true, "message": "Code validĂ©. Notre Ă©quipe traitera votre retrait sous peu.", "data": { "id": 123, "withdrawal_reference": "WTH1733304458abc123", "amount": 50000.00, "status": "pending_processing", "is_code_verified": true, "code_verified_at": "2025-12-05 14:25:00" } } RĂ©ponse Ă©chec (400) : json { "success": false, "message": "Code expirĂ©" } 5. ANNULER UN RETRAIT http POST /withdrawals/{id}/cancel ParamĂštres URL : id : ID du retrait Exemple de requĂȘte : bash curl -X POST "http://localhost:8000/api/withdrawals/123/cancel" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" RĂ©ponse rĂ©ussie (200) : json { "success": true, "message": "Retrait annulĂ©", "data": { "id": 123, "status": "cancelled", "refunded_amount": 50000.00 } } 6. RENVOYER LE CODE http POST /withdrawals/{id}/resend-code ParamĂštres URL : id : ID du retrait Exemple de requĂȘte : bash curl -X POST "http://localhost:8000/api/withdrawals/123/resend-code" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" RĂ©ponse rĂ©ussie (200) : json { "success": true, "message": "Code renvoyĂ©", "data": { "code_expires_at": "2025-12-05 14:40:00" } } 7. LISTER LES RETRAITS http GET /withdrawals ParamĂštres de requĂȘte optionnels : per_page : Nombre d'Ă©lĂ©ments par page (dĂ©faut: 20) page : NumĂ©ro de page status : Filtrer par statut operator : Filtrer par opĂ©rateur Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/withdrawals?per_page=10&page=1" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "current_page": 1, "data": [ { "id": 123, "withdrawal_reference": "WTH1733304458abc123", "amount": 50000.00, "fees": 750.00, "net_amount": 49250.00, "phone_number": "+237612345678", "operator": "mtn_money", "status": "pending_processing", "is_code_verified": true, "created_at": "2025-12-05 14:20:00", "updated_at": "2025-12-05 14:25:00" } ], "first_page_url": "http://localhost:8000/api/withdrawals?page=1", "from": 1, "last_page": 5, "last_page_url": "http://localhost:8000/api/withdrawals?page=5", "next_page_url": "http://localhost:8000/api/withdrawals?page=2", "path": "http://localhost:8000/api/withdrawals", "per_page": 10, "prev_page_url": null, "to": 10, "total": 47 } } 8. DÉTAILS D'UN RETRAIT http GET /withdrawals/{id} ParamĂštres URL : id : ID du retrait Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/withdrawals/123" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "id": 123, "user_id": 1, "wallet_id": 1, "amount": 50000.00, "currency": "XAF", "fees": 750.00, "net_amount": 49250.00, "method": "mobile_money", "phone_number": "+237612345678", "operator": "mtn_money", "withdrawal_reference": "WTH1733304458abc123", "withdrawal_code": null, // MasquĂ© pour sĂ©curitĂ© "code_expires_at": "2025-12-05 14:30:00", "code_verified_at": "2025-12-05 14:25:00", "is_code_verified": true, "status": "pending_processing", "created_at": "2025-12-05 14:20:00", "updated_at": "2025-12-05 14:25:00" } } 9. STATISTIQUES DES RETRAITS http GET /withdrawals/stats Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/withdrawals/stats" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "total_withdrawn": 1500000.00, "total_fees": 22500.00, "pending_count": 3, "daily_stats": [ { "date": "2025-12-04", "count": 5, "total_amount": 250000.00 }, { "date": "2025-12-05", "count": 3, "total_amount": 150000.00 } ] } } đŸ‘šâ€đŸ’Œ ENDPOINTS ADMINISTRATEUR ⚠ Requiert un token avec rĂŽle admin/super_admin 1. LISTER LES RETRAITS EN ATTENTE http GET /admin/withdrawals/pending ParamĂštres optionnels : per_page : Nombre par page (dĂ©faut: 20) operator : Filtrer par opĂ©rateur date : Filtrer par date (YYYY-MM-DD) Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/admin/withdrawals/pending" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "current_page": 1, "data": [ { "id": 123, "withdrawal_reference": "WTH1733304458abc123", "amount": 50000.00, "net_amount": 49250.00, "phone_number": "+237612345678", "operator": "mtn_money", "user": { "id": 1, "email": "john@example.com", "phone": "+237612345678" }, "wallet": { "id": 1, "wallet_number": "WAL00000001" }, "is_code_verified": true, "created_at": "2025-12-05 14:20:00" } ], "stats": { "total_pending": 15, "total_amount_pending": 750000.00, "count_by_operator": [ { "operator": "mtn_money", "count": 8, "total": 400000.00 }, { "operator": "orange_money", "count": 5, "total": 250000.00 }, { "operator": "moov_money", "count": 2, "total": 100000.00 } ] } } } 2. MARQUER COMME TRAITÉ http POST /admin/withdrawals/{id}/process ParamĂštres URL : id : ID du retrait Corps optionnel : json { "manual_reference": "MAN-2025-12-05-001", "notes": "TraitĂ© manuellement via MTN Money" } Exemple de requĂȘte : bash curl -X POST "http://localhost:8000/api/admin/withdrawals/123/process" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "manual_reference": "MAN-2025-12-05-001", "notes": "TraitĂ© manuellement" }' RĂ©ponse rĂ©ussie (200) : json { "success": true, "message": "Retrait marquĂ© comme traitĂ©", "data": { "id": 123, "status": "completed", "processed_manually_by": 2, "processed_manually_at": "2025-12-05 15:00:00", "manual_reference": "MAN-2025-12-05-001", "manual_notes": "TraitĂ© manuellement" } } 3. MARQUER COMME ÉCHOUÉ http POST /admin/withdrawals/{id}/fail ParamĂštres URL : id : ID du retrait Corps requis : json { "reason": "NumĂ©ro invalide / NumĂ©ro non joignable" } Exemple de requĂȘte : bash curl -X POST "http://localhost:8000/api/admin/withdrawals/123/fail" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "reason": "NumĂ©ro invalide" }' RĂ©ponse rĂ©ussie (200) : json { "success": true, "message": "Retrait marquĂ© comme Ă©chouĂ©", "data": { "id": 123, "status": "failed", "failure_reason": "NumĂ©ro invalide" } } 4. STATISTIQUES ADMIN http GET /admin/withdrawals/stats ParamĂštres optionnels : period : today, week, month, year (dĂ©faut: today) Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/admin/withdrawals/stats?period=week" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "period": "week", "total_count": 150, "completed_amount": 7500000.00, "pending_amount": 500000.00, "total_fees": 112500.00, "by_operator": [ { "operator": "mtn_money", "count": 80, "total_amount": 4000000.00 }, { "operator": "orange_money", "count": 50, "total_amount": 2500000.00 }, { "operator": "moov_money", "count": 20, "total_amount": 1000000.00 } ], "last_7_days": [ { "date": "2025-11-29", "count": 15, "completed_amount": 750000.00, "pending_amount": 50000.00 }, { "date": "2025-11-30", "count": 20, "completed_amount": 1000000.00, "pending_amount": 75000.00 } ] } } 5. RECHERCHER DES RETRAITS http GET /admin/withdrawals/search ParamĂštres de recherche : reference : RĂ©fĂ©rence du retrait phone_number : NumĂ©ro de tĂ©lĂ©phone status : Statut du retrait date_from : Date de dĂ©but (YYYY-MM-DD) date_to : Date de fin (YYYY-MM-DD) per_page : RĂ©sultats par page Exemple de requĂȘte : bash curl -X GET "http://localhost:8000/api/admin/withdrawals/search?phone_number=+237612345678&status=completed&date_from=2025-12-01" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" RĂ©ponse (200) : json { "success": true, "data": { "current_page": 1, "data": [ { "id": 123, "withdrawal_reference": "WTH1733304458abc123", "amount": 50000.00, "phone_number": "+237612345678", "operator": "mtn_money", "status": "completed", "user": { "id": 1, "email": "john@example.com" }, "created_at": "2025-12-05 14:20:00", "processed_manually_at": "2025-12-05 15:00:00" } ] } } đŸ§Ș SCÉNARIOS DE TEST AVEC POSTMAN Collection Postman : Module 6 - Retraits Variables d'environnement : json { "base_url": "http://localhost:8000/api", "user_token": "USER_JWT_TOKEN", "admin_token": "ADMIN_JWT_TOKEN", "withdrawal_id": "", "withdrawal_reference": "" } Flux de test complet : Étape 1 : VĂ©rifier Ă©ligibilitĂ© text MĂ©thode : GET URL : {{base_url}}/withdrawals/check-eligibility Headers : Authorization: Bearer {{user_token}} Étape 2 : Calculer les frais text MĂ©thode : GET URL : {{base_url}}/withdrawals/fees-calculator Params : amount=50000, operator=mtn_money Headers : Authorization: Bearer {{user_token}} Étape 3 : Demander retrait text MĂ©thode : POST URL : {{base_url}}/withdrawals/request Body : { "amount": 50000, "phone_number": "+237612345678", "operator": "mtn_money" } Headers : Authorization: Bearer {{user_token}} → Sauvegarder withdrawal_id et withdrawal_reference dans les variables Étape 4 : Valider le code text MĂ©thode : POST URL : {{base_url}}/withdrawals/{{withdrawal_id}}/validate Body : { "code": "123456" } Headers : Authorization: Bearer {{user_token}} Étape 5 : Admin - Lister retraits en attente text MĂ©thode : GET URL : {{base_url}}/admin/withdrawals/pending Headers : Authorization: Bearer {{admin_token}} Étape 6 : Admin - Marquer comme traitĂ© text MĂ©thode : POST URL : {{base_url}}/admin/withdrawals/{{withdrawal_id}}/process Body : { "manual_reference": "MAN-TEST-001", "notes": "Test postman" } Headers : Authorization: Bearer {{admin_token}} Étape 7 : VĂ©rifier historique text MĂ©thode : GET URL : {{base_url}}/withdrawals Headers : Authorization: Bearer {{user_token}} 🚹 CODES D'ERREUR COURANTS 400 - Bad Request : json { "success": false, "message": "Validation error", "errors": { "amount": ["Le montant doit ĂȘtre un multiple de 100."], "phone_number": ["Le numĂ©ro doit ĂȘtre un numĂ©ro camerounais valide (+2376xxxxxxxx)"] } } 401 - Unauthorized : json { "message": "Unauthenticated." } 403 - Forbidden : json { "success": false, "message": "VĂ©rification KYC requise pour les retraits", "kyc_status": "pending" } 404 - Not Found : json { "success": false, "message": "Retrait non trouvĂ©" } 422 - Unprocessable Entity : json { "success": false, "message": "Solde insuffisant" } 📊 VÉRIFICATION DES LIMITES Limites par dĂ©faut : Montant minimum : 500 XAF Montant maximum : 500,000 XAF Multiple de : 100 XAF Limite quotidienne : 1,000,000 XAF Max retraits/jour : 5 transactions Niveaux KYC : Niveau Limite quotidienne Restrictions Non vĂ©rifiĂ© 0 XAF Aucun retrait Basic 500,000 XAF Retraits limitĂ©s Verified 1,000,000 XAF Retraits standards Premium 5,000,000 XAF Retraits Ă©levĂ©s 🔄 STATUTS DES RETRAITS Workflow : text 1. pending_verification → Code envoyĂ©, en attente de validation 2. pending_processing → Code validĂ©, en attente traitement manuel 3. processing → En cours de traitement (si automatisĂ©) 4. completed → TraitĂ© et terminĂ© 5. failed → ÉchouĂ© (annulĂ© et remboursĂ©) 6. cancelled → AnnulĂ© par l'utilisateur 7. expired → Code expirĂ© (automatiquement annulĂ©) 8. reversed → RemboursĂ© aprĂšs traitement đŸ’Ÿ EXPORT POSTMAN COLLECTION Collection JSON : json { "info": { "name": "Nelsius Pay - Module 6: Retraits", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" }, "item": [ { "name": "User - Check Eligibility", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{user_token}}", "type": "text" } ], "url": { "raw": "{{base_url}}/withdrawals/check-eligibility", "host": ["{{base_url}}"], "path": ["withdrawals", "check-eligibility"] } } }, { "name": "User - Calculate Fees", "request": { "method": "GET", "header": [ { "key": "Authorization", "value": "Bearer {{user_token}}", "type": "text" } ], "url": { "raw": "{{base_url}}/withdrawals/fees-calculator?amount=50000&operator=mtn_money", "host": ["{{base_url}}"], "path": ["withdrawals", "fees-calculator"], "query": [ { "key": "amount", "value": "50000" }, { "key": "operator", "value": "mtn_money" } ] } } }, { "name": "User - Request Withdrawal", "request": { "method": "POST", "header": [ { "key": "Authorization", "value": "Bearer {{user_token}}", "type": "text" }, { "key": "Content-Type", "value": "application/json", "type": "text" } ], "body": { "mode": "raw", "raw": "{\n \"amount\": 50000,\n \"phone_number\": \"+237612345678\",\n \"operator\": \"mtn_money\"\n}" }, "url": { "raw": "{{base_url}}/withdrawals/request", "host": ["{{base_url}}"], "path": ["withdrawals", "request"] } } } ] } 🚀 BONNES PRATIQUES POUR LES TESTS Testez d'abord sans KYC → Devrait retourner 403 Simulez diffĂ©rents scĂ©narios : Solde insuffisant Limite quotidienne atteinte Code expirĂ© Code invalide multiple fois VĂ©rifiez l'impact sur le portefeuille : Solde disponible diminue aprĂšs demande Solde bloquĂ© augmente Solde bloquĂ© diminue aprĂšs traitement/annulation Testez les cas admin : Traiter un retrait Échouer un retrait Rechercher des retraits 📝 CHECKLIST DE TEST Endpoints utilisateur : GET /withdrawals/check-eligibility (avec/sans KYC) GET /withdrawals/fees-calculator (diffĂ©rents montants/opĂ©rateurs) POST /withdrawals/request (succĂšs/Ă©chec validation) POST /withdrawals/{id}/validate (code valide/invalide/expirĂ©) POST /withdrawals/{id}/cancel (annulation possible/impossible) POST /withdrawals/{id}/resend-code GET /withdrawals (pagination, filtres) GET /withdrawals/{id} GET /withdrawals/stats Endpoints admin : GET /admin/withdrawals/pending (filtres) POST /admin/withdrawals/{id}/process (avec/sans rĂ©fĂ©rence) POST /admin/withdrawals/{id}/fail (avec raison) GET /admin/withdrawals/stats (diffĂ©rentes pĂ©riodes) GET /admin/withdrawals/search (critĂšres multiples)