feat(wave-mock): simuler le paiement Wave en mode dev (épargne + cotisations)
En mode dev (URL contient 'mock' ou 'localhost', ou !AppConfig.isProd), le paiement Wave est simulé directement sans ouvrir le navigateur : - Dépôt épargne (depot_epargne_dialog.dart) : simulation 800ms + SnackBar succès - Paiement cotisation (payment_dialog.dart) : même pattern En mode prod : comportement inchangé (ouvre l'app Wave via launchUrl). Pattern identique à wave_payment_page.dart (onboarding souscription) appliqué à tous les flux Wave de l'application.
This commit is contained in:
@@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import '../../../../shared/design_system/tokens/color_tokens.dart';
|
import '../../../../shared/design_system/tokens/color_tokens.dart';
|
||||||
import '../../../../shared/design_system/tokens/app_colors.dart';
|
import '../../../../shared/design_system/tokens/app_colors.dart';
|
||||||
|
import '../../../../core/config/environment.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:unionflow_mobile_apps/core/di/injection.dart';
|
import 'package:unionflow_mobile_apps/core/di/injection.dart';
|
||||||
@@ -445,9 +446,29 @@ class _PaymentDialogState extends State<PaymentDialog> {
|
|||||||
numeroTelephone: phone,
|
numeroTelephone: phone,
|
||||||
);
|
);
|
||||||
final url = result.waveLaunchUrl.isNotEmpty ? result.waveLaunchUrl : result.redirectUrl;
|
final url = result.waveLaunchUrl.isNotEmpty ? result.waveLaunchUrl : result.redirectUrl;
|
||||||
if (url.isEmpty) {
|
if (url.isEmpty) throw Exception('URL Wave non reçue');
|
||||||
throw Exception('URL Wave non reçue');
|
|
||||||
|
// Mode dev/mock : simuler le paiement sans ouvrir le navigateur
|
||||||
|
final isMock = url.contains('mock') || url.contains('localhost') || !AppConfig.isProd;
|
||||||
|
if (isMock) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 800));
|
||||||
|
if (!mounted) return;
|
||||||
|
Navigator.pop(context);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Row(children: [
|
||||||
|
Icon(Icons.science_rounded, color: AppColors.onPrimary, size: 16),
|
||||||
|
const SizedBox(width: 8),
|
||||||
|
const Expanded(child: Text('Paiement simulé avec succès (mode dev)')),
|
||||||
|
]),
|
||||||
|
backgroundColor: AppColors.success,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
context.read<ContributionsBloc>().add(const LoadContributions());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mode prod : ouvrir Wave
|
||||||
final uri = Uri.parse(url);
|
final uri = Uri.parse(url);
|
||||||
if (await canLaunchUrl(uri)) {
|
if (await canLaunchUrl(uri)) {
|
||||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:get_it/get_it.dart';
|
|||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
|
|
||||||
|
import '../../../../core/config/environment.dart';
|
||||||
import '../../../../core/constants/lcb_ft_constants.dart';
|
import '../../../../core/constants/lcb_ft_constants.dart';
|
||||||
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
|
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
|
||||||
import '../../../../core/utils/error_formatter.dart';
|
import '../../../../core/utils/error_formatter.dart';
|
||||||
@@ -159,6 +160,29 @@ class _DepotEpargneDialogState extends State<DepotEpargneDialog> {
|
|||||||
);
|
);
|
||||||
final url = result.waveLaunchUrl.isNotEmpty ? result.waveLaunchUrl : result.redirectUrl;
|
final url = result.waveLaunchUrl.isNotEmpty ? result.waveLaunchUrl : result.redirectUrl;
|
||||||
if (url.isEmpty) throw Exception('URL Wave non reçue');
|
if (url.isEmpty) throw Exception('URL Wave non reçue');
|
||||||
|
|
||||||
|
// Mode dev/mock : simuler le paiement au lieu d'ouvrir le navigateur
|
||||||
|
final isMock = url.contains('mock') || url.contains('localhost') || !AppConfig.isProd;
|
||||||
|
if (isMock) {
|
||||||
|
// Simulation : attendre 1s puis confirmer le succès
|
||||||
|
await Future.delayed(const Duration(milliseconds: 800));
|
||||||
|
if (!mounted) return;
|
||||||
|
Navigator.of(context).pop(true);
|
||||||
|
widget.onSuccess?.call();
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: const Row(children: [
|
||||||
|
Icon(Icons.science_rounded, color: Colors.white, size: 16),
|
||||||
|
SizedBox(width: 8),
|
||||||
|
Expanded(child: Text('Dépôt simulé avec succès (mode dev)')),
|
||||||
|
]),
|
||||||
|
backgroundColor: AppColors.success,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode prod : ouvrir Wave
|
||||||
final uri = Uri.parse(url);
|
final uri = Uri.parse(url);
|
||||||
if (await canLaunchUrl(uri)) {
|
if (await canLaunchUrl(uri)) {
|
||||||
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
||||||
|
|||||||
Reference in New Issue
Block a user