Some checks are pending
Backend CI / test (push) Waiting to run
Backend CI / build (push) Blocked by required conditions
Deploy Mnemo Cards / Deploy Backend (push) Waiting to run
Deploy Mnemo Cards / Deploy Web App (push) Blocked by required conditions
Deploy Mnemo Cards / Final Verification (push) Blocked by required conditions
167 lines
4.8 KiB
Text
167 lines
4.8 KiB
Text
import 'dart:convert';
|
|
import 'dart:developer';
|
|
|
|
import 'package:dio/dio.dart';
|
|
import 'package:injectable/injectable.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 '../../main.dart';
|
|
import '../../packs/pack_manager.dart';
|
|
|
|
@LazySingleton()
|
|
class YooMoneyHandler {
|
|
final testKey = 'test_Px7SnKrsT0fO8ZKXmnzNqMknuHne7LwG-ypKhJnw9Ro';
|
|
final testShop = '382060';
|
|
|
|
final key = 'live_17KhhN5jmobRyjS2LKHPOBVs6noAtJYCg4Wyd_-3byQ';
|
|
final shop = '380354';
|
|
|
|
late final _yookassaClient = YookassaClient(
|
|
Dio(),
|
|
credentials: YookassaAuthCredentials(
|
|
shopId: shop,
|
|
secretKey: key,
|
|
),
|
|
);
|
|
|
|
late final _testYookassaClient = YookassaClient(
|
|
Dio(),
|
|
credentials: YookassaAuthCredentials(
|
|
shopId: testShop,
|
|
secretKey: testKey,
|
|
),
|
|
);
|
|
Map<String, DateTime> _testPayments = {};
|
|
|
|
YookassaClient get yookassaClient => _yookassaClient;
|
|
|
|
final PackManager _packManager;
|
|
|
|
YooMoneyHandler(this._packManager);
|
|
|
|
Future<YookassaPaymentDto?> createPayment({
|
|
required String productId,
|
|
required String price,
|
|
required String title,
|
|
required UserModel user,
|
|
required MnemoCardsProductType productType,
|
|
}) async {
|
|
if (user.id == null) {
|
|
return null;
|
|
}
|
|
|
|
final reservedPaymentId = await isar.writeTxn(
|
|
() => isar.paymentModels.put(
|
|
PaymentModel.empty(
|
|
date: DateTime.now(),
|
|
userId: user.id!,
|
|
),
|
|
),
|
|
);
|
|
|
|
final checkPaymentUrl = PurchaseCheckDeeplink(
|
|
id: productId,
|
|
productType: productType,
|
|
token: reservedPaymentId.toString(),
|
|
paymentSystem: PaymentSystem.yookassa,
|
|
).uri.toString();
|
|
|
|
final amount = Amount(
|
|
value: price.replaceAll(new RegExp(r"\D"), ""),
|
|
currency: 'RUB',
|
|
);
|
|
final createdPaymentRequest = CreatePaymentRequest(
|
|
amount: amount,
|
|
receipt: YookassaReceipt(
|
|
customer: YookassaCustomer(
|
|
email: user.email,
|
|
),
|
|
items: [
|
|
YookassaItem(description: title, quantity: '1', amount: amount),
|
|
],
|
|
),
|
|
confirmation: YookassaConfirmation.redirect(
|
|
returnUrl: checkPaymentUrl,
|
|
),
|
|
capture: true,
|
|
description: title,
|
|
);
|
|
|
|
try {
|
|
final payment = await yookassaClient.createPayment(
|
|
paymentRequest: createdPaymentRequest,
|
|
);
|
|
isar.writeTxn(() async {
|
|
final paymentId = await isar.paymentModels.put(
|
|
PaymentModel.yooKassa(
|
|
id: reservedPaymentId,
|
|
amount: payment.amount.value,
|
|
currency: payment.amount.currency,
|
|
date: DateTime.now(),
|
|
userId: user.id!,
|
|
packs: [
|
|
if (productType == MnemoCardsProductType.pack) productId,
|
|
],
|
|
subscription: productType == MnemoCardsProductType.subscription,
|
|
externalToken: payment.id,
|
|
meta: jsonEncode(payment.toJson()),
|
|
products: [
|
|
if (productType == MnemoCardsProductType.pack)
|
|
MnemoCardsProductModelBase.pack(
|
|
int.tryParse(productId),
|
|
)
|
|
else if (productType == MnemoCardsProductType.subscription)
|
|
MnemoCardsProductModelBase.subscription(
|
|
int.tryParse(productId),
|
|
)
|
|
],
|
|
),
|
|
);
|
|
await isar.userModels.put(
|
|
user.copyWith(purchases: [...user.purchases, paymentId.toString()]),
|
|
);
|
|
});
|
|
final url = payment.confirmation?.maybeMap(
|
|
embedded: (_) {},
|
|
external: (_) {},
|
|
mobileApplication: (_) {},
|
|
qr: (_) {},
|
|
redirect: (redirect) => redirect.confirmationUrl,
|
|
orElse: () => null,
|
|
);
|
|
if (url == null) {
|
|
throw Exception('Yookassa url is null');
|
|
}
|
|
return YookassaPaymentDto(
|
|
purchaseUrl: url,
|
|
checkUrl: checkPaymentUrl,
|
|
);
|
|
} on YookassaException catch (e, s) {
|
|
print(e);
|
|
log('YookassaException when creating Yookassa payment',
|
|
error: e, stackTrace: s);
|
|
} on Exception catch (e, s) {
|
|
print(e);
|
|
log('Error when creating Yookassa payment', error: e, stackTrace: s);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Future<YookassaPayment> checkPayment(String yookassaId) async {
|
|
final payment = await yookassaClient.getPaymentInfo(
|
|
paymentId: yookassaId,
|
|
);
|
|
return payment;
|
|
}
|
|
}
|
|
|
|
extension YookassaPaymentStatusExt on YookassaPaymentStatus {
|
|
PaymentStatus toPaymentStatus() => switch (this) {
|
|
YookassaPaymentStatus.pending => PaymentStatus.created,
|
|
YookassaPaymentStatus.waitingForCapture => PaymentStatus.waiting,
|
|
YookassaPaymentStatus.succeeded => PaymentStatus.succeeded,
|
|
YookassaPaymentStatus.canceled => PaymentStatus.canceled,
|
|
};
|
|
}
|