1+ import 'dart:convert' ;
2+
3+
4+ /// Enum defining payment types
5+ enum PaymentType {
6+ /// Card payment type
7+ card,
8+ /// Bank transfer payment type
9+ bank
10+ }
11+
12+ class Card {
13+ final String number;
14+ final String cvv;
15+ final String expiryMonth;
16+ final String expiryYear;
17+
18+ /// Creates a new [Card] instance
19+ Card ({
20+ required this .number,
21+ required this .cvv,
22+ required this .expiryMonth,
23+ required this .expiryYear,
24+ });
25+
26+ /// Creates a [Card] instance from JSON map
27+ factory Card .fromJson (Map <String , dynamic > json) {
28+ return Card (
29+ number: json['number' ]? .toString () ?? '' ,
30+ cvv: json['cvv' ]? .toString () ?? '' ,
31+ expiryMonth: json['expiry_month' ]? .toString () ?? '' ,
32+ expiryYear: json['expiry_year' ]? .toString () ?? '' ,
33+ );
34+ }
35+
36+ /// Converts the card details to JSON map
37+ Map <String , dynamic > toJson () => {
38+ 'number' : number,
39+ 'cvv' : cvv,
40+ 'expiry_month' : expiryMonth,
41+ 'expiry_year' : expiryYear,
42+ };
43+
44+ /// Validates the card details
45+ bool isValid () =>
46+ number.isNotEmpty &&
47+ cvv.isNotEmpty &&
48+ expiryMonth.isNotEmpty &&
49+ expiryYear.isNotEmpty;
50+ }
51+
52+ /// Model class representing bank account details
53+ class Bank {
54+ final String accountNumber;
55+ final String code;
56+
57+ /// Creates a new [Bank] instance
58+ Bank ({
59+ required this .accountNumber,
60+ required this .code,
61+ });
62+
63+ /// Creates a [Bank] instance from JSON map
64+ factory Bank .fromJson (Map <String , dynamic > json) {
65+ return Bank (
66+ accountNumber: json['account_number' ]? .toString () ?? '' ,
67+ code: json['code' ]? .toString () ?? '' ,
68+ );
69+ }
70+
71+ /// Converts the bank details to JSON map
72+ Map <String , dynamic > toJson () => {
73+ 'account_number' : accountNumber,
74+ 'code' : code,
75+ };
76+
77+ /// Validates the bank details
78+ bool isValid () => accountNumber.isNotEmpty && code.isNotEmpty;
79+ }
80+
81+ /// Abstract class defining common payment request properties
82+ abstract class PaymentRequest {
83+ /// Email address of the customer
84+ String get email;
85+
86+ /// Payment amount in main currency
87+ double get amount;
88+
89+ /// Converts the payment request to JSON map
90+ Map <String , dynamic > toJson ();
91+
92+ /// Validates the payment request
93+ bool isValid ();
94+ }
95+
96+ /// Implementation of card-based payment request
97+ class CardPaymentRequest implements PaymentRequest {
98+ @override
99+ final String email;
100+ @override
101+ final double amount;
102+ final Card card;
103+
104+ /// Creates a new [CardPaymentRequest] instance
105+ CardPaymentRequest ({
106+ required this .email,
107+ required this .amount,
108+ required this .card,
109+ });
110+
111+ /// Gets the amount in kobo (amount * 100)
112+ int get amountInKobo => (amount * 100 ).toInt ();
113+
114+ /// Creates a [CardPaymentRequest] instance from JSON map
115+ factory CardPaymentRequest .fromJson (Map <String , dynamic > json) {
116+ return CardPaymentRequest (
117+ email: json['email' ]? .toString () ?? '' ,
118+ amount: (json['amount' ] as num ? )? .toDouble () ?? 0.0 / 100 ,
119+ card: Card .fromJson (json['card' ] as Map <String , dynamic >),
120+ );
121+ }
122+
123+ @override
124+ /// Converts the card payment request to JSON map
125+ Map <String , dynamic > toJson () => {
126+ 'email' : email,
127+ 'amount' : amountInKobo,
128+ 'card' : card.toJson (),
129+ };
130+
131+ @override
132+ /// Validates the card payment request
133+ bool isValid () =>
134+ email.isNotEmpty &&
135+ amount > 0 &&
136+ card.isValid ();
137+ }
138+
139+ /// Implementation of bank-based payment request
140+ class BankPaymentRequest implements PaymentRequest {
141+ @override
142+ final String email;
143+ @override
144+ final double amount;
145+ final Bank bank;
146+
147+ /// Creates a new [BankPaymentRequest] instance
148+ BankPaymentRequest ({
149+ required this .email,
150+ required this .amount,
151+ required this .bank,
152+ });
153+
154+ /// Gets the amount in kobo (amount * 100)
155+ int get amountInKobo => (amount * 100 ).toInt ();
156+
157+ /// Creates a [BankPaymentRequest] instance from JSON map
158+ factory BankPaymentRequest .fromJson (Map <String , dynamic > json) {
159+ return BankPaymentRequest (
160+ email: json['email' ]? .toString () ?? '' ,
161+ amount: (json['amount' ] as num ? )? .toDouble () ?? 0.0 / 100 ,
162+ bank: Bank .fromJson (json['bank' ] as Map <String , dynamic >),
163+ );
164+ }
165+
166+ @override
167+ /// Converts the bank payment request to JSON map
168+ Map <String , dynamic > toJson () => {
169+ 'email' : email,
170+ 'amount' : amountInKobo,
171+ 'bank' : bank.toJson (),
172+ };
173+
174+ @override
175+ /// Validates the bank payment request
176+ bool isValid () =>
177+ email.isNotEmpty &&
178+ amount > 0 &&
179+ bank.isValid ();
180+ }
0 commit comments