1.0.3: Fixed iOS confirmation flow. Refactored TokenizationResult, now it's have SuccessTokenizationResult, ErrorTokenizationResult and CanceledTokenizationResult versions.

This commit is contained in:
Искандар Р. Шабаев 2022-09-08 11:32:35 +03:00
parent 187f2a4af5
commit 6b72dfee66
15 changed files with 267 additions and 164 deletions

13
.vscode/launch.json vendored
View File

@ -22,6 +22,19 @@
"--flavor", "--flavor",
"dev" "dev"
] ]
},
{
"name": "demo-debug-prod",
"cwd": "demo",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"-t",
"lib/main_prod.dart",
"--flavor",
"prod"
]
} }
] ]
} }

View File

@ -1,3 +1,14 @@
# 1.0.3
* Fixed iOS confirmation flow. Refactored `TokenizationResult`, now it's have SuccessTokenizationResult, ErrorTokenizationResult and CanceledTokenizationResult versions.
Not to get token from TokenizationResult you need to check it's type:
```
var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData);
if (result is SuccessTokenizationResult) {
result.token
}
```
# 1.0.2 # 1.0.2
* Made applePayID and moneyAuthClientId fields optional. * Made applePayID and moneyAuthClientId fields optional.

View File

@ -6,6 +6,7 @@ import ru.yoomoney.sdk.kassa.payments.checkoutParameters.PaymentMethodType
fun TokenizationResult.toJson(): String { fun TokenizationResult.toJson(): String {
val json = JSONObject() val json = JSONObject()
json.put("status", "success")
json.put("paymentToken", paymentToken) json.put("paymentToken", paymentToken)
json.put("paymentMethodType", when(paymentMethodType) { json.put("paymentMethodType", when(paymentMethodType) {
PaymentMethodType.YOO_MONEY -> "yoo_money" PaymentMethodType.YOO_MONEY -> "yoo_money"

View File

@ -36,6 +36,9 @@ import ru.yoomoney.sdk.kassa.payments.checkoutParameters.TestParameters
import ru.yoomoney.sdk.kassa.payments.TokenizationResult import ru.yoomoney.sdk.kassa.payments.TokenizationResult
import ru.yoomoney.sdk.kassa.payments.checkoutParameters.UiParameters import ru.yoomoney.sdk.kassa.payments.checkoutParameters.UiParameters
private const val CANCELED_RESULT = "{\"status\":\"canceled\"}"
private const val ERROR_RESULT = "{\"status\":\"error\"}"
class YookassaPaymentsFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener { class YookassaPaymentsFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener {
private lateinit var flutterResult: Result private lateinit var flutterResult: Result
@ -123,9 +126,13 @@ class YookassaPaymentsFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityA
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean {
if (requestCode == REQUEST_CODE_TOKENIZE) { if (requestCode == REQUEST_CODE_TOKENIZE) {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_CANCELED) {
flutterResult.success(CANCELED_RESULT)
} else if (resultCode == Activity.RESULT_OK && data != null) {
val result: TokenizationResult = Checkout.createTokenizationResult(data); val result: TokenizationResult = Checkout.createTokenizationResult(data);
flutterResult.success(result.toJson()) flutterResult.success(result.toJson())
} else {
flutterResult.success(ERROR_RESULT)
} }
} else if (requestCode == REQUEST_CODE_CONFIRMATION) { } else if (requestCode == REQUEST_CODE_CONFIRMATION) {
flutterResult.success(resultCode) flutterResult.success(resultCode)

View File

@ -42,6 +42,7 @@ post_install do |installer|
target.build_configurations.each do |config| target.build_configurations.each do |config|
config.build_settings["ONLY_ACTIVE_ARCH"] = "YES" config.build_settings["ONLY_ACTIVE_ARCH"] = "YES"
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
end end
end end
end end

View File

@ -1,26 +1,29 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:yookassa_payments_flutter/input_data/saved_card_module_input_data.dart'; import 'package:yookassa_payments_flutter/input_data/saved_card_module_input_data.dart';
import 'package:yookassa_payments_flutter/models/tokenization_result.dart';
import 'package:yookassa_payments_flutter/yookassa_payments_flutter.dart'; import 'package:yookassa_payments_flutter/yookassa_payments_flutter.dart';
class SuccessTokenizationScreen extends StatefulWidget { class SuccessTokenizationScreen extends StatefulWidget {
const SuccessTokenizationScreen({Key? key, required this.result, this.tokenizationData, this.repeatData}) : super(key: key); const SuccessTokenizationScreen(
{Key? key, required this.result, this.tokenizationData, this.repeatData})
: super(key: key);
final TokenizationResult result; final SuccessTokenizationResult result;
final TokenizationModuleInputData? tokenizationData; final TokenizationModuleInputData? tokenizationData;
final SavedBankCardModuleInputData? repeatData; final SavedBankCardModuleInputData? repeatData;
@override @override
State<StatefulWidget> createState() => SuccessTokenizationScreenState(result, tokenizationData, repeatData); State<StatefulWidget> createState() =>
SuccessTokenizationScreenState(result, tokenizationData, repeatData);
} }
class SuccessTokenizationScreenState extends State<SuccessTokenizationScreen> { class SuccessTokenizationScreenState extends State<SuccessTokenizationScreen> {
final TokenizationResult result; final SuccessTokenizationResult result;
final TokenizationModuleInputData? tokenizationData; final TokenizationModuleInputData? tokenizationData;
final SavedBankCardModuleInputData? repeatData; final SavedBankCardModuleInputData? repeatData;
SuccessTokenizationScreenState(this.result, this.tokenizationData, this.repeatData); SuccessTokenizationScreenState(
this.result, this.tokenizationData, this.repeatData);
late TextEditingController controller; late TextEditingController controller;
@ -47,39 +50,41 @@ class SuccessTokenizationScreenState extends State<SuccessTokenizationScreen> {
padding: const EdgeInsets.all(20.0), padding: const EdgeInsets.all(20.0),
child: TextField( child: TextField(
controller: controller, controller: controller,
decoration: const InputDecoration( decoration:
hintText: "3ds / App2App ссылка" const InputDecoration(hintText: "3ds / App2App ссылка"),
),
), ),
), ),
ElevatedButton( ElevatedButton(
onPressed: () async { onPressed: () async {
await YookassaPaymentsFlutter.confirmation(controller.text, result.paymentMethodType); await YookassaPaymentsFlutter.confirmation(
showDialog(context: context, builder: (context) => const AlertDialog( controller.text, result.paymentMethodType);
content: Text("Confirmation process is done"), showDialog(
)); context: context,
builder: (context) => const AlertDialog(
content: Text("Confirmation process is done"),
));
}, },
child: const Text("Подтвердить") child: const Text("Подтвердить")),
),
TextButton( TextButton(
onPressed: () async { onPressed: () async {
showDialog(context: context, builder: (context) => AlertDialog( showDialog(
content: Text(result.token), context: context,
actions: <Widget>[ builder: (context) => AlertDialog(
TextButton( content: Text(result.token),
onPressed: () { actions: <Widget>[
Clipboard.setData(ClipboardData(text: result.token)); TextButton(
Navigator.of(context).pop(); onPressed: () {
}, Clipboard.setData(
child: const Text('Скопировать'), ClipboardData(text: result.token));
), Navigator.of(context).pop();
] },
)); child: const Text('Скопировать'),
),
]));
}, },
child: const Text("Показать токен") child: const Text("Показать токен"))
)
], ],
), ),
); );
} }
} }

View File

@ -1,8 +1,9 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:yookassa_payments_flutter/yookassa_payments_flutter.dart'; import 'package:yookassa_payments_flutter/yookassa_payments_flutter.dart';
import 'package:yookassa_payments_flutter_example/success_tokenization_screen.dart'; import 'package:yookassa_payments_flutter_example/success_tokenization_screen.dart';
import 'package:yookassa_payments_flutter/models/tokenization_result.dart';
class TokenizationScreen extends StatefulWidget{ class TokenizationScreen extends StatefulWidget {
const TokenizationScreen({Key? key}) : super(key: key); const TokenizationScreen({Key? key}) : super(key: key);
@override @override
@ -37,8 +38,7 @@ class TokenizationScreenState extends State<TokenizationScreen> {
onPressed: () async { onPressed: () async {
startTokenization(); startTokenization();
}, },
child: const Text("Оплатить") child: const Text("Оплатить"))
)
], ],
), ),
); );
@ -46,7 +46,8 @@ class TokenizationScreenState extends State<TokenizationScreen> {
void startTokenization() async { void startTokenization() async {
var clientApplicationKey = "<Ключ для клиентских приложений>"; var clientApplicationKey = "<Ключ для клиентских приложений>";
var amount = Amount(value: double.parse(controller.text), currency: Currency.rub); var amount =
Amount(value: double.parse(controller.text), currency: Currency.rub);
var moneyAuthClientId = "<ID для центра авторизации в системе YooMoney>"; var moneyAuthClientId = "<ID для центра авторизации в системе YooMoney>";
var shopId = "<Идентификатор магазина в ЮKassa>"; var shopId = "<Идентификатор магазина в ЮKassa>";
var applicationScheme = "<Схема вашего приложения для deeplink>" "://"; var applicationScheme = "<Схема вашего приложения для deeplink>" "://";
@ -61,16 +62,26 @@ class TokenizationScreenState extends State<TokenizationScreen> {
shopId: shopId, shopId: shopId,
customerId: "<Уникальный идентификатор покупателя>", customerId: "<Уникальный идентификатор покупателя>",
applicationScheme: applicationScheme, applicationScheme: applicationScheme,
tokenizationSettings: const TokenizationSettings( tokenizationSettings: const TokenizationSettings(PaymentMethodTypes([
PaymentMethodTypes([ PaymentMethod.bankCard,
PaymentMethod.bankCard, PaymentMethod.yooMoney,
PaymentMethod.yooMoney, PaymentMethod.sberbank
PaymentMethod.sberbank ])),
]) testModeSettings: null);
), var result =
testModeSettings: null await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData);
); if (result is SuccessTokenizationResult) {
var result = await YookassaPaymentsFlutter.tokenization(tokenizationModuleInputData); Navigator.push(
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) => SuccessTokenizationScreen(result: result, tokenizationData: tokenizationModuleInputData))); context,
MaterialPageRoute(
builder: (BuildContext context) => SuccessTokenizationScreen(
result: result,
tokenizationData: tokenizationModuleInputData)));
} else if (result is ErrorTokenizationResult) {
showDialog(
context: context,
builder: (context) => AlertDialog(content: Text(result.error)));
return;
}
} }
} }

View File

@ -42,7 +42,7 @@ packages:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.16.0" version: "1.15.0"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -56,7 +56,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.2.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -94,7 +94,7 @@ packages:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.3"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -108,7 +108,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.8.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -120,7 +120,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -155,21 +155,28 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.9" version: "0.4.8"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "2.1.1"
yookassa_payments_flutter: yookassa_payments_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "1.0.0" version: "1.0.2"
sdks: sdks:
dart: ">=2.17.0-0 <3.0.0" dart: ">=2.14.0 <3.0.0"
flutter: ">=2.10.5" flutter: ">=2.10.5"

View File

@ -9,6 +9,7 @@ var flutterController: FlutterViewController?
var yoomoneyController: UIViewController? var yoomoneyController: UIViewController?
public class SwiftYookassaPaymentsFlutterPlugin: NSObject, FlutterPlugin { public class SwiftYookassaPaymentsFlutterPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) { public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "ru.yoomoney.yookassa_payments_flutter/yoomoney", binaryMessenger: registrar.messenger()) let channel = FlutterMethodChannel(name: "ru.yoomoney.yookassa_payments_flutter/yoomoney", binaryMessenger: registrar.messenger())
let instance = SwiftYookassaPaymentsFlutterPlugin() let instance = SwiftYookassaPaymentsFlutterPlugin()
@ -18,26 +19,31 @@ public class SwiftYookassaPaymentsFlutterPlugin: NSObject, FlutterPlugin {
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
flutterResult = result flutterResult = result
// Tokenezation Flow
if (call.method == YooMoneyService.tokenization.rawValue) { if (call.method == YooMoneyService.tokenization.rawValue) {
guard let data = call.arguments as? [String:AnyObject], guard let data = call.arguments as? [String:AnyObject],
let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted), let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted),
let tokenizationModuleInputData = try? JSONDecoder().decode(TokenizationModuleInputData.self, from: jsonData) let tokenizationModuleInputData = try? JSONDecoder().decode(TokenizationModuleInputData.self, from: jsonData)
else { else {
result(YooMoneyErrors.tokenizationData.rawValue) result(YooMoneyErrors.tokenizationData.rawValue)
return return
} }
let controller = UIApplication.shared.delegate?.window??.rootViewController as? FlutterViewController
let inputData: TokenizationFlow = .tokenization(tokenizationModuleInputData)
let inputData: TokenizationFlow = .tokenization(tokenizationModuleInputData) if let flutterVC = controller {
let tokenezationViewController = TokenizationAssembly.makeModule(inputData: inputData, moduleOutput: flutterVC)
yoomoneyController = tokenezationViewController;
flutterController = flutterVC;
let controller = UIApplication.shared.delegate?.window??.rootViewController as! FlutterViewController flutterVC.present(tokenezationViewController, animated: true, completion: nil)
}
let vc = TokenizationAssembly.makeModule(inputData: inputData, moduleOutput: controller)
controller.present(vc, animated: true, completion: nil)
flutterController = controller
yoomoneyController = vc
} }
// Confirmation Flow
if (call.method == YooMoneyService.confirmation.rawValue) { if (call.method == YooMoneyService.confirmation.rawValue) {
guard let data = call.arguments as? [String:AnyObject], guard let data = call.arguments as? [String:AnyObject],
let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted), let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted),
@ -79,6 +85,8 @@ public class SwiftYookassaPaymentsFlutterPlugin: NSObject, FlutterPlugin {
) )
} }
// BankCardRepeat Flow
if (call.method == YooMoneyService.repeatPayment.rawValue) { if (call.method == YooMoneyService.repeatPayment.rawValue) {
guard let data = call.arguments as? [String:AnyObject], guard let data = call.arguments as? [String:AnyObject],
let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted), let jsonData = try? JSONSerialization.data(withJSONObject: data, options: .prettyPrinted),
@ -94,6 +102,7 @@ public class SwiftYookassaPaymentsFlutterPlugin: NSObject, FlutterPlugin {
if let controller = flutterController { if let controller = flutterController {
let vc = TokenizationAssembly.makeModule(inputData: inputData, moduleOutput: controller) let vc = TokenizationAssembly.makeModule(inputData: inputData, moduleOutput: controller)
yoomoneyController = vc
tokenizationModuleInput = vc tokenizationModuleInput = vc
controller.present(vc, animated: true, completion: nil) controller.present(vc, animated: true, completion: nil)
} }
@ -102,21 +111,6 @@ public class SwiftYookassaPaymentsFlutterPlugin: NSObject, FlutterPlugin {
} }
extension FlutterViewController: TokenizationModuleOutput { extension FlutterViewController: TokenizationModuleOutput {
public func didSuccessfullyPassedCardSec(on module: TokenizationModuleInput) {
DispatchQueue.main.async { [weak self] in
guard let self = self else { return }
let alertController = UIAlertController(
title: "3D-Sec",
message: "Successfully passed 3d-sec",
preferredStyle: .alert
)
let action = UIAlertAction(title: "OK", style: .default)
alertController.addAction(action)
self.dismiss(animated: true)
self.present(alertController, animated: true)
}
}
public func tokenizationModule( public func tokenizationModule(
_ module: TokenizationModuleInput, _ module: TokenizationModuleInput,
@ -126,7 +120,7 @@ extension FlutterViewController: TokenizationModuleOutput {
tokenizationModuleInput = module tokenizationModuleInput = module
if let result = flutterResult { if let result = flutterResult {
result("{\"paymentToken\": \"\(token.paymentToken)\", \"paymentMethodType\": \"\(paymentMethodType.rawValue)\"}") result("{\"status\":\"success\", \"paymentToken\": \"\(token.paymentToken)\", \"paymentMethodType\": \"\(paymentMethodType.rawValue)\"}")
DispatchQueue.main.async { DispatchQueue.main.async {
if let controller = yoomoneyController { if let controller = yoomoneyController {
controller.dismiss(animated: true) controller.dismiss(animated: true)
@ -144,24 +138,22 @@ extension FlutterViewController: TokenizationModuleOutput {
controller.dismiss(animated: true) controller.dismiss(animated: true)
} }
} }
guard let result = flutterResult else { return }
if let error = error {
result("{\"status\":\"error\", \"error\": \"\(error.localizedDescription)\"}")
} else {
result("{\"status\":\"canceled\"}")
}
} }
public func didSuccessfullyConfirmation( public func didFinishConfirmation(paymentMethodType: PaymentMethodType) {
paymentMethodType: PaymentMethodType guard let result = flutterResult else { return }
) {
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
guard let self = self else { return } if let controller = yoomoneyController {
let alertController = UIAlertController( controller.dismiss(animated: true)
title: "Confirmation", }
message: "Successfully confirmation",
preferredStyle: .alert
)
let action = UIAlertAction(title: "OK", style: .default)
alertController.addAction(action)
self.dismiss(animated: true)
self.present(alertController, animated: true)
} }
result("{\"paymentMethodType\": \"\(paymentMethodType.rawValue)\"}")
} }
} }
@ -292,8 +284,8 @@ extension TokenizationModuleInputData: Decodable {
extension BankCardRepeatModuleInputData: Decodable { extension BankCardRepeatModuleInputData: Decodable {
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case clientApplicationKey = "clientApplicationKey" case clientApplicationKey = "clientApplicationKey"
case shopName = "shopName" case shopName = "title"
case purchaseDescription = "purchaseDescription" case purchaseDescription = "subtitle"
case amount = "amount" case amount = "amount"
case savePaymentMethod = "savePaymentMethod" case savePaymentMethod = "savePaymentMethod"
case paymentMethodId = "paymentMethodId" case paymentMethodId = "paymentMethodId"

View File

@ -11,7 +11,7 @@ Flutter SDK from yoomoney
s.source = { :path => '.' } s.source = { :path => '.' }
s.source_files = 'Classes/**/*' s.source_files = 'Classes/**/*'
s.dependency 'Flutter' s.dependency 'Flutter'
s.dependency 'YooKassaPayments', '6.8.0' s.dependency 'YooKassaPayments', '6.9.0'
s.platform = :ios, '10.0' s.platform = :ios, '10.0'

View File

@ -6,11 +6,16 @@ class PaymentMethodTypes {
return paymentMethodTypes.map((e) => e.toString()).toList(); return paymentMethodTypes.map((e) => e.toString()).toList();
} }
static const PaymentMethodTypes bankCard = PaymentMethodTypes([PaymentMethod.bankCard]); static const PaymentMethodTypes bankCard =
static const PaymentMethodTypes yooMoney = PaymentMethodTypes([PaymentMethod.yooMoney]); PaymentMethodTypes([PaymentMethod.bankCard]);
static const PaymentMethodTypes sberbank = PaymentMethodTypes([PaymentMethod.sberbank]); static const PaymentMethodTypes yooMoney =
static const PaymentMethodTypes applePay = PaymentMethodTypes([PaymentMethod.applePay]); PaymentMethodTypes([PaymentMethod.yooMoney]);
static const PaymentMethodTypes googlePay = PaymentMethodTypes([PaymentMethod.googlePay]); static const PaymentMethodTypes sberbank =
PaymentMethodTypes([PaymentMethod.sberbank]);
static const PaymentMethodTypes applePay =
PaymentMethodTypes([PaymentMethod.applePay]);
static const PaymentMethodTypes googlePay =
PaymentMethodTypes([PaymentMethod.googlePay]);
static const PaymentMethodTypes all = PaymentMethodTypes([ static const PaymentMethodTypes all = PaymentMethodTypes([
PaymentMethod.bankCard, PaymentMethod.bankCard,
PaymentMethod.yooMoney, PaymentMethod.yooMoney,
@ -20,10 +25,22 @@ class PaymentMethodTypes {
]); ]);
} }
enum PaymentMethod { enum PaymentMethod { bankCard, yooMoney, applePay, googlePay, sberbank }
bankCard,
yooMoney, extension PaymentMethodExtension on PaymentMethod {
applePay, static PaymentMethod fromStringValue(String rawValue) {
googlePay, switch (rawValue) {
sberbank case 'bank_card':
} return PaymentMethod.bankCard;
case 'yoo_money':
return PaymentMethod.yooMoney;
case 'sberbank':
return PaymentMethod.sberbank;
case 'apple_pay':
return PaymentMethod.applePay;
case 'google_pay':
return PaymentMethod.googlePay;
}
return PaymentMethod.bankCard;
}
}

View File

@ -1,35 +1,62 @@
import 'package:yookassa_payments_flutter/models/payment_method_types.dart'; import 'package:yookassa_payments_flutter/models/payment_method_types.dart';
class TokenizationResult { class TokenizationResult {
String token; TokenizationResult._();
PaymentMethod? paymentMethodType;
TokenizationResult(this.token, this.paymentMethodType); factory TokenizationResult.success(
String token, PaymentMethod? paymentMethodType) =
SuccessTokenizationResult;
factory TokenizationResult.canceled() = CanceledTokenizationResult;
factory TokenizationResult.error(String error) = ErrorTokenizationResult;
factory TokenizationResult.fromJson(Map<String, dynamic> json) { factory TokenizationResult.fromJson(Map<String, dynamic> json) {
var token = json['paymentToken']; final status = json['status'];
switch (status) {
PaymentMethod? paymentMethodType; case 'success':
switch(json['paymentMethodType']){ {
case "sberbank": final token = json['paymentToken'];
paymentMethodType = PaymentMethod.sberbank; PaymentMethod? paymentMethodType =
break; _paymentMethodFromString(json['paymentMethodType']);
case "bank_card": return TokenizationResult.success(token, paymentMethodType);
paymentMethodType = PaymentMethod.bankCard; }
break; case 'canceled':
case "yoo_money": return TokenizationResult.canceled();
paymentMethodType = PaymentMethod.yooMoney;
break;
case "apple_pay":
paymentMethodType = PaymentMethod.applePay;
break;
case "google_pay":
paymentMethodType = PaymentMethod.googlePay;
break;
default: default:
break; return TokenizationResult.error(json['error'] ?? 'Unknown error');
} }
return TokenizationResult(token, paymentMethodType);
} }
} }
class SuccessTokenizationResult extends TokenizationResult {
final String token;
final PaymentMethod? paymentMethodType;
SuccessTokenizationResult(this.token, this.paymentMethodType) : super._();
}
class CanceledTokenizationResult extends TokenizationResult {
CanceledTokenizationResult() : super._();
}
class ErrorTokenizationResult extends TokenizationResult {
final String error;
ErrorTokenizationResult(this.error) : super._();
}
PaymentMethod? _paymentMethodFromString(String type) {
switch (type) {
case "sberbank":
return PaymentMethod.sberbank;
case "bank_card":
return PaymentMethod.bankCard;
case "yoo_money":
return PaymentMethod.yooMoney;
case "apple_pay":
return PaymentMethod.applePay;
case "google_pay":
return PaymentMethod.googlePay;
default:
return null;
}
}

View File

@ -6,6 +6,7 @@ export 'models/tokenization_settings.dart';
export 'models/customization_settings.dart'; export 'models/customization_settings.dart';
export 'models/google_pay_parameters.dart'; export 'models/google_pay_parameters.dart';
export 'models/test_mode_settings.dart'; export 'models/test_mode_settings.dart';
export 'models/tokenization_result.dart';
export 'input_data/tokenization_module_input_data.dart'; export 'input_data/tokenization_module_input_data.dart';
import 'input_data/saved_card_module_input_data.dart'; import 'input_data/saved_card_module_input_data.dart';
@ -14,28 +15,31 @@ import 'package:flutter/services.dart';
import 'package:yookassa_payments_flutter/models/tokenization_result.dart'; import 'package:yookassa_payments_flutter/models/tokenization_result.dart';
import 'input_data/tokenization_module_input_data.dart'; import 'input_data/tokenization_module_input_data.dart';
import 'models/payment_method_types.dart'; import 'models/payment_method_types.dart';
import 'models/tokenization_result.dart';
class YookassaPaymentsFlutter { class YookassaPaymentsFlutter {
static const MethodChannel _channel = MethodChannel('ru.yoomoney.yookassa_payments_flutter/yoomoney'); static const MethodChannel _channel =
MethodChannel('ru.yoomoney.yookassa_payments_flutter/yoomoney');
static Future<TokenizationResult> tokenization(TokenizationModuleInputData data) async { static Future<TokenizationResult> tokenization(
TokenizationModuleInputData data) async {
var inputData = data.toJson(); var inputData = data.toJson();
return await _channel return await _channel
.invokeMethod('tokenization', inputData).then((value) => TokenizationResult.fromJson(json.decode(value))); .invokeMethod('tokenization', inputData)
.then((value) => TokenizationResult.fromJson(json.decode(value)));
} }
static Future<void> confirmation(String url, PaymentMethod? paymentMethod) async { static Future<void> confirmation(
await _channel String url, PaymentMethod? paymentMethod) async {
.invokeMethod('confirmation', var inputData = {'url': url, 'paymentMethod': paymentMethod?.name};
{ return await _channel.invokeMethod('confirmation', inputData);
'url': url,
'paymentMethod': paymentMethod?.name
}
);
} }
static Future<TokenizationResult> bankCardRepeat(SavedBankCardModuleInputData data) async { static Future<TokenizationResult> bankCardRepeat(
return await _channel.invokeMethod('repeat', data.toJson()).then((value) => TokenizationResult.fromJson(json.decode(value))); SavedBankCardModuleInputData data) async {
return await _channel
.invokeMethod('repeat', data.toJson())
.then((value) => TokenizationResult.fromJson(json.decode(value)));
} }
} }

View File

@ -42,14 +42,14 @@ packages:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.16.0" version: "1.15.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.2.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -87,7 +87,7 @@ packages:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.3"
meta: meta:
dependency: transitive dependency: transitive
description: description:
@ -101,7 +101,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.8.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -113,7 +113,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.8.1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -148,14 +148,21 @@ packages:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.9" version: "0.4.8"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.2" version: "2.1.1"
sdks: sdks:
dart: ">=2.17.0-0 <3.0.0" dart: ">=2.14.0 <3.0.0"
flutter: ">=2.10.5" flutter: ">=2.10.5"

View File

@ -1,6 +1,6 @@
name: yookassa_payments_flutter name: yookassa_payments_flutter
description: This Flutter SDK allows processing payments using a payment token. It works as an addition to the YooMoney API. description: This Flutter SDK allows processing payments using a payment token. It works as an addition to the YooMoney API.
version: 1.0.2 version: 1.0.3
homepage: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse homepage: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse
repository: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse repository: https://git.yoomoney.ru/projects/SDK/repos/yookassa-payments-flutter-sdk/browse