improved environment management

This commit is contained in:
2026-03-27 19:46:45 +02:00
parent d010ec75eb
commit 15f8e0dfd0
7 changed files with 120 additions and 55 deletions

View File

@@ -1,7 +1,48 @@
import 'dart:async';
import 'dart:js_interop';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:web/web.dart' as web;
const String _defaultGatewayScriptUrl =
'https://test-gateway.mastercard.com/static/checkout/checkout.min.js';
@JS('Checkout')
external JSAny? _checkout;
@JS('configure')
external void configure(String sessionID);
@JS('showEmbeddedPage')
external void showEmbeddedPage();
Future<void> ensureCheckoutScriptLoaded() async {
final existing = web.document.querySelector('#mastercard-checkout-script');
if (existing is web.HTMLScriptElement) {
await _waitForCheckout();
return;
}
final scriptUrl =
dotenv.env['GATEWAY_SCRIPT_URL'] ?? _defaultGatewayScriptUrl;
final scriptElement = web.HTMLScriptElement()
..id = 'mastercard-checkout-script'
..src = scriptUrl
..async = true;
web.document.head?.append(scriptElement);
await _waitForCheckout();
}
Future<void> _waitForCheckout() async {
const maxAttempts = 100;
for (var attempt = 0; attempt < maxAttempts; attempt++) {
if (_checkout != null) {
return;
}
await Future.delayed(const Duration(milliseconds: 100));
}
throw StateError('Mastercard Checkout script failed to load before timeout.');
}

View File

@@ -29,21 +29,34 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';
const String testEnv = "assets/.env";
const String liveEnv = "assets/.env";
const String testEnv = 'assets/.env.test';
const String liveEnv = 'assets/.env.live';
const String appEnv = String.fromEnvironment('APP_ENV', defaultValue: 'test');
String resolveEnvFile(String env) {
switch (env.toLowerCase()) {
case 'live':
return liveEnv;
case 'test':
default:
return testEnv;
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await dotenv.load(fileName: testEnv);
await dotenv.load(fileName: resolveEnvFile(appEnv));
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider<TransactionController>(create: (_) => TransactionController()),
ChangeNotifierProvider<OnboardingController>(create: (_) => OnboardingController()),
ChangeNotifierProvider<TransactionController>(
create: (_) => TransactionController(),
),
ChangeNotifierProvider<OnboardingController>(
create: (_) => OnboardingController(),
),
],
child: const MyApp(),
),

View File

@@ -60,6 +60,8 @@ class _GatewayWebScreenState extends State<GatewayWebScreen> {
}
void initIframeView() async {
await ensureCheckoutScriptLoaded();
final uri = Uri.parse(url);
// 2. The pathSegments property returns a list of the parts of the path.
// For "checkout/pay/SESSION...", the segments are ["checkout", "pay", "SESSION..."].
@@ -187,10 +189,8 @@ class _GatewayWebScreenState extends State<GatewayWebScreen> {
horizontal: 20,
),
child: Row(
crossAxisAlignment:
CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Once done on this page, check transaction status',
@@ -211,9 +211,7 @@ class _GatewayWebScreenState extends State<GatewayWebScreen> {
.colorScheme
.primary
.withValues(alpha: 0.15),
borderRadius: BorderRadius.circular(
12,
),
borderRadius: BorderRadius.circular(12),
),
child: Text(
'Check status',
@@ -224,7 +222,7 @@ class _GatewayWebScreenState extends State<GatewayWebScreen> {
],
),
),
SizedBox(height: 10,),
SizedBox(height: 10),
SizedBox(
width: double.infinity,
height: constraints.maxHeight + 300,