mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
CW-1409-Update-Cakepay-cards-to-use-all-variants (#3112)
* add prepaid range support for CakePay cards * use selected denomination for order creation * fix Flexible widget issue * forces to use prod api * auto-reformat * fix the input string format [skip ci] Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * fix the value string format [skip ci] Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * fix the nextamount string format Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> --------- Co-authored-by: Robert Malikowski <malikowskirobert@gmail.com> Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
co-authored by
Omar Hatem
Robert Malikowski
parent
b1922fc663
commit
6fc27dd3a0
@@ -8,6 +8,7 @@ import 'package:cake_wallet/cake_pay/src/widgets/denominations_amount_widget.dar
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/enter_amount_widget.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/image_placeholder.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/link_extractor.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/prepaid_range_amount_widget.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/rounded_overlay_cards_widget.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/text_icon_button.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart';
|
||||
@@ -147,24 +148,38 @@ class CakePayBuyCardPage extends BasePage {
|
||||
),
|
||||
bottomCardChild: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: card.denominationItems.isNotEmpty
|
||||
? DenominationsAmountWidget(
|
||||
fiatCurrency: card.fiatCurrency.title,
|
||||
denominations: card.denominationItems,
|
||||
amountFieldFocus: _amountFieldFocus,
|
||||
amountController: _amountController,
|
||||
quantityFieldFocus: _quantityFieldFocus,
|
||||
quantityController: _quantityController,
|
||||
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged,
|
||||
onQuantityChanged: cakePayBuyCardViewModel.onQuantityChanged,
|
||||
cakePayBuyCardViewModel: cakePayBuyCardViewModel)
|
||||
: EnterAmountWidget(
|
||||
minValue: card.minValue ?? '-',
|
||||
maxValue: card.maxValue ?? '-',
|
||||
fiatCurrency: card.fiatCurrency.title,
|
||||
amountFieldFocus: _amountFieldFocus,
|
||||
amountController: _amountController,
|
||||
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged))),
|
||||
child: Column(children: [
|
||||
if (card.prepaidRange.isNotEmpty)
|
||||
PrepaidRangeAmountWidget(
|
||||
fiatCurrency: card.fiatCurrency.title,
|
||||
prepaidRanges: card.prepaidRange,
|
||||
amountFieldFocus: _amountFieldFocus,
|
||||
amountController: _amountController,
|
||||
cakePayBuyCardViewModel: cakePayBuyCardViewModel,
|
||||
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged,
|
||||
)
|
||||
else if (card.denominationItems.isNotEmpty)
|
||||
DenominationsAmountWidget(
|
||||
fiatCurrency: card.fiatCurrency.title,
|
||||
denominations: card.denominationItems,
|
||||
amountFieldFocus: _amountFieldFocus,
|
||||
amountController: _amountController,
|
||||
quantityFieldFocus: _quantityFieldFocus,
|
||||
quantityController: _quantityController,
|
||||
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged,
|
||||
onQuantityChanged: cakePayBuyCardViewModel.onQuantityChanged,
|
||||
cakePayBuyCardViewModel: cakePayBuyCardViewModel,
|
||||
)
|
||||
else
|
||||
EnterAmountWidget(
|
||||
minValue: card.minValue ?? '-',
|
||||
maxValue: card.maxValue ?? '-',
|
||||
fiatCurrency: card.fiatCurrency.title,
|
||||
amountFieldFocus: _amountFieldFocus,
|
||||
amountController: _amountController,
|
||||
onAmountChanged: cakePayBuyCardViewModel.onAmountChanged,
|
||||
),
|
||||
]))),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Padding(
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
import 'package:cake_wallet/core/utilities.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
|
||||
enum CakePayCardType {
|
||||
prepaid('Prepaid Cards'),
|
||||
gift('gift'),
|
||||
onDemand('on_demand'),
|
||||
custom('custom');
|
||||
|
||||
const CakePayCardType(this.apiValue);
|
||||
|
||||
final String apiValue;
|
||||
}
|
||||
|
||||
class CakePayCard {
|
||||
final int id;
|
||||
final String name;
|
||||
final CakePayCardType? type;
|
||||
final String? description;
|
||||
final String? termsAndConditions;
|
||||
final String? howToUse;
|
||||
@@ -15,26 +28,77 @@ class CakePayCard {
|
||||
final String? minValue;
|
||||
final String? maxValue;
|
||||
final List<Denomination> denominationItems;
|
||||
final List<PrepaidRange> prepaidRange;
|
||||
|
||||
CakePayCard({
|
||||
required this.id,
|
||||
required this.name,
|
||||
this.description,
|
||||
this.termsAndConditions,
|
||||
this.howToUse,
|
||||
this.expiryAndValidity,
|
||||
this.cardImageUrl,
|
||||
this.country,
|
||||
required this.fiatCurrency,
|
||||
this.minValueUsd,
|
||||
this.maxValueUsd,
|
||||
this.minValue,
|
||||
this.maxValue,
|
||||
CakePayCard(
|
||||
{required this.id,
|
||||
required this.name,
|
||||
this.type,
|
||||
this.description,
|
||||
this.termsAndConditions,
|
||||
this.howToUse,
|
||||
this.expiryAndValidity,
|
||||
this.cardImageUrl,
|
||||
this.country,
|
||||
required this.fiatCurrency,
|
||||
this.minValueUsd,
|
||||
this.maxValueUsd,
|
||||
this.minValue,
|
||||
this.maxValue,
|
||||
List<Denomination>? denominationItems,
|
||||
List<PrepaidRange>? prepaidRange})
|
||||
: denominationItems = denominationItems ?? const [],
|
||||
prepaidRange = prepaidRange ?? const [];
|
||||
|
||||
CakePayCard copyWith({
|
||||
int? id,
|
||||
String? name,
|
||||
CakePayCardType? type,
|
||||
String? description,
|
||||
String? termsAndConditions,
|
||||
String? howToUse,
|
||||
String? expiryAndValidity,
|
||||
String? cardImageUrl,
|
||||
String? country,
|
||||
FiatCurrency? fiatCurrency,
|
||||
String? minValueUsd,
|
||||
String? maxValueUsd,
|
||||
String? minValue,
|
||||
String? maxValue,
|
||||
List<Denomination>? denominationItems,
|
||||
}) : denominationItems = denominationItems ?? const [];
|
||||
List<PrepaidRange>? prepaidRange,
|
||||
}) {
|
||||
return CakePayCard(
|
||||
id: id ?? this.id,
|
||||
name: name ?? this.name,
|
||||
type: type ?? this.type,
|
||||
description: description ?? this.description,
|
||||
termsAndConditions: termsAndConditions ?? this.termsAndConditions,
|
||||
howToUse: howToUse ?? this.howToUse,
|
||||
expiryAndValidity: expiryAndValidity ?? this.expiryAndValidity,
|
||||
cardImageUrl: cardImageUrl ?? this.cardImageUrl,
|
||||
country: country ?? this.country,
|
||||
fiatCurrency: fiatCurrency ?? this.fiatCurrency,
|
||||
minValueUsd: minValueUsd ?? this.minValueUsd,
|
||||
maxValueUsd: maxValueUsd ?? this.maxValueUsd,
|
||||
minValue: minValue ?? this.minValue,
|
||||
maxValue: maxValue ?? this.maxValue,
|
||||
denominationItems: denominationItems ?? this.denominationItems,
|
||||
prepaidRange: prepaidRange ?? this.prepaidRange,
|
||||
);
|
||||
}
|
||||
|
||||
static CakePayCardType? cakePayCardTypeFromApi(String? value) {
|
||||
if (value == null) return null;
|
||||
final normalized = value.trim().toLowerCase();
|
||||
return CakePayCardType.values.firstWhereOrNull(
|
||||
(e) => e.apiValue.toLowerCase() == normalized,
|
||||
);
|
||||
}
|
||||
|
||||
factory CakePayCard.fromJson(Map<String, dynamic> json) {
|
||||
final name = stripHtmlIfNeeded(json['name'] as String? ?? '');
|
||||
final typeString = json['type'] as String? ?? '';
|
||||
final description = stripHtmlIfNeeded(json['description'] as String? ?? '');
|
||||
final termsAndConditions = stripHtmlIfNeeded(json['terms_and_conditions'] as String? ?? '');
|
||||
final howToUse = stripHtmlIfNeeded(json['how_to_use'] as String? ?? '');
|
||||
@@ -63,9 +127,12 @@ class CakePayCard {
|
||||
}
|
||||
}
|
||||
|
||||
final cakePayCardType = cakePayCardTypeFromApi(typeString);
|
||||
|
||||
return CakePayCard(
|
||||
id: json['id'] as int? ?? 0,
|
||||
name: name,
|
||||
type: cakePayCardType,
|
||||
description: description,
|
||||
termsAndConditions: termsAndConditions,
|
||||
howToUse: howToUse,
|
||||
@@ -103,12 +170,6 @@ class Denomination {
|
||||
this.usdValue,
|
||||
});
|
||||
|
||||
static double? _toDouble(dynamic v) {
|
||||
if (v == null) return null;
|
||||
if (v is num) return v.toDouble();
|
||||
return double.tryParse(v.toString());
|
||||
}
|
||||
|
||||
factory Denomination.fromJson(Map<String, dynamic> json) {
|
||||
return Denomination(
|
||||
value: _toDouble(json['value']) ?? 0,
|
||||
@@ -117,3 +178,29 @@ class Denomination {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PrepaidRange {
|
||||
final double minValue;
|
||||
final double maxValue;
|
||||
final String rangeId;
|
||||
|
||||
PrepaidRange({
|
||||
required this.minValue,
|
||||
required this.maxValue,
|
||||
required this.rangeId,
|
||||
});
|
||||
|
||||
factory PrepaidRange.fromCard(CakePayCard card) {
|
||||
return PrepaidRange(
|
||||
minValue: _toDouble(card.minValue) ?? 0,
|
||||
maxValue: _toDouble(card.maxValue) ?? 0,
|
||||
rangeId: card.id.toString(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
double? _toDouble(dynamic v) {
|
||||
if (v == null) return null;
|
||||
if (v is num) return v.toDouble();
|
||||
return double.tryParse(v.toString());
|
||||
}
|
||||
|
||||
@@ -31,9 +31,26 @@ class CakePayVendor {
|
||||
|
||||
if (cardsJson != null && cardsJson.isNotEmpty) {
|
||||
try {
|
||||
cardForVendor = CakePayCard.fromJson(cardsJson.firstWhere((card) {
|
||||
return Country.normalizeName(card['country'] as String) == country;
|
||||
}) as Map<String, dynamic>);
|
||||
final cards = cardsJson
|
||||
.map((cardJson) => CakePayCard.fromJson(cardJson as Map<String, dynamic>))
|
||||
.toList();
|
||||
final cardsForSelectedCountry =
|
||||
cards.where((card) => Country.normalizeName(card.country ?? '') == country).toList();
|
||||
|
||||
if (cardsForSelectedCountry.isNotEmpty) {
|
||||
final isPrepaid =
|
||||
cardsForSelectedCountry.every((card) => card.type == CakePayCardType.prepaid);
|
||||
|
||||
if (isPrepaid) {
|
||||
final firstCard = cardsForSelectedCountry.first;
|
||||
final prepaidRanges = cardsForSelectedCountry.map(PrepaidRange.fromCard).toList()
|
||||
..sort((a, b) => a.minValue.compareTo(b.minValue));
|
||||
|
||||
cardForVendor = firstCard.copyWith(prepaidRange: prepaidRanges);
|
||||
} else {
|
||||
cardForVendor = cardsForSelectedCountry.first;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
printV('Error parsing card for vendor: $e');
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import 'package:cw_core/utils/proxy_wrapper.dart';
|
||||
import 'package:cw_core/utils/print_verbose.dart';
|
||||
|
||||
class CakePayApi {
|
||||
static const testBaseUri = FeatureFlag.hasDevOptions;
|
||||
static const testBaseUri = false; //FeatureFlag.hasDevOptions;
|
||||
|
||||
static const baseTestCakePayUri = 'api-stg.cakepay.com';
|
||||
static const baseProdCakePayUri = 'api-prod.cakepay.com';
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_card.dart';
|
||||
import 'package:cake_wallet/view_model/cake_pay/cake_pay_buy_card_view_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'enter_amount_widget.dart';
|
||||
|
||||
class PrepaidRangeAmountWidget extends StatefulWidget {
|
||||
const PrepaidRangeAmountWidget({
|
||||
required this.fiatCurrency,
|
||||
required this.prepaidRanges,
|
||||
required this.amountFieldFocus,
|
||||
required this.amountController,
|
||||
required this.cakePayBuyCardViewModel,
|
||||
required this.onAmountChanged,
|
||||
});
|
||||
|
||||
final String fiatCurrency;
|
||||
final List<PrepaidRange> prepaidRanges;
|
||||
final FocusNode amountFieldFocus;
|
||||
final TextEditingController amountController;
|
||||
final CakePayBuyCardViewModel cakePayBuyCardViewModel;
|
||||
final Function(String) onAmountChanged;
|
||||
|
||||
@override
|
||||
State<PrepaidRangeAmountWidget> createState() => _PrepaidRangeAmountWidgetState();
|
||||
}
|
||||
|
||||
class _PrepaidRangeAmountWidgetState extends State<PrepaidRangeAmountWidget> {
|
||||
late PrepaidRange _selectedRange;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedRange = widget.prepaidRanges.first;
|
||||
_applySelectedRange(forceAmountUpdate: widget.amountController.text.isEmpty);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Select range:',
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).textTheme.titleLarge!.color!,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
DropdownButtonFormField<PrepaidRange>(
|
||||
value: _selectedRange,
|
||||
isExpanded: true,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
filled: true,
|
||||
fillColor: Theme.of(context).cardColor,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.onSurface.withAlpha(40),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
borderSide: BorderSide(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
),
|
||||
items: widget.prepaidRanges
|
||||
.map(
|
||||
(range) => DropdownMenuItem<PrepaidRange>(
|
||||
value: range,
|
||||
child: Text(_rangeLabel(range)),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
onChanged: (range) {
|
||||
if (range == null) return;
|
||||
setState(() => _selectedRange = range);
|
||||
widget.cakePayBuyCardViewModel.onPrepaidRangeChanged(range);
|
||||
_applySelectedRange(forceAmountUpdate: true);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
EnterAmountWidget(
|
||||
minValue: _formatAmount(_selectedRange.minValue),
|
||||
maxValue: _formatAmount(_selectedRange.maxValue),
|
||||
fiatCurrency: widget.fiatCurrency,
|
||||
amountFieldFocus: widget.amountFieldFocus,
|
||||
amountController: widget.amountController,
|
||||
onAmountChanged: (value) {
|
||||
widget.onAmountChanged(value);
|
||||
widget.cakePayBuyCardViewModel.selectedDenomination = (
|
||||
value.replaceAll(',', '.'),
|
||||
int.tryParse(_selectedRange.rangeId),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
void _applySelectedRange({required bool forceAmountUpdate}) {
|
||||
final currentAmount = double.tryParse(widget.amountController.text);
|
||||
final isCurrentAmountInRange = currentAmount != null &&
|
||||
currentAmount >= _selectedRange.minValue &&
|
||||
currentAmount <= _selectedRange.maxValue;
|
||||
|
||||
final nextAmount = forceAmountUpdate || !isCurrentAmountInRange
|
||||
? _formatAmount(_selectedRange.minValue)
|
||||
: widget.amountController.text;
|
||||
|
||||
widget.amountController.text = nextAmount;
|
||||
widget.onAmountChanged(nextAmount);
|
||||
widget.cakePayBuyCardViewModel.selectedDenomination = (
|
||||
nextAmount.replaceAll(',', '.'),
|
||||
int.tryParse(_selectedRange.rangeId),
|
||||
);
|
||||
}
|
||||
|
||||
String _rangeLabel(PrepaidRange range) {
|
||||
return '${widget.fiatCurrency} ${_formatAmount(range.minValue)} - ${_formatAmount(range.maxValue)}';
|
||||
}
|
||||
|
||||
String _formatAmount(double value) {
|
||||
return value % 1 == 0 ? value.toInt().toString() : value.toStringAsFixed(2);
|
||||
}
|
||||
}
|
||||
@@ -12,32 +12,46 @@ class RoundedOverlayCards extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenHeight = MediaQuery.of(context).size.height;
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius:
|
||||
BorderRadius.only(bottomLeft: Radius.circular(25.0), bottomRight: Radius.circular(25.0)),
|
||||
child: Container(
|
||||
height: screenHeight * 0.50,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24),
|
||||
),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer),
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24),
|
||||
),
|
||||
color: Theme.of(context).colorScheme.surfaceContainer,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(25.0), bottomRight: Radius.circular(25.0)),
|
||||
Flexible(
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(25.0),
|
||||
bottomRight: Radius.circular(25.0),
|
||||
),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
|
||||
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: const BorderRadius.only(
|
||||
bottomLeft: Radius.circular(24),
|
||||
bottomRight: Radius.circular(24),
|
||||
),
|
||||
height: screenHeight * 0.38,
|
||||
width: double.infinity,
|
||||
child: topCardChild)),
|
||||
bottomCardChild,
|
||||
color: Theme.of(context).colorScheme.surfaceContainerLow,
|
||||
),
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: screenHeight * 0.38,
|
||||
),
|
||||
width: double.infinity,
|
||||
child: topCardChild,
|
||||
),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: bottomCardChild,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -33,8 +33,12 @@ abstract class CakePayBuyCardViewModelBase with Store {
|
||||
: 0,
|
||||
quantity = 1,
|
||||
card = vendor.card!,
|
||||
min = _toDouble(vendor.card!.minValue) ?? 0,
|
||||
max = _toDouble(vendor.card!.maxValue) ?? 0 {
|
||||
min = vendor.card!.prepaidRange.isNotEmpty
|
||||
? vendor.card!.prepaidRange.first.minValue
|
||||
: _toDouble(vendor.card!.minValue) ?? 0,
|
||||
max = vendor.card!.prepaidRange.isNotEmpty
|
||||
? vendor.card!.prepaidRange.first.maxValue
|
||||
: _toDouble(vendor.card!.maxValue) ?? 0 {
|
||||
selectedPaymentMethod = availableMethods.isNotEmpty ? availableMethods.first : null;
|
||||
}
|
||||
|
||||
@@ -46,8 +50,6 @@ abstract class CakePayBuyCardViewModelBase with Store {
|
||||
final CakePayVendor vendor;
|
||||
final SendViewModel sendViewModel;
|
||||
final CakePayService _cakePayService;
|
||||
final double max;
|
||||
final double min;
|
||||
final CakePayCard card;
|
||||
final WalletType walletType;
|
||||
final Box<Order> orders;
|
||||
@@ -59,6 +61,8 @@ abstract class CakePayBuyCardViewModelBase with Store {
|
||||
bool confirmsNoVpn = false;
|
||||
bool confirmsVoidedRefund = false;
|
||||
bool confirmsTermsAgreed = false;
|
||||
double max;
|
||||
double min;
|
||||
(String, int?) selectedDenomination = ('', null);
|
||||
|
||||
String simulatedResponse = '';
|
||||
@@ -136,10 +140,24 @@ abstract class CakePayBuyCardViewModelBase with Store {
|
||||
@action
|
||||
void onQuantityChanged(int? input) => quantity = input ?? 1;
|
||||
|
||||
void onPrepaidRangeChanged(PrepaidRange range) {
|
||||
min = range.minValue;
|
||||
max = range.maxValue;
|
||||
selectedDenomination = (range.minValue.toString(), int.tryParse(range.rangeId));
|
||||
|
||||
if (amount < min || amount > max) {
|
||||
amount = min;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
void onAmountChanged(String input) {
|
||||
if (input.isEmpty) return;
|
||||
amount = double.parse(input.replaceAll(',', '.'));
|
||||
|
||||
if (card.prepaidRange.isNotEmpty) {
|
||||
selectedDenomination = (input.replaceAll(',', '.'), selectedDenomination.$2);
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -153,10 +171,25 @@ abstract class CakePayBuyCardViewModelBase with Store {
|
||||
sendViewModel.state =
|
||||
FailureState('Unsupported wallet type, please use Bitcoin, Monero, Litecoin or Zcash.');
|
||||
}
|
||||
|
||||
final isPrepaidRangeSelected = card.prepaidRange.isNotEmpty;
|
||||
|
||||
int selectedCardId = card.id;
|
||||
String selectedPrice = amount.toString();
|
||||
|
||||
if (isPrepaidRangeSelected) {
|
||||
selectedCardId = selectedDenomination.$2 ?? card.id;
|
||||
selectedPrice =
|
||||
selectedDenomination.$1.isNotEmpty ? selectedDenomination.$1 : amount.toString();
|
||||
} else if (isDenominationSelected) {
|
||||
selectedCardId = selectedDenomination.$2 ?? card.id;
|
||||
selectedPrice = selectedDenomination.$1;
|
||||
}
|
||||
|
||||
try {
|
||||
order = await _cakePayService.createOrder(
|
||||
cardId: isDenominationSelected ? selectedDenomination.$2 ?? card.id : card.id,
|
||||
price: isDenominationSelected ? selectedDenomination.$1 : amount.toString(),
|
||||
cardId: selectedCardId,
|
||||
price: selectedPrice,
|
||||
quantity: quantity,
|
||||
confirmsNoVpn: confirmsNoVpn,
|
||||
confirmsVoidedRefund: confirmsVoidedRefund,
|
||||
|
||||
Reference in New Issue
Block a user