Fix: Corriger le type PDO dans StripeService et retirer getConnection()
This commit is contained in:
213
app/lib/core/services/stripe_connect_service.dart
Normal file
213
app/lib/core/services/stripe_connect_service.dart
Normal file
@@ -0,0 +1,213 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:geosector_app/core/services/api_service.dart';
|
||||
import 'package:geosector_app/core/data/models/amicale_model.dart';
|
||||
|
||||
/// Service pour gérer Stripe Connect dans l'application
|
||||
class StripeConnectService {
|
||||
final ApiService apiService;
|
||||
|
||||
StripeConnectService({required this.apiService});
|
||||
|
||||
/// Créer un compte Stripe Connect pour une amicale
|
||||
/// Retourne l'URL d'onboarding ou null si erreur
|
||||
Future<String?> createStripeAccount(AmicaleModel amicale) async {
|
||||
try {
|
||||
debugPrint('🏢 Création compte Stripe pour ${amicale.name}...');
|
||||
debugPrint(' Amicale ID: ${amicale.id}');
|
||||
|
||||
// 1. Créer le compte Stripe Connect via notre API
|
||||
final createResponse = await apiService.post(
|
||||
'/stripe/accounts',
|
||||
data: {'fk_entite': amicale.id},
|
||||
);
|
||||
|
||||
debugPrint(' Response status: ${createResponse.statusCode}');
|
||||
debugPrint(' Response data: ${createResponse.data}');
|
||||
|
||||
if (createResponse.statusCode != 200 && createResponse.statusCode != 201) {
|
||||
final error = createResponse.data?['message'] ?? 'Erreur création compte';
|
||||
|
||||
// Si le compte existe déjà, récupérer l'account_id
|
||||
if (error.toString().contains('existe déjà')) {
|
||||
final accountId = createResponse.data?['account_id'];
|
||||
debugPrint(' Compte existant détecté, account_id: $accountId');
|
||||
if (accountId != null) {
|
||||
return await getOnboardingLink(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint('❌ Erreur création compte: $error');
|
||||
throw Exception(error);
|
||||
}
|
||||
|
||||
final accountId = createResponse.data?['account_id'];
|
||||
debugPrint('✅ Compte créé/récupéré: $accountId');
|
||||
|
||||
if (accountId == null) {
|
||||
throw Exception('account_id non retourné par l\'API');
|
||||
}
|
||||
|
||||
// 2. Créer la Location pour Terminal/Tap to Pay
|
||||
try {
|
||||
await apiService.post(
|
||||
'/stripe/locations',
|
||||
data: {'fk_entite': amicale.id},
|
||||
);
|
||||
debugPrint('✅ Location Terminal créée');
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ Erreur création Location (non bloquant): $e');
|
||||
}
|
||||
|
||||
// 3. Obtenir le lien d'onboarding
|
||||
return await getOnboardingLink(accountId);
|
||||
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur StripeConnect: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtenir le lien d'onboarding pour finaliser la configuration
|
||||
Future<String?> getOnboardingLink(String accountId) async {
|
||||
try {
|
||||
debugPrint('📋 Génération du lien d\'onboarding pour account: $accountId');
|
||||
|
||||
// URLs de retour après onboarding
|
||||
const baseUrl = 'https://dapp.geosector.fr'; // À adapter selon l'environnement
|
||||
final returnUrl = Uri.encodeFull('$baseUrl/stripe/success');
|
||||
final refreshUrl = Uri.encodeFull('$baseUrl/stripe/refresh');
|
||||
|
||||
debugPrint(' Return URL: $returnUrl');
|
||||
debugPrint(' Refresh URL: $refreshUrl');
|
||||
|
||||
final response = await apiService.post(
|
||||
'/stripe/accounts/$accountId/onboarding-link',
|
||||
data: {
|
||||
'return_url': returnUrl,
|
||||
'refresh_url': refreshUrl,
|
||||
},
|
||||
);
|
||||
|
||||
debugPrint(' Response status: ${response.statusCode}');
|
||||
debugPrint(' Response data: ${response.data}');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final url = response.data['url'];
|
||||
debugPrint('✅ Lien onboarding généré: $url');
|
||||
return url;
|
||||
}
|
||||
|
||||
final errorMessage = response.data?['message'] ?? 'Erreur inconnue';
|
||||
throw Exception('Impossible de générer le lien: $errorMessage');
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur onboarding link: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Vérifier le statut du compte Stripe d'une amicale
|
||||
Future<StripeAccountStatus> checkAccountStatus(int amicaleId) async {
|
||||
try {
|
||||
final response = await apiService.get('/stripe/accounts/$amicaleId/status');
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = response.data;
|
||||
return StripeAccountStatus(
|
||||
hasAccount: data['has_account'] ?? false,
|
||||
accountId: data['account_id'],
|
||||
chargesEnabled: data['charges_enabled'] ?? false,
|
||||
payoutsEnabled: data['payouts_enabled'] ?? false,
|
||||
onboardingCompleted: data['onboarding_completed'] ?? false,
|
||||
);
|
||||
}
|
||||
|
||||
return StripeAccountStatus(hasAccount: false);
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur vérification statut: $e');
|
||||
return StripeAccountStatus(hasAccount: false);
|
||||
}
|
||||
}
|
||||
|
||||
/// Ouvrir le Dashboard Stripe pour l'amicale
|
||||
Future<void> openStripeDashboard(String? accountId) async {
|
||||
if (accountId == null || accountId.isEmpty) return;
|
||||
|
||||
// URL du dashboard Stripe Express
|
||||
final url = Uri.parse('https://dashboard.stripe.com/express/$accountId');
|
||||
|
||||
if (await canLaunchUrl(url)) {
|
||||
await launchUrl(url, mode: LaunchMode.externalApplication);
|
||||
}
|
||||
}
|
||||
|
||||
/// Lancer le processus d'onboarding dans un navigateur externe
|
||||
Future<bool> launchOnboarding(String url) async {
|
||||
try {
|
||||
debugPrint('🚀 Lancement onboarding URL: $url');
|
||||
debugPrint(' Plateforme: ${kIsWeb ? "Web" : "Mobile"}');
|
||||
|
||||
final uri = Uri.parse(url);
|
||||
|
||||
// Sur web, on peut directement lancer sans vérification
|
||||
if (kIsWeb) {
|
||||
final launched = await launchUrl(
|
||||
uri,
|
||||
webOnlyWindowName: '_blank', // Ouvre dans un nouvel onglet
|
||||
);
|
||||
debugPrint(launched ? '✅ URL lancée avec succès' : '❌ Échec du lancement');
|
||||
return launched;
|
||||
} else {
|
||||
// Sur mobile, vérifier d'abord si on peut lancer l'URL
|
||||
if (await canLaunchUrl(uri)) {
|
||||
await launchUrl(
|
||||
uri,
|
||||
mode: LaunchMode.externalApplication,
|
||||
);
|
||||
debugPrint('✅ URL lancée avec succès');
|
||||
return true;
|
||||
} else {
|
||||
debugPrint('❌ Impossible de lancer l\'URL sur mobile');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('❌ Erreur lancement onboarding: $e');
|
||||
debugPrint(' Détails: $e');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Statut d'un compte Stripe Connect
|
||||
class StripeAccountStatus {
|
||||
final bool hasAccount;
|
||||
final String? accountId;
|
||||
final bool chargesEnabled;
|
||||
final bool payoutsEnabled;
|
||||
final bool onboardingCompleted;
|
||||
|
||||
StripeAccountStatus({
|
||||
required this.hasAccount,
|
||||
this.accountId,
|
||||
this.chargesEnabled = false,
|
||||
this.payoutsEnabled = false,
|
||||
this.onboardingCompleted = false,
|
||||
});
|
||||
|
||||
bool get canAcceptPayments => chargesEnabled && payoutsEnabled;
|
||||
|
||||
String get statusMessage {
|
||||
if (!hasAccount) return 'Pas de compte Stripe';
|
||||
if (!onboardingCompleted) return 'Configuration en cours';
|
||||
if (!chargesEnabled) return 'Paiements non activés';
|
||||
if (!payoutsEnabled) return 'Virements non activés';
|
||||
return 'Compte actif';
|
||||
}
|
||||
|
||||
Color get statusColor {
|
||||
if (canAcceptPayments) return Colors.green;
|
||||
if (hasAccount) return Colors.orange;
|
||||
return Colors.red;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user