createDeposit method
Creates a OperationDeposit.
Implementation
Future<Operation?> createDeposit() async {
operationStatus.value = RxStatus.loading();
try {
// Under Web platforms, it's better to open the popup as fast as possible
// due to browser usual policies to block unexpected popups.
//
// Thus the mutation itself is happening within the popup afterwards
//
// Message passing cannot be reliable due to iOS Safari, for example,
// freezing the execution when tab is not in focus.
if (PlatformUtils.isDesktop && !PlatformUtils.isWeb) {
operation.value = await _walletService.createOperationDeposit(
methodId: method.id,
nominal: nominal,
country: country,
paypal: _secret ??= OperationDepositSecret.generate(),
);
}
operationStatus.value = RxStatus.success();
String? orderId;
Price? total;
final OperationDepositMethodPricing? pricing = method.pricing;
final Price? perNominal = pricing?.total;
if (perNominal != null) {
total = nominal * perNominal;
}
final Operation? order = operation.value?.value;
if (order is OperationDeposit) {
final details = order.details;
if (details is OperationDepositPayPalDetails) {
orderId = details.processingUrl.val.split('?order_id=').last;
}
if (total == null) {
final OperationDepositPricing? pricing = order.pricing;
final Price? perNominal = pricing?.total;
if (perNominal != null) {
total = nominal * perNominal;
}
}
}
// Ensure parameters used by PayPal HTML page are up to date.
final MyUser? myUser = this.myUser.value;
if (myUser != null) {
WebUtils.putAccount(myUser.id);
}
final String url = '${Config.origin}/payment/paypal.html';
final Map<String, dynamic> parameters = {
'price': total?.l10n ?? nominal.l10next(digits: 0),
'account': myUser?.num.toString(),
'name': myUser?.title,
'client-id': Config.payPalClientId,
if (orderId == null) ...{
'operation-id': operation.value?.value.id.val,
'secret': _secret?.val,
'method-id': method.id,
'nominal': nominal.l10next(digits: 0),
'country': country.val,
} else
'order-id': orderId,
};
final WindowHandle handle = await WebUtils.openPopup(
url,
parameters: parameters,
);
_messagesSubscription?.cancel();
_messagesSubscription = handle.messages.listen((e) async {
Log.debug('Message received from `WindowHandle` -> $e', '$runtimeType');
if (e is Map) {
final type = e['type'];
if (type is String) {
switch (type) {
case 'createOperationDeposit':
final operationId = e['operationId'];
if (operationId is String) {
operation.value = await _walletService.get(
id: OperationId(operationId),
);
_startResponseTimer();
}
break;
}
}
}
});
if (!handle.isOpen) {
Log.warning(
'createDeposit() -> Popup didn\'t open, trying `launchUrlString()`...',
'$runtimeType',
);
try {
final bool isOpen = await launchUrlString(
'$url?${parameters.entries.map((e) => '${e.key}=${e.value}').join('&')}',
);
Log.warning(
'createDeposit() -> `launchUrlString()` is open: $isOpen',
'$runtimeType',
);
if (!isOpen) {
await MessagePopup.alert(
'Window cannot be opened automatically',
button: (context) {
return PrimaryButton(
onPressed: () async {
await launchUrlString(
'$url?${parameters.entries.map((e) => '${e.key}=${e.value}').join('&')}',
);
},
title: 'btn_proceed'.l10n,
);
},
);
}
} catch (e) {
Log.error(
'createDeposit() -> unable to do `launchUrlString()` due to $e',
'$runtimeType',
);
MessagePopup.error(e);
rethrow;
}
_startResponseTimer();
}
return operation.value?.value;
} catch (e) {
operationStatus.value = RxStatus.error('err_data_transfer'.l10n);
error.value = e.toString();
rethrow;
} finally {
status.value = PayPalDepositStatus.inProgress;
}
}