feat: Implémentation complète Stripe Connect V1 - Configuration des paiements pour amicales

Cette intégration permet aux amicales de configurer leurs comptes Stripe Express
pour accepter les paiements par carte bancaire avec 0% de commission plateforme.

## 🎯 Fonctionnalités implémentées

### API PHP (Backend)
- **POST /api/stripe/accounts**: Création comptes Stripe Express
- **GET /api/stripe/accounts/:id/status**: Vérification statut compte
- **POST /api/stripe/accounts/:id/onboarding-link**: Liens onboarding
- **POST /api/stripe/locations**: Création locations Terminal
- **POST /api/stripe/terminal/connection-token**: Tokens connexion
- **POST /api/stripe/webhook**: Réception événements Stripe

### Interface Flutter (Frontend)
- Widget configuration Stripe dans amicale_form.dart
- Service StripeConnectService pour communication API
- États visuels dynamiques avec codes couleur
- Messages utilisateur "100% des paiements pour votre amicale"

## 🔧 Corrections techniques

### StripeController.php
- Fix Database::getInstance() → $this->db
- Fix $db->prepare() → $this->db->prepare()
- Suppression colonne details_submitted inexistante
- Ajout exit après réponses JSON (évite 502)

### StripeService.php
- Ajout imports Stripe SDK (use Stripe\Account)
- Fix Account::retrieve() → $this->stripe->accounts->retrieve()
- **CRUCIAL**: Déchiffrement données encrypted_email/encrypted_name
- Suppression calcul commission (0% plateforme)

### Router.php
- Suppression logs debug excessifs (fix nginx 502 "header too big")

### AppConfig.php
- application_fee_percent: 0 (était 2.5)
- application_fee_minimum: 0 (était 50)
- **POLITIQUE**: 100% des paiements vers amicales

##  Tests validés
- Compte pilote créé: acct_1S2YfNP63A07c33Y
- Location Terminal: tml_GLJ21w7KCYX4Wj
- Onboarding Stripe complété avec succès
- Toutes les APIs retournent 200 OK

## 📚 Documentation
- Plannings mis à jour avec accomplissements
- Architecture technique documentée
- Erreurs résolues listées avec solutions

## 🚀 Prêt pour production
V1 Stripe Connect opérationnelle - Prochaine étape: Terminal Payments V2

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-09-01 18:11:28 +02:00
parent 92a69c978a
commit 50f55d825d
10 changed files with 523 additions and 122 deletions

View File

@@ -76,6 +76,12 @@ class StripeController extends Controller {
try {
$this->requireAuth();
// Log du début de la requête
\LogService::log('Début createOnboardingLink', [
'account_id' => $accountId,
'user_id' => Session::getUserId()
]);
// Vérifier le rôle de l'utilisateur
$userId = Session::getUserId();
$stmt = $this->db->prepare('SELECT fk_role FROM users WHERE id = ?');
@@ -92,6 +98,11 @@ class StripeController extends Controller {
$returnUrl = $data['return_url'] ?? '';
$refreshUrl = $data['refresh_url'] ?? '';
\LogService::log('URLs reçues', [
'return_url' => $returnUrl,
'refresh_url' => $refreshUrl
]);
if (!$returnUrl || !$refreshUrl) {
$this->sendError('URLs de retour requises', 400);
return;
@@ -99,14 +110,30 @@ class StripeController extends Controller {
$result = $this->stripeService->createOnboardingLink($accountId, $returnUrl, $refreshUrl);
\LogService::log('Résultat createOnboardingLink', [
'success' => $result['success'] ?? false,
'has_url' => isset($result['url'])
]);
if ($result['success']) {
$this->sendSuccess(['url' => $result['url']]);
$this->sendSuccess([
'status' => 'success',
'url' => $result['url']
]);
exit; // Terminer explicitement après l'envoi de la réponse
} else {
$this->sendError($result['message'], 400);
exit;
}
} catch (Exception $e) {
\LogService::log('Erreur createOnboardingLink', [
'level' => 'error',
'message' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
$this->sendError('Erreur: ' . $e->getMessage());
exit;
}
}
@@ -309,10 +336,8 @@ class StripeController extends Controller {
return;
}
$db = Database::getInstance();
// Récupérer le compte Stripe
$stmt = $db->prepare(
$stmt = $this->db->prepare(
"SELECT sa.*, e.encrypted_name as entite_nom
FROM stripe_accounts sa
LEFT JOIN entites e ON sa.fk_entite = e.id
@@ -349,18 +374,16 @@ class StripeController extends Controller {
}
// Mettre à jour la base de données avec le statut actuel
$stmt = $db->prepare(
$stmt = $this->db->prepare(
"UPDATE stripe_accounts
SET charges_enabled = :charges,
payouts_enabled = :payouts,
details_submitted = :details,
updated_at = NOW()
WHERE id = :id"
);
$stmt->execute([
'charges' => $stripeAccount->charges_enabled ? 1 : 0,
'payouts' => $stripeAccount->payouts_enabled ? 1 : 0,
'details' => $stripeAccount->details_submitted ? 1 : 0,
'id' => $account['id']
]);
@@ -377,10 +400,10 @@ class StripeController extends Controller {
]);
} catch (Exception $e) {
Logger::getInstance()->error('Erreur statut compte Stripe', [
'entity_id' => $entityId,
'error' => $e->getMessage()
]);
// Logger::getInstance()->error('Erreur statut compte Stripe', [
// 'entity_id' => $entityId,
// 'error' => $e->getMessage()
// ]);
$this->sendError('Erreur: ' . $e->getMessage());
}
}