diff --git a/android/build.gradle b/android/build.gradle index c77dcc3..db7c5d9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -29,7 +29,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 31 + compileSdkVersion 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 297f2fe..ab716dd 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip \ No newline at end of file diff --git a/android/src/main/kotlin/com/unact/iboxpro_flutter/IboxproFlutterHandlerImpl.kt b/android/src/main/kotlin/com/unact/iboxpro_flutter/IboxproFlutterHandlerImpl.kt index 547341d..62f2952 100644 --- a/android/src/main/kotlin/com/unact/iboxpro_flutter/IboxproFlutterHandlerImpl.kt +++ b/android/src/main/kotlin/com/unact/iboxpro_flutter/IboxproFlutterHandlerImpl.kt @@ -176,6 +176,16 @@ class IboxproFlutterHandlerImpl: MethodCallHandler { methodChannel.invokeMethod("onLogin", arguments) } + private fun setCustomReaderParams(call: MethodCall) { + val params = call.arguments as HashMap + val notup = params["NOTUP"] as Boolean + + val readerParams = Hashtable() + readerParams["NOTUP"] = notup + + paymentController.setCustomReaderParams(readerParams) + } + private fun startPayment(call: MethodCall) { val params = call.arguments as HashMap val inputType = PaymentController.PaymentInputType.fromValue(params["inputType"] as Int) @@ -306,6 +316,10 @@ class IboxproFlutterHandlerImpl: MethodCallHandler { login(call) result.success(null) } + "setCustomReaderParams" -> { + setCustomReaderParams(call) + result.success(null) + } "startPayment" -> { startPayment(call) result.success(null) diff --git a/example/android/build.gradle b/example/android/build.gradle index 8a9374e..fe24169 100644 --- a/example/android/build.gradle +++ b/example/android/build.gradle @@ -28,4 +28,4 @@ subprojects { task clean(type: Delete) { delete rootProject.buildDir -} +} \ No newline at end of file diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index b8793d3..8b6dc59 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip \ No newline at end of file diff --git a/example/android/settings.gradle b/example/android/settings.gradle index 5a2f14f..121d30d 100644 --- a/example/android/settings.gradle +++ b/example/android/settings.gradle @@ -12,4 +12,4 @@ plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory -} +} \ No newline at end of file diff --git a/example/lib/pages/main_page.dart b/example/lib/pages/main_page.dart index 2b1aad7..0ee9c12 100644 --- a/example/lib/pages/main_page.dart +++ b/example/lib/pages/main_page.dart @@ -15,6 +15,8 @@ class _MainPage extends State { String _loginEmail = ''; String _password = ''; String _deviceName = ''; + bool _isHidden = true; + bool _nfcActivation = false; late StreamSubscription _onLoginSubscription; late StreamSubscription _onReaderSetDeviceSubscription; @@ -54,14 +56,27 @@ class _MainPage extends State { TextFormField( initialValue: _loginEmail, maxLines: 1, + keyboardType: TextInputType.emailAddress, decoration: InputDecoration(labelText: 'Логин'), - onChanged: (val) => _loginEmail = val - ), + onChanged: (val) => _loginEmail = val), TextFormField( initialValue: _password, - obscureText: true, + obscureText: _isHidden, + keyboardType: _isHidden ? null : TextInputType.visiblePassword, + enableSuggestions: false, + autocorrect: false, maxLines: 1, - decoration: InputDecoration(labelText: 'Пароль'), + decoration: InputDecoration( + labelText: 'Пароль', + suffixIcon: IconButton( + icon: Icon(_isHidden ? Icons.visibility : Icons.visibility_off), + onPressed: () { + setState(() { + _isHidden = !_isHidden; + }); + }, + ), + ), onChanged: (val) => _password = val ), ElevatedButton( @@ -102,11 +117,35 @@ class _MainPage extends State { ]; } - List _buildPaymentPart(BuildContext context) { + List _buildReaderParams(BuildContext context) { return [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: Text('Авто NFC: ${_nfcActivation ? "Включено" : "Отключено"}'), + ), + Switch( + value: _nfcActivation, + onChanged: (bool newValue) async { + await PaymentController.setCustomReaderParams(nfcActivation: newValue); + setState(() { + _nfcActivation = newValue; + }); + _showSnackBar(newValue + ? 'Автоматическое включение NFC активировано' + : 'Автоматическое включение NFC отключено'); + }, + ), + ], + ) + ]; + } + List _buildPaymentPart(BuildContext context) { + return [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( child: Text('Оплатить'), @@ -133,9 +172,8 @@ class _MainPage extends State { padding: EdgeInsets.all(8), children: _buildLoginPart(context) ..addAll(_buildSearchDevicePart(context)) - ..addAll(_buildPaymentPart(context)) - ) - ), + ..addAll(_buildReaderParams(context)) + ..addAll(_buildPaymentPart(context)))), ); } } diff --git a/ios/Classes/SwiftIboxproFlutterPlugin.swift b/ios/Classes/SwiftIboxproFlutterPlugin.swift index ec6534d..0487ab8 100644 --- a/ios/Classes/SwiftIboxproFlutterPlugin.swift +++ b/ios/Classes/SwiftIboxproFlutterPlugin.swift @@ -104,6 +104,16 @@ public class SwiftIboxproFlutterPlugin: NSObject, FlutterPlugin { } } + private func setCustomReaderParams(call: FlutterMethodCall) { + let params = call.arguments as! [String: Any] + let notup = params["NOTUP"] as! Bool + + var readerParams = [String: Any]() + readerParams["NOTUP"] = notup + + paymentController.setCustomReaderParams(readerParams: readerParams) + } + public func startPayment(_ call: FlutterMethodCall) { let params = call.arguments as! [String: Any] let inputType = TransactionInputType( @@ -211,6 +221,9 @@ public class SwiftIboxproFlutterPlugin: NSObject, FlutterPlugin { case "login": login(call) return result(nil) + case "setCustomReaderParams": + setCustomReaderParams(call) + return result(nil) case "startPayment": startPayment(call) return result(nil) diff --git a/lib/src/events.dart b/lib/src/events.dart index 0996023..c585513 100644 --- a/lib/src/events.dart +++ b/lib/src/events.dart @@ -30,13 +30,13 @@ class PaymentCompleteEvent extends PaymentEvent { } class PaymentAdjustEvent extends PaymentEvent { - final Result result; + final Result result; PaymentAdjustEvent(this.result); } class PaymentAdjustReverseEvent extends PaymentEvent { - final Result result; + final Result result; PaymentAdjustReverseEvent(this.result); } @@ -59,6 +59,7 @@ class PaymentReaderSetDeviceEvent extends PaymentEvent { PaymentReaderSetDeviceEvent(this.deviceName); } + class PaymentRejectReverseEvent extends PaymentEvent { PaymentRejectReverseEvent(); } diff --git a/lib/src/payment.dart b/lib/src/payment.dart index 1c76b73..9815a58 100644 --- a/lib/src/payment.dart +++ b/lib/src/payment.dart @@ -51,6 +51,16 @@ class PaymentController { }); } + /// Устанавливает параметры работы ридера. + /// + /// [nfcActivation] (true/false) – автоматическое включение NFC на ридере P17 + /// при проведении транзакции + static Future setCustomReaderParams({bool nfcActivation = false}) async { + await _channel.invokeMethod('setCustomReaderParams', { + 'NOTUP': nfcActivation, + }); + } + /// Начинает операцию принятия оплаты терминалом /// /// [inputType] вид оплаты, все возможные значения в [InputType]