updating sequence of flows
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
; BASE_URL=https://peakapi.qantra.co.zw/api
|
BASE_URL=https://peakapi.qantra.co.zw/api
|
||||||
; BASE_URL=http://192.168.100.26:6950/api
|
; BASE_URL=http://192.168.100.26:6950/api
|
||||||
BASE_URL=http://10.69.5.204:6950/api
|
; BASE_URL=http://10.69.5.204:6950/api
|
||||||
; BASE_URL=http://192.168.1.164:6950/api
|
; BASE_URL=http://192.168.1.164:6950/api
|
||||||
; BASE_URL=http://192.168.120.160:6950/api
|
; BASE_URL=http://192.168.120.160:6950/api
|
||||||
; BASE_URL=http://10.10.2.92:6950/api
|
; BASE_URL=http://10.10.2.92:6950/api
|
||||||
|
|||||||
@@ -110,9 +110,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/gateway',
|
path: '/gateway',
|
||||||
builder:
|
builder: (context, state) => const GatewayScreen(),
|
||||||
(context, state) =>
|
|
||||||
GatewayScreen(url: state.extra as String),
|
|
||||||
),
|
),
|
||||||
GoRoute(
|
GoRoute(
|
||||||
path: '/receipt',
|
path: '/receipt',
|
||||||
|
|||||||
@@ -84,14 +84,11 @@ class ConfirmController extends ChangeNotifier {
|
|||||||
if (transactionController.model.selectedPaymentProcessor.authType ==
|
if (transactionController.model.selectedPaymentProcessor.authType ==
|
||||||
"WEB") {
|
"WEB") {
|
||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
context.push(
|
context.push('/gateway');
|
||||||
'/gateway',
|
|
||||||
extra: transactionController.model.receiptData?['targetUrl'],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await pollTransaction(transactionController.model.receiptData?['id']);
|
await pollTransaction(transactionController.model.receiptData?['id']);
|
||||||
context.push('/receipt');
|
context.push('/integration');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
model.status = response['status'];
|
model.status = response['status'];
|
||||||
|
|||||||
@@ -60,15 +60,10 @@ class GatewayController extends ChangeNotifier {
|
|||||||
dynamic response = workflowResponse['body'];
|
dynamic response = workflowResponse['body'];
|
||||||
|
|
||||||
model.status = response['status'];
|
model.status = response['status'];
|
||||||
transactionController.model.paymentStatus = response['status'];
|
transactionController.model.paymentStatus = response['paymentStatus'];
|
||||||
transactionController.updateReceiptData(response);
|
|
||||||
|
|
||||||
if(model.status == 'PENDING') {
|
if(model.status == 'SUCCESS') {
|
||||||
_showErrorSnackBar('Transaction status still pending');
|
transactionController.updateReceiptData(response);
|
||||||
}
|
|
||||||
|
|
||||||
if(model.status != 'FAILED') {
|
|
||||||
_showErrorSnackBar(response['errorMessage'].isEmpty ? 'Transaction failed' : response['errorMessage']);
|
|
||||||
}
|
}
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import 'package:qpay/screens/gateway/gateway_controller.dart';
|
|||||||
import 'package:webview_flutter/webview_flutter.dart';
|
import 'package:webview_flutter/webview_flutter.dart';
|
||||||
|
|
||||||
class GatewayScreen extends StatefulWidget {
|
class GatewayScreen extends StatefulWidget {
|
||||||
final String url;
|
const GatewayScreen({super.key});
|
||||||
const GatewayScreen({super.key, required this.url});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<GatewayScreen> createState() => _GatewayScreenState();
|
State<GatewayScreen> createState() => _GatewayScreenState();
|
||||||
@@ -17,20 +16,22 @@ class GatewayScreen extends StatefulWidget {
|
|||||||
class _GatewayScreenState extends State<GatewayScreen> {
|
class _GatewayScreenState extends State<GatewayScreen> {
|
||||||
late WebViewController _webViewController;
|
late WebViewController _webViewController;
|
||||||
late GatewayController controller;
|
late GatewayController controller;
|
||||||
|
late String url;
|
||||||
|
|
||||||
bool integrationStarted = false;
|
bool integrationStarted = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_initWebView(widget.url);
|
|
||||||
controller = GatewayController(context);
|
controller = GatewayController(context);
|
||||||
|
url = controller.transactionController.model.receiptData?['targetUrl'];
|
||||||
|
_initWebView(url);
|
||||||
|
|
||||||
bool simulate = bool.parse(dotenv.env['SIMULATE_PAYMENT_SUCCESS']!);
|
bool simulate = bool.parse(dotenv.env['SIMULATE_PAYMENT_SUCCESS']!);
|
||||||
if(simulate) {
|
if(simulate) {
|
||||||
sleep(Duration(seconds: 10));
|
sleep(Duration(seconds: 10));
|
||||||
String url = widget.url.replaceAll("/pay/", "/receipt/");
|
String targetUrl = url.replaceAll("/pay/", "/receipt/");
|
||||||
_webViewController.loadRequest(Uri.parse(url));
|
_webViewController.loadRequest(Uri.parse(targetUrl));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +72,6 @@ class _GatewayScreenState extends State<GatewayScreen> {
|
|||||||
setState(() {
|
setState(() {
|
||||||
integrationStarted = true;
|
integrationStarted = true;
|
||||||
});
|
});
|
||||||
await controller.poll(controller.transactionController.model.receiptData?['id']);
|
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
context.go('/integration');
|
context.go('/integration');
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:qpay/http/http.dart';
|
import 'package:qpay/http/http.dart';
|
||||||
|
import 'package:qpay/screens/gateway/gateway_controller.dart';
|
||||||
import 'package:qpay/screens/transaction_controller.dart';
|
import 'package:qpay/screens/transaction_controller.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ class IntegrationController extends ChangeNotifier {
|
|||||||
final IntegrationModel model = IntegrationModel();
|
final IntegrationModel model = IntegrationModel();
|
||||||
final Http http = Http();
|
final Http http = Http();
|
||||||
late TransactionController transactionController;
|
late TransactionController transactionController;
|
||||||
|
late GatewayController gatewayController;
|
||||||
late SharedPreferences prefs;
|
late SharedPreferences prefs;
|
||||||
|
|
||||||
BuildContext context;
|
BuildContext context;
|
||||||
@@ -27,6 +29,8 @@ class IntegrationController extends ChangeNotifier {
|
|||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
gatewayController = GatewayController(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showErrorSnackBar(String? message) {
|
void _showErrorSnackBar(String? message) {
|
||||||
@@ -58,6 +62,8 @@ class IntegrationController extends ChangeNotifier {
|
|||||||
if (response['status'] == 'SUCCESS') {
|
if (response['status'] == 'SUCCESS') {
|
||||||
model.status = response['status'];
|
model.status = response['status'];
|
||||||
transactionController.updateReceiptData(response);
|
transactionController.updateReceiptData(response);
|
||||||
|
|
||||||
|
gatewayController.poll(transactionController.model.confirmationData['id']);
|
||||||
} else {
|
} else {
|
||||||
model.status = response['status'];
|
model.status = response['status'];
|
||||||
model.errorMessage = response['errorMessage'];
|
model.errorMessage = response['errorMessage'];
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:qpay/screens/gateway/gateway_controller.dart';
|
|
||||||
import 'package:qpay/screens/transaction_controller.dart';
|
import 'package:qpay/screens/transaction_controller.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.dart';
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
|
|
||||||
@@ -17,7 +16,6 @@ class IntegrationScreen extends StatefulWidget {
|
|||||||
class _IntegrationScreenState extends State<IntegrationScreen> {
|
class _IntegrationScreenState extends State<IntegrationScreen> {
|
||||||
late IntegrationController controller;
|
late IntegrationController controller;
|
||||||
late TransactionController transactionController;
|
late TransactionController transactionController;
|
||||||
late GatewayController gatewayController;
|
|
||||||
|
|
||||||
bool integrating = false;
|
bool integrating = false;
|
||||||
|
|
||||||
@@ -25,27 +23,12 @@ class _IntegrationScreenState extends State<IntegrationScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
controller = IntegrationController(context);
|
controller = IntegrationController(context);
|
||||||
gatewayController = GatewayController(context);
|
|
||||||
transactionController = Provider.of<TransactionController>(
|
transactionController = Provider.of<TransactionController>(
|
||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
controller.doIntegration();
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() async {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
|
|
||||||
if(integrating) return;
|
|
||||||
|
|
||||||
String status = Provider.of<TransactionController>(context).model.paymentStatus;
|
|
||||||
if(status == 'SUCCESS') {
|
|
||||||
setState(() {
|
|
||||||
integrating = true;
|
|
||||||
});
|
|
||||||
await controller.doIntegration();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showErrorSnackBar(String? message) {
|
void _showErrorSnackBar(String? message) {
|
||||||
@@ -74,91 +57,64 @@ class _IntegrationScreenState extends State<IntegrationScreen> {
|
|||||||
title: const Text('Completing your transaction'),
|
title: const Text('Completing your transaction'),
|
||||||
),
|
),
|
||||||
body: ListenableBuilder(
|
body: ListenableBuilder(
|
||||||
listenable: gatewayController,
|
listenable: controller,
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
return ListenableBuilder(
|
if (controller.model.status == 'SUCCESS') {
|
||||||
listenable: controller,
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
builder: (context, child) {
|
context.go('/receipt');
|
||||||
if (controller.model.status == 'SUCCESS') {
|
});
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
}
|
||||||
context.go('/receipt');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: EdgeInsets.all(50),
|
padding: EdgeInsets.all(50),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 75),
|
||||||
|
|
||||||
|
Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 75),
|
Text(
|
||||||
|
'We\'ve successfully collected your funds. We are now '
|
||||||
if(transactionController.model.paymentStatus != 'SUCCESS')
|
'updating your billing account. This won\'t take long',
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
Image.asset('assets/peak-animation.gif', width: 150),
|
||||||
|
SizedBox(
|
||||||
|
width: 50,
|
||||||
|
child: LinearProgressIndicator(),
|
||||||
|
),
|
||||||
|
SizedBox(height: 50),
|
||||||
|
if(controller.model.status == 'FAILED')
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'We failed to check your payment status',
|
'We failed to update your billing account',
|
||||||
style: TextStyle(fontSize: 20),
|
style: TextStyle(fontSize: 20),
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 50,),
|
SizedBox(height: 20,),
|
||||||
Skeletonizer(
|
Skeletonizer(
|
||||||
enabled: gatewayController.model.isLoading,
|
enabled: controller.model.isLoading,
|
||||||
child: OutlinedButton(
|
child: OutlinedButton(
|
||||||
child: Text('Check latest status'),
|
child: Text('Retry'),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
gatewayController.poll(transactionController.model.receiptData?['id']);
|
controller.doIntegration();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
if(transactionController.model.paymentStatus == 'SUCCESS')
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'We\'ve successfully collected your funds. We are now '
|
|
||||||
'updating your billing account. This won\'t take long',
|
|
||||||
style: TextStyle(fontSize: 20),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
Image.asset('assets/peak-animation.gif', width: 150),
|
|
||||||
SizedBox(
|
|
||||||
width: 50,
|
|
||||||
child: LinearProgressIndicator(),
|
|
||||||
),
|
|
||||||
SizedBox(height: 50),
|
|
||||||
if(controller.model.status == 'FAILED')
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
'We failed to update your billing account',
|
|
||||||
style: TextStyle(fontSize: 20),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
SizedBox(height: 20,),
|
|
||||||
Skeletonizer(
|
|
||||||
enabled: controller.model.isLoading,
|
|
||||||
child: OutlinedButton(
|
|
||||||
child: Text('Retry'),
|
|
||||||
onPressed: () {
|
|
||||||
controller.doIntegration();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
);
|
),
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:qpay/screens/gateway/gateway_controller.dart';
|
import 'package:qpay/screens/gateway/gateway_controller.dart';
|
||||||
import 'package:qpay/screens/transaction_controller.dart';
|
import 'package:qpay/screens/transaction_controller.dart';
|
||||||
@@ -6,6 +7,7 @@ import 'package:go_router/go_router.dart';
|
|||||||
import 'package:qpay/screens/receipt/receipt_controller.dart';
|
import 'package:qpay/screens/receipt/receipt_controller.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.dart';
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
|
import 'package:timeago/timeago.dart' as timeago;
|
||||||
import 'package:widgets_to_image/widgets_to_image.dart';
|
import 'package:widgets_to_image/widgets_to_image.dart';
|
||||||
|
|
||||||
class ReceiptScreen extends StatefulWidget {
|
class ReceiptScreen extends StatefulWidget {
|
||||||
@@ -96,6 +98,11 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
|||||||
receiptController.setLoading(true);
|
receiptController.setLoading(true);
|
||||||
await gatewayController.poll(receiptController.model.receiptData?["id"]);
|
await gatewayController.poll(receiptController.model.receiptData?["id"]);
|
||||||
if(gatewayController.model.status == "SUCCESS"){
|
if(gatewayController.model.status == "SUCCESS"){
|
||||||
|
receiptController.getReceiptData(transactionController.model.receiptData?["id"]);
|
||||||
|
if(transactionController.model.receiptData?["pollingStatus"]) {
|
||||||
|
receiptController.setLoading(false);
|
||||||
|
return; // no need to proceed if we've already polled successfully
|
||||||
|
}
|
||||||
await _retry();
|
await _retry();
|
||||||
}
|
}
|
||||||
receiptController.setLoading(false);
|
receiptController.setLoading(false);
|
||||||
@@ -253,21 +260,22 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
|||||||
CrossAxisAlignment.center,
|
CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
// receiptController
|
|
||||||
// .model
|
|
||||||
// .receiptData?["providerImage"] !=
|
|
||||||
// null
|
|
||||||
// ? Image.asset(
|
|
||||||
// 'assets/${receiptController.model.receiptData?["providerImage"] ?? ''}',
|
|
||||||
// width: 50,
|
|
||||||
// )
|
|
||||||
// : SizedBox.shrink(),
|
|
||||||
Text(
|
Text(
|
||||||
receiptController
|
receiptController
|
||||||
.model
|
.model
|
||||||
.receiptData?["billName"] ??
|
.receiptData?["billName"] ??
|
||||||
"",
|
"",
|
||||||
style: TextStyle(fontSize: 14),
|
style: TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
receiptController
|
||||||
|
.model
|
||||||
|
.receiptData?["createdAt"] != null ?
|
||||||
|
DateFormat.yMMMd().add_jm().format(DateTime.parse(
|
||||||
|
receiptController
|
||||||
|
.model
|
||||||
|
.receiptData?["createdAt"])) : "",
|
||||||
|
style: TextStyle(fontSize: 15),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -602,43 +610,47 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
|
||||||
if(receiptController.model.receiptData?["integrationStatus"] != "SUCCESS" &&
|
if(receiptController.model.receiptData?["integrationStatus"] != "SUCCESS" &&
|
||||||
receiptController.model.receiptData?["paymentStatus"] == "SUCCESS")
|
receiptController.model.receiptData?["paymentStatus"] == "SUCCESS")
|
||||||
Skeletonizer(
|
Column(
|
||||||
enabled:
|
children: [
|
||||||
receiptController
|
const SizedBox(height: 10),
|
||||||
.model
|
Skeletonizer(
|
||||||
.isLoading,
|
enabled:
|
||||||
child: Row(
|
receiptController
|
||||||
mainAxisAlignment:
|
.model
|
||||||
MainAxisAlignment
|
.isLoading,
|
||||||
.spaceBetween,
|
child: Row(
|
||||||
children: [
|
mainAxisAlignment:
|
||||||
Text(
|
MainAxisAlignment
|
||||||
"Additional action",
|
.spaceBetween,
|
||||||
style: TextStyle(
|
children: [
|
||||||
fontSize: 16,
|
Text(
|
||||||
fontWeight:
|
"Additional action",
|
||||||
FontWeight.bold,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Text("Billing account update failed, please tap on retry to try again",
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: Theme.of(
|
fontWeight:
|
||||||
context,
|
FontWeight.bold,
|
||||||
).colorScheme.primary,
|
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.end,
|
|
||||||
softWrap: true,
|
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
Expanded(
|
||||||
],
|
child: Text("Billing account update failed, please tap on Retry to try again",
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Theme.of(
|
||||||
|
context,
|
||||||
|
).colorScheme.primary,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.end,
|
||||||
|
softWrap: true,
|
||||||
|
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
|
),
|
||||||
SizedBox(height: 10,),
|
SizedBox(height: 10,),
|
||||||
|
|
||||||
Skeletonizer(
|
Skeletonizer(
|
||||||
@@ -767,39 +779,44 @@ class _ReceiptScreenState extends State<ReceiptScreen>
|
|||||||
.model
|
.model
|
||||||
.receiptData?["additionalData"]
|
.receiptData?["additionalData"]
|
||||||
.map<Widget>((data) {
|
.map<Widget>((data) {
|
||||||
return Column(
|
return Skeletonizer(
|
||||||
children: [
|
enabled: receiptController
|
||||||
Row(
|
.model
|
||||||
mainAxisAlignment:
|
.isLoading,
|
||||||
MainAxisAlignment
|
child: Column(
|
||||||
.spaceBetween,
|
children: [
|
||||||
children: [
|
Row(
|
||||||
Text(
|
mainAxisAlignment:
|
||||||
data["name"] ??
|
MainAxisAlignment
|
||||||
"",
|
.spaceBetween,
|
||||||
style: TextStyle(
|
children: [
|
||||||
fontSize:
|
Text(
|
||||||
16,
|
data["name"] ??
|
||||||
fontWeight:
|
"",
|
||||||
FontWeight
|
style: TextStyle(
|
||||||
.bold,
|
fontSize:
|
||||||
|
16,
|
||||||
|
fontWeight:
|
||||||
|
FontWeight
|
||||||
|
.bold,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
Text(
|
||||||
Text(
|
data["value"] ??
|
||||||
data["value"] ??
|
"",
|
||||||
"",
|
style:
|
||||||
style:
|
TextStyle(
|
||||||
TextStyle(
|
fontSize:
|
||||||
fontSize:
|
16,
|
||||||
16,
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
const SizedBox(
|
||||||
const SizedBox(
|
height: 10,
|
||||||
height: 10,
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.toList(),
|
.toList(),
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class TransactionModel {
|
|||||||
providerLabel: '',
|
providerLabel: '',
|
||||||
);
|
);
|
||||||
String paymentStatus = 'PENDING';
|
String paymentStatus = 'PENDING';
|
||||||
|
String pollStatus = 'PENDING';
|
||||||
String? errorMessage;
|
String? errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user