prototype complete
This commit is contained in:
@@ -1,17 +1,41 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:qpay/http/http.dart';
|
||||
import 'package:qpay/screens/home/home_controller.dart' as hc;
|
||||
import 'package:qpay/screens/transaction_controller.dart';
|
||||
import 'package:qpay/screens/transaction_controller.dart' as tc;
|
||||
|
||||
part 'pay_controller.freezed.dart';
|
||||
part 'pay_controller.g.dart';
|
||||
|
||||
class PayScreenModel {
|
||||
List<BillProduct> products = [];
|
||||
late BillProduct selectedProduct;
|
||||
dynamic formData = {};
|
||||
List<PaymentProcessor> paymentProcessors = [];
|
||||
hc.BillProvider? selectedProvider;
|
||||
BillProduct? selectedProduct;
|
||||
PaymentProcessor? selectedPaymentProcessor;
|
||||
bool isLoading = false;
|
||||
String? errorMessage;
|
||||
String? status;
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class PaymentProcessor with _$PaymentProcessor {
|
||||
const factory PaymentProcessor({
|
||||
required String name,
|
||||
required String description,
|
||||
required String image,
|
||||
required String accountFieldName,
|
||||
required String accountFieldLabel,
|
||||
required String label,
|
||||
required String authType,
|
||||
}) = _PaymentProcessor;
|
||||
|
||||
factory PaymentProcessor.fromJson(Map<String, dynamic> json) =>
|
||||
_$PaymentProcessorFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
@@ -32,13 +56,94 @@ abstract class BillProduct with _$BillProduct {
|
||||
class PayController extends ChangeNotifier {
|
||||
final PayScreenModel model = PayScreenModel();
|
||||
final Http http = Http();
|
||||
late SharedPreferences prefs;
|
||||
late TransactionController transactionController;
|
||||
BuildContext context;
|
||||
|
||||
void updateSelectedProduct(BillProduct product) {
|
||||
model.selectedProduct = product;
|
||||
PayController(this.context) {
|
||||
transactionController = Provider.of<TransactionController>(
|
||||
context,
|
||||
listen: false,
|
||||
);
|
||||
model.selectedProvider = transactionController.model.selectedProvider;
|
||||
model.selectedProduct = transactionController.model.selectedProduct;
|
||||
}
|
||||
|
||||
void _showErrorSnackBar(String? message) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(message.toString()),
|
||||
behavior: SnackBarBehavior.floating,
|
||||
backgroundColor: Colors.deepOrange,
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// formData can come from a repeat transaction
|
||||
// otherwise build it from elements of the normal flow
|
||||
Future<void> doTransaction([tc.FormData? formData]) async {
|
||||
try {
|
||||
model.isLoading = true;
|
||||
notifyListeners();
|
||||
|
||||
prefs = await SharedPreferences.getInstance();
|
||||
|
||||
transactionController.model.formData =
|
||||
formData ??
|
||||
transactionController.model.formData.copyWith(
|
||||
type: "CONFIRM",
|
||||
billClientId: model.selectedProvider?.clientId ?? '',
|
||||
debitRef: 'peak',
|
||||
debitCurrency: 'USD',
|
||||
creditAccount: transactionController.model.formData.creditAccount,
|
||||
creditPhone: transactionController.model.formData.creditPhone,
|
||||
billName: model.selectedProvider?.name ?? '',
|
||||
paymentProcessorLabel: model.selectedPaymentProcessor?.label ?? '',
|
||||
paymentProcessorName: model.selectedPaymentProcessor?.name ?? '',
|
||||
paymentProcessorImage: model.selectedPaymentProcessor?.image ?? '',
|
||||
providerImage: model.selectedProvider?.image ?? '',
|
||||
providerLabel: model.selectedProvider?.label ?? '',
|
||||
userId: prefs.getString("userId") ?? '',
|
||||
creditName: transactionController.model.formData.creditName,
|
||||
creditEmail: transactionController.model.formData.creditEmail,
|
||||
productUid: model.selectedProduct?.uid,
|
||||
);
|
||||
|
||||
dynamic response = await http.post(
|
||||
'/transaction',
|
||||
transactionController.model.formData,
|
||||
);
|
||||
logger.i(response.toString());
|
||||
|
||||
if (response['status'] == 'SUCCESS') {
|
||||
model.status = response['status'];
|
||||
|
||||
transactionController.updateConfirmationData(response);
|
||||
} else {
|
||||
model.status = response['status'];
|
||||
model.errorMessage =
|
||||
response['errorMessage'] ??
|
||||
"Problem with the transaction. Please try again or contact support";
|
||||
_showErrorSnackBar(model.errorMessage);
|
||||
}
|
||||
} on DioException catch (e, s) {
|
||||
logger.e(s);
|
||||
_showErrorSnackBar("Network error. Please try again or contact support");
|
||||
} catch (e, s) {
|
||||
logger.e(s);
|
||||
_showErrorSnackBar(
|
||||
"Problem processing that transaction. Please try again or contact support",
|
||||
);
|
||||
}
|
||||
|
||||
model.isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getProducts(String providerId) async {
|
||||
model.products = getFakeProducts();
|
||||
try {
|
||||
model.isLoading = true;
|
||||
|
||||
@@ -48,11 +153,86 @@ class PayController extends ChangeNotifier {
|
||||
model.products = response.map((e) => BillProduct.fromJson(e)).toList();
|
||||
} catch (e) {
|
||||
logger.e(e);
|
||||
model.errorMessage = e.toString();
|
||||
_showErrorSnackBar(
|
||||
"Problem fetching products, are you connected to the internet?",
|
||||
);
|
||||
}
|
||||
|
||||
model.isLoading = false;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> getPaymentProcessors() async {
|
||||
try {
|
||||
model.isLoading = true;
|
||||
model.paymentProcessors = getFakePaymentProcessors();
|
||||
notifyListeners();
|
||||
|
||||
List<dynamic> response = await http.get('/payment-processors');
|
||||
model.paymentProcessors =
|
||||
response.map((e) => PaymentProcessor.fromJson(e)).toList();
|
||||
|
||||
notifyListeners();
|
||||
} catch (e) {
|
||||
logger.e(e);
|
||||
_showErrorSnackBar(
|
||||
"Problem fetching payment processors, are you connected to the internet?",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void updateAdditionalRecipientDetails(String name, String email) {
|
||||
transactionController.model.formData = transactionController.model.formData
|
||||
.copyWith(creditName: name, creditEmail: email);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updatePhone(String phone) {
|
||||
transactionController.model.formData = transactionController.model.formData
|
||||
.copyWith(creditPhone: phone);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updateAmount(String amount) {
|
||||
transactionController.model.formData = transactionController.model.formData
|
||||
.copyWith(amount: amount);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updateSelectedProduct(BillProduct product) {
|
||||
model.selectedProduct = product;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void updateSelectedPaymentProcessor(PaymentProcessor processor) {
|
||||
model.selectedPaymentProcessor = processor;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
List<PaymentProcessor> getFakePaymentProcessors() {
|
||||
return [
|
||||
PaymentProcessor(
|
||||
name: "EcoCash",
|
||||
description: "Pay using your mobile wallet.",
|
||||
image: "ecocash.png",
|
||||
accountFieldName: "phoneNumber",
|
||||
accountFieldLabel: "EcoCash Phone Number",
|
||||
label: "ECOCASH",
|
||||
authType: "REMOTE",
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<BillProduct> getFakeProducts() {
|
||||
return [
|
||||
BillProduct(
|
||||
uid: '1',
|
||||
name: 'Product 1',
|
||||
description: 'Description 1',
|
||||
displayName: 'Product 1',
|
||||
defaultAmount: 100,
|
||||
requiresAmount: true,
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user