513 lines
17 KiB
Text
513 lines
17 KiB
Text
|
|
import 'dart:convert';
|
||
|
|
import 'dart:developer';
|
||
|
|
import 'dart:io';
|
||
|
|
import 'package:dio/dio.dart';
|
||
|
|
import 'package:googleapis/androidpublisher/v3.dart' as ap;
|
||
|
|
import 'package:googleapis/firestore/v1.dart' as fs;
|
||
|
|
|
||
|
|
import 'package:googleapis_auth/auth_io.dart' as auth;
|
||
|
|
import 'package:injectable/injectable.dart';
|
||
|
|
import 'package:mnemo_cards_backend/api/purchase/google_play_purchase_handler.dart';
|
||
|
|
import 'package:mnemo_cards_backend/api/purchase/rustore/rustore_purchase_response.dart';
|
||
|
|
import 'package:mnemo_cards_backend/database/database.dart';
|
||
|
|
import 'package:mnemo_cards_common_backend/mnemo_cards_common_backend.dart';
|
||
|
|
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
|
||
|
|
import 'package:yookassa_client/yookassa_client.dart';
|
||
|
|
import 'package:drift/drift.dart' as drift;
|
||
|
|
|
||
|
|
import 'payment_drift_extension.dart';
|
||
|
|
import '../../main.dart' as backend_main;
|
||
|
|
|
||
|
|
import '../../packs/pack_manager.dart';
|
||
|
|
import '../../packs/products_price_resolver.dart';
|
||
|
|
import '../subscription/subscription_manager.dart';
|
||
|
|
import 'iap_repository.dart';
|
||
|
|
import 'rustore/rustore_purchase_handler.dart';
|
||
|
|
import 'yoo_money.dart';
|
||
|
|
|
||
|
|
@lazySingleton
|
||
|
|
class PaymentManager {
|
||
|
|
final AppDatabase _db;
|
||
|
|
final PackManager _packManager;
|
||
|
|
final SubscriptionManager _subscriptionManager;
|
||
|
|
late final GooglePlayPurchaseHandler googlePurchaseHandler;
|
||
|
|
final YooMoneyHandler _yooMoneyHandler;
|
||
|
|
final RustorePurchaseHandler _rustorePurchaseHandler;
|
||
|
|
final ProductsPriceResolver _productsPriceResolver;
|
||
|
|
|
||
|
|
PaymentManager(
|
||
|
|
this._db,
|
||
|
|
this._packManager,
|
||
|
|
this._subscriptionManager,
|
||
|
|
this._yooMoneyHandler,
|
||
|
|
this._rustorePurchaseHandler,
|
||
|
|
this._productsPriceResolver,
|
||
|
|
);
|
||
|
|
|
||
|
|
/// Создать платеж в базе данных
|
||
|
|
Future<PaymentDto> createPayment(PaymentDto paymentDto, int userId) async {
|
||
|
|
final companion = paymentDto.toCompanion(userId);
|
||
|
|
final paymentId = await _db.paymentDao.createPayment(companion);
|
||
|
|
final payment = await _db.paymentDao.getPaymentById(paymentId);
|
||
|
|
if (payment == null) {
|
||
|
|
throw Exception('Failed to create payment');
|
||
|
|
}
|
||
|
|
return payment.toDto();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Обновить платеж в базе данных
|
||
|
|
Future<void> updatePayment(PaymentDto paymentDto) async {
|
||
|
|
final paymentId = int.parse(paymentDto.id);
|
||
|
|
final companion = paymentDto.toUpdateCompanion(paymentId);
|
||
|
|
await _db.paymentDao.updatePaymentCompanion(companion);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Получить платеж по ID
|
||
|
|
Future<PaymentDto?> getPaymentById(int id) async {
|
||
|
|
final payment = await _db.paymentDao.getPaymentById(id);
|
||
|
|
return payment?.toDto();
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Creates the Google Play and Apple Store [PurchaseHandler]
|
||
|
|
/// and their dependencies
|
||
|
|
Future<Map<String, GooglePlayPurchaseHandler>>
|
||
|
|
_createPurchaseHandlers() async {
|
||
|
|
// Configure Android Publisher API access
|
||
|
|
final serviceAccountGooglePlay =
|
||
|
|
File('data/service-account-google-play.json').readAsStringSync();
|
||
|
|
final clientCredentialsGooglePlay =
|
||
|
|
auth.ServiceAccountCredentials.fromJson(serviceAccountGooglePlay);
|
||
|
|
final clientGooglePlay =
|
||
|
|
await auth.clientViaServiceAccount(clientCredentialsGooglePlay, [
|
||
|
|
ap.AndroidPublisherApi.androidpublisherScope,
|
||
|
|
]);
|
||
|
|
final androidPublisher = ap.AndroidPublisherApi(clientGooglePlay);
|
||
|
|
|
||
|
|
// Configure Firestore API access
|
||
|
|
final serviceAccountFirebase =
|
||
|
|
File('assets/service-account-firebase.json').readAsStringSync();
|
||
|
|
final clientCredentialsFirebase =
|
||
|
|
auth.ServiceAccountCredentials.fromJson(serviceAccountFirebase);
|
||
|
|
final clientFirebase =
|
||
|
|
await auth.clientViaServiceAccount(clientCredentialsFirebase, [
|
||
|
|
fs.FirestoreApi.cloudPlatformScope,
|
||
|
|
]);
|
||
|
|
final firestoreApi = fs.FirestoreApi(clientFirebase);
|
||
|
|
final dynamic json = jsonDecode(serviceAccountFirebase);
|
||
|
|
final projectId = json['project_id'] as String;
|
||
|
|
final iapRepository = IapRepository(firestoreApi, projectId);
|
||
|
|
|
||
|
|
return {
|
||
|
|
'google_play': GooglePlayPurchaseHandler(
|
||
|
|
androidPublisher,
|
||
|
|
iapRepository,
|
||
|
|
),
|
||
|
|
// 'app_store': AppStorePurchaseHandler(
|
||
|
|
// iapRepository,
|
||
|
|
// ),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<void> init() async {
|
||
|
|
googlePurchaseHandler = (await _createPurchaseHandlers()).values.first;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<YookassaPaymentDto?> createYooMoneyPayment(
|
||
|
|
String productId,
|
||
|
|
MnemoCardsProductType productType,
|
||
|
|
UserModel? user,
|
||
|
|
) async {
|
||
|
|
if (user == null) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (productType == MnemoCardsProductType.pack) {
|
||
|
|
final pack = await _packManager.getBuyPage(productId, user);
|
||
|
|
if (pack == null) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
final dto = await _yooMoneyHandler.createPayment(
|
||
|
|
productId: pack.id,
|
||
|
|
productType: MnemoCardsProductType.pack,
|
||
|
|
// Price with discounts
|
||
|
|
price: pack.price!,
|
||
|
|
title: pack.title,
|
||
|
|
user: user,
|
||
|
|
);
|
||
|
|
return dto;
|
||
|
|
} else if (productType == MnemoCardsProductType.subscription) {
|
||
|
|
await user.subscriptionModel.load();
|
||
|
|
if (user.subscriptionModel.value?.isActive == true) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
final sub = await _subscriptionManager.getSubscriptionPlan(productId);
|
||
|
|
if (sub == null) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
final dto = await _yooMoneyHandler.createPayment(
|
||
|
|
productId: productId,
|
||
|
|
productType: MnemoCardsProductType.subscription,
|
||
|
|
title: sub.ui?.title ?? 'Подписка',
|
||
|
|
price: await _productsPriceResolver.userSubscriptionPrice(user, sub),
|
||
|
|
user: user,
|
||
|
|
);
|
||
|
|
return dto;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Future<String?> createGooglePayment(String packId, UserModel? user) async {
|
||
|
|
// if (user == null) {
|
||
|
|
// return null;
|
||
|
|
// }
|
||
|
|
// final pack = await _packManager.getBuyPage(packId, user);
|
||
|
|
// if (pack == null) {
|
||
|
|
// return null;
|
||
|
|
// }
|
||
|
|
// final product = await googlePurchaseHandler.getProduct(pack.googlePlayId!);
|
||
|
|
// if (product == null) {
|
||
|
|
// return null;
|
||
|
|
// }
|
||
|
|
// isar.writeTxnSync(() {
|
||
|
|
// final paymentId = isar.paymentModels.putSync(
|
||
|
|
// PaymentModel.google(
|
||
|
|
// amount: product.defaultPrice.priceMicros,
|
||
|
|
// currency: product.defaultPrice.currency,
|
||
|
|
// userId: user.id!,
|
||
|
|
// packs: [pack.id],
|
||
|
|
// externalToken: payment.id,
|
||
|
|
// meta: jsonEncode(payment.toJson()),
|
||
|
|
// ),
|
||
|
|
// );
|
||
|
|
// isar.userModels.putSync(
|
||
|
|
// user.copyWith(purchases: [...user.purchases, paymentId.toString()]),
|
||
|
|
// );
|
||
|
|
// })
|
||
|
|
//
|
||
|
|
// if (url != null) {
|
||
|
|
// [3, 5, 10].map(
|
||
|
|
// (e) =>
|
||
|
|
// Future.delayed(
|
||
|
|
// Duration(minutes: e),
|
||
|
|
// () => checkAndProcessUserPayments(user),
|
||
|
|
// ),
|
||
|
|
// );
|
||
|
|
// }
|
||
|
|
// return url;
|
||
|
|
// }
|
||
|
|
|
||
|
|
Future<void> processPayment(PaymentModel paymentModel) async {
|
||
|
|
if (paymentModel.status == PaymentStatus.processed) {
|
||
|
|
log('Payment already processed');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (paymentModel.status == PaymentStatus.succeeded) {
|
||
|
|
// TODO: Replace with _db.userDao after model conversion
|
||
|
|
final user = await backend_main.database.transaction(() async {
|
||
|
|
// Temporary: Need to convert between Isar UserModel and Drift User
|
||
|
|
final user = await backend_main.database.userDao.getUserById(paymentModel.userId);
|
||
|
|
await user?.subscriptionModel.load();
|
||
|
|
return user;
|
||
|
|
});
|
||
|
|
if (user == null) {
|
||
|
|
print('User not found ${paymentModel.userId}');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
// TODO: Replace with PackDao after model conversion (CardPackModel -> CardPack)
|
||
|
|
final packs = await isar.txn(
|
||
|
|
() async => (await isar.cardPackModels.getAll(
|
||
|
|
{
|
||
|
|
...paymentModel.packs.map((e) => int.parse(e)),
|
||
|
|
...paymentModel.products
|
||
|
|
.where((p) => p.type == MnemoCardsProductModelType.pack)
|
||
|
|
.map((e) => e.id)
|
||
|
|
.whereNotNull(),
|
||
|
|
}.toList(),
|
||
|
|
))
|
||
|
|
.whereNotNull(),
|
||
|
|
);
|
||
|
|
|
||
|
|
final subs = paymentModel.products
|
||
|
|
.where((p) => p.type == MnemoCardsProductModelType.subscription)
|
||
|
|
.toList();
|
||
|
|
SubscriptionPlanModel? planModel;
|
||
|
|
if (subs.isNotEmpty) {
|
||
|
|
planModel = await _subscriptionManager
|
||
|
|
.getSubscriptionPlan(subs.first.id.toString());
|
||
|
|
}
|
||
|
|
|
||
|
|
await isar.writeTxn(() async {
|
||
|
|
if (packs.isNotEmpty) {
|
||
|
|
await (user.packs..addAll(packs)).save();
|
||
|
|
}
|
||
|
|
if (planModel != null) {
|
||
|
|
final userSubscriptionModel = UserSubscriptionModel(
|
||
|
|
start: DateTime.now(),
|
||
|
|
finish: DateTime.now().add(Duration(days: planModel.durationDays)),
|
||
|
|
features: [...planModel.features],
|
||
|
|
);
|
||
|
|
user.subscriptionModel.value = userSubscriptionModel;
|
||
|
|
await isar.userSubscriptionModels.put(userSubscriptionModel);
|
||
|
|
await user.subscriptionModel.save();
|
||
|
|
}
|
||
|
|
await isar.userModels.put(user);
|
||
|
|
await isar.paymentModels.put(
|
||
|
|
paymentModel.copyWith(
|
||
|
|
status: PaymentStatus.processed,
|
||
|
|
),
|
||
|
|
);
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
throw Exception('Payment status is not success');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<List<PaymentDto>> getUserPayments(String userIdString) async {
|
||
|
|
final userId = int.tryParse(userIdString);
|
||
|
|
if (userId == null) return [];
|
||
|
|
|
||
|
|
final payments = await _db.paymentDao.getPaymentsByUserId(userId);
|
||
|
|
return payments.map((p) => p.toDto()).toList();
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<List<PaymentModel>> checkAndProcessUserPayments(
|
||
|
|
UserModel model,
|
||
|
|
) async {
|
||
|
|
final payments = await getUserPayments(model.id.toString());
|
||
|
|
final updatedPayments = <PaymentModel>[];
|
||
|
|
for (final payment in payments) {
|
||
|
|
try {
|
||
|
|
updatedPayments.add(
|
||
|
|
await checkAndProcessPayment(payment),
|
||
|
|
);
|
||
|
|
} catch (e) {
|
||
|
|
print(e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return updatedPayments
|
||
|
|
.where((element) => element.status == PaymentStatus.succeeded)
|
||
|
|
.toList();
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<bool> checkYookassaPayment(
|
||
|
|
MnemoCardsProductDto product,
|
||
|
|
String token,
|
||
|
|
UserModel? user,
|
||
|
|
) async {
|
||
|
|
final modelId = int.tryParse(token);
|
||
|
|
if (modelId == null) {
|
||
|
|
log('Invalid payment model id: ${token}');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
final model = await _db.paymentDao.getPaymentById(modelId);
|
||
|
|
if (model == null) {
|
||
|
|
log('Payment model with id ${modelId} not found');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (model.externalToken == null) {
|
||
|
|
log('Payment model ${modelId} has no external token');
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
final result = await checkAndProcessPayment(model);
|
||
|
|
return result.status == PaymentStatus.succeeded;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<bool> checkGooglePayment({
|
||
|
|
required MnemoCardsProductDto product,
|
||
|
|
required String token,
|
||
|
|
required UserModel? user,
|
||
|
|
}) async {
|
||
|
|
final productId = product.id.toString();
|
||
|
|
if (product.type == MnemoCardsProductType.pack) {
|
||
|
|
final productPurchase = await googlePurchaseHandler.handleNonSubscription(
|
||
|
|
productId: productId,
|
||
|
|
token: token,
|
||
|
|
);
|
||
|
|
if (productPurchase == null) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
final pack = await isar.txn(
|
||
|
|
() => isar.cardPackModels
|
||
|
|
.filter()
|
||
|
|
.googlePlayIdEqualTo(productId)
|
||
|
|
.findFirst(),
|
||
|
|
);
|
||
|
|
PaymentModel? model = await isar.txn(
|
||
|
|
() =>
|
||
|
|
isar.paymentModels.filter().externalTokenEqualTo(token).findFirst(),
|
||
|
|
);
|
||
|
|
final googleStatus = GooglePlayPurchaseHandler.nonSubscriptionStatusFrom(
|
||
|
|
productPurchase.purchaseState);
|
||
|
|
|
||
|
|
PaymentModel updatedModel;
|
||
|
|
if (model == null) {
|
||
|
|
final product = (await googlePurchaseHandler.getProduct(productId))!;
|
||
|
|
final price =
|
||
|
|
product.prices?[productPurchase.regionCode] ?? product.defaultPrice;
|
||
|
|
final amount = int.tryParse(price?.priceMicros ?? '')?.toString() ?? '';
|
||
|
|
final currency = price?.currency ?? '';
|
||
|
|
updatedModel = PaymentModel.google(
|
||
|
|
amount: amount,
|
||
|
|
currency: currency,
|
||
|
|
userId: user!.id!,
|
||
|
|
externalToken: token,
|
||
|
|
date: DateTime.now(),
|
||
|
|
packs: [pack?.id.toString() ?? ''],
|
||
|
|
products: [
|
||
|
|
MnemoCardsProductModelBase.pack(pack?.id),
|
||
|
|
],
|
||
|
|
subscription: productId == 'subscription',
|
||
|
|
meta: jsonEncode(productPurchase.toJson()),
|
||
|
|
status: PaymentStatus.created,
|
||
|
|
);
|
||
|
|
await _db.paymentDao.updatePayment(updatedModel.toPayment());
|
||
|
|
} else {
|
||
|
|
updatedModel =
|
||
|
|
model.copyWith(meta: jsonEncode(productPurchase.toJson()));
|
||
|
|
await _db.paymentDao.updatePayment(updatedModel.toPayment());
|
||
|
|
}
|
||
|
|
if (googleStatus == PaymentStatus.succeeded) {
|
||
|
|
try {
|
||
|
|
processPayment(updatedModel);
|
||
|
|
} catch (error) {
|
||
|
|
print(error);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
final acknowledged =
|
||
|
|
await googlePurchaseHandler.acknowledge(productId, token);
|
||
|
|
if (!acknowledged) {
|
||
|
|
await _db.paymentDao.updatePayment(
|
||
|
|
updatedModel.copyWith(status: PaymentStatus.waiting).toPayment(),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<bool> checkRustorePayment({
|
||
|
|
required String productId,
|
||
|
|
required String subscriptionToken,
|
||
|
|
required UserModel? user,
|
||
|
|
}) async {
|
||
|
|
final rustorePurchaseResponse =
|
||
|
|
await _rustorePurchaseHandler.checkPayment(subscriptionToken);
|
||
|
|
final pack = await isar.txn(
|
||
|
|
() =>
|
||
|
|
isar.cardPackModels.filter().rustoreIdEqualTo(productId).findFirst(),
|
||
|
|
);
|
||
|
|
PaymentModel? model = await isar.txn(
|
||
|
|
() => isar.paymentModels
|
||
|
|
.filter()
|
||
|
|
.externalTokenEqualTo(subscriptionToken)
|
||
|
|
.findFirst(),
|
||
|
|
);
|
||
|
|
final meta = rustorePurchaseResponse?.let(jsonEncode);
|
||
|
|
|
||
|
|
PaymentModel updatedModel;
|
||
|
|
if (model == null) {
|
||
|
|
updatedModel = PaymentModel.rustore(
|
||
|
|
amount: pack?.price ?? 'no-price',
|
||
|
|
currency: 'rub',
|
||
|
|
userId: user!.id!,
|
||
|
|
externalToken: subscriptionToken,
|
||
|
|
date: DateTime.now(),
|
||
|
|
products: [
|
||
|
|
MnemoCardsProductModelBase.pack(pack?.id),
|
||
|
|
],
|
||
|
|
packs: [pack?.id.toString() ?? ''],
|
||
|
|
subscription: productId == 'subscription',
|
||
|
|
meta: meta,
|
||
|
|
status: rustorePurchaseResponse?.invoiceStatus.toPaymentStatus() ??
|
||
|
|
PaymentStatus.created,
|
||
|
|
);
|
||
|
|
await isar.writeTxn(() {
|
||
|
|
return isar.paymentModels.put(updatedModel);
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
updatedModel = model.copyWith(meta: meta);
|
||
|
|
await _db.paymentDao.updatePayment(updatedModel.toPayment());
|
||
|
|
}
|
||
|
|
if (updatedModel.status == PaymentStatus.succeeded) {
|
||
|
|
try {
|
||
|
|
processPayment(updatedModel);
|
||
|
|
} catch (error) {
|
||
|
|
print(error);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
Future<PaymentModel> checkAndProcessPayment(PaymentModel model) async {
|
||
|
|
var paymentStatus = model.status;
|
||
|
|
if (model.status == PaymentStatus.created) {
|
||
|
|
if (model.paymentSystem == PaymentSystem.rustore) {
|
||
|
|
if (model.externalToken != null) {
|
||
|
|
final payment =
|
||
|
|
await _rustorePurchaseHandler.checkPayment(model.externalToken!);
|
||
|
|
paymentStatus =
|
||
|
|
payment?.invoiceStatus.toPaymentStatus() ?? PaymentStatus.unknown;
|
||
|
|
}
|
||
|
|
} else if (model.paymentSystem == PaymentSystem.yookassa) {
|
||
|
|
print(
|
||
|
|
'Checking ${model.paymentSystem.name} ${model.status.name} ${model.id}');
|
||
|
|
try {
|
||
|
|
final payment =
|
||
|
|
await _yooMoneyHandler.checkPayment(model.externalToken!);
|
||
|
|
paymentStatus = payment.status.toPaymentStatus();
|
||
|
|
} on DioException catch (e) {
|
||
|
|
print(
|
||
|
|
'Dio exception ${model.paymentSystem.name} ${model.status.name} ${model.id}');
|
||
|
|
print('Yookassa dio error: ${e}');
|
||
|
|
final error = e.error;
|
||
|
|
if (error is YookassaException) {
|
||
|
|
print('Yookassa payment error: ${e}');
|
||
|
|
if (error.code == YookassaErrorCode.notFound) {
|
||
|
|
paymentStatus = PaymentStatus.unknown;
|
||
|
|
print('Yookassa payment not found: ${model.externalToken}');
|
||
|
|
} else {
|
||
|
|
rethrow;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
} on Object catch (e, s) {
|
||
|
|
print(
|
||
|
|
'Exception ${model.paymentSystem.name} ${model.status.name} ${model.id}');
|
||
|
|
print(e);
|
||
|
|
print(s);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
print(
|
||
|
|
'Checked ${model.paymentSystem.name} ${model.status.name}->${paymentStatus} ${model.id}');
|
||
|
|
}
|
||
|
|
|
||
|
|
final updatedModel = model.copyWith(
|
||
|
|
status: paymentStatus,
|
||
|
|
);
|
||
|
|
if (model.status != updatedModel.status) {
|
||
|
|
await _db.paymentDao.updatePayment(updatedModel.toPayment());
|
||
|
|
}
|
||
|
|
|
||
|
|
if (updatedModel.status == PaymentStatus.succeeded) {
|
||
|
|
print(
|
||
|
|
'Processing ${updatedModel.paymentSystem.name} ${updatedModel.status.name} ${updatedModel.id}');
|
||
|
|
try {
|
||
|
|
processPayment(updatedModel);
|
||
|
|
} catch (error) {
|
||
|
|
print(error);
|
||
|
|
print(
|
||
|
|
'Process error ${updatedModel.paymentSystem.name} ${updatedModel.status.name} ${updatedModel.id}');
|
||
|
|
return model;
|
||
|
|
}
|
||
|
|
await _db.paymentDao.updatePayment(updatedModel.toPayment());
|
||
|
|
print(
|
||
|
|
'Processed ${updatedModel.paymentSystem.name} ${updatedModel.status.name} ${updatedModel.id}',
|
||
|
|
);
|
||
|
|
} else if (updatedModel.status == PaymentStatus.unknown) {
|
||
|
|
await _db.paymentDao.updatePayment(updatedModel.toPayment());
|
||
|
|
}
|
||
|
|
return updatedModel;
|
||
|
|
}
|
||
|
|
}
|