From 9d54a20f655e892f183df0adb92373728bd0575d Mon Sep 17 00:00:00 2001 From: suvaissov Date: Tue, 27 Apr 2021 11:18:17 +0600 Subject: [PATCH] payment + closeDay +- refund - --- .../kotlin/kz/com/aman/kassa/MainActivity.kt | 134 +++++--- ...JsonForTests.kt => JsonForExternalCall.kt} | 144 ++++----- lib/core/models/card_data.dart | 23 +- lib/core/models/halyk_response_dao.dart | 133 ++++++++ lib/core/services/ApiService.dart | 10 +- lib/core/services/BankService.dart | 156 ++-------- lib/test/foo.dart | 7 + lib/views/bank_setting/bank_setting_view.dart | 16 +- lib/views/check/image_show_container.dart | 99 +++++- lib/views/history/history_view.dart | 2 +- lib/views/home/tabs/AdditionalTab.dart | 81 ++--- lib/views/payment/halyk_pos_service.dart | 92 ++++++ lib/views/payment/payment_view.dart | 182 ++++++----- lib/views/payment_nfc/payment_nfc_view.dart | 289 +++++++----------- pubspec.lock | 2 +- pubspec.yaml | 1 + 16 files changed, 769 insertions(+), 602 deletions(-) rename android/app/src/main/kotlin/kz/com/aman/kassa/bank/{JsonForTests.kt => JsonForExternalCall.kt} (54%) create mode 100644 lib/core/models/halyk_response_dao.dart create mode 100644 lib/views/payment/halyk_pos_service.dart diff --git a/android/app/src/main/kotlin/kz/com/aman/kassa/MainActivity.kt b/android/app/src/main/kotlin/kz/com/aman/kassa/MainActivity.kt index 895a7a9..0faae5b 100644 --- a/android/app/src/main/kotlin/kz/com/aman/kassa/MainActivity.kt +++ b/android/app/src/main/kotlin/kz/com/aman/kassa/MainActivity.kt @@ -11,88 +11,124 @@ import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant -import kz.com.aman.kassa.bank.JsonForTests +import kz.com.aman.kassa.bank.JsonForExternalCall import kz.com.aman.kassa.bank.OperationType -class MainActivity: FlutterActivity() { +class MainActivity : FlutterActivity() { private val externalApplicationRequestCode = 207 - private val EXTERNAL_OPERATION_TYPE_KEY = "ru.m4bank.ExternalApplication.OperationTypeKey" - private val EXTERNAL_INPUT_DATA_KEY = "ru.m4bank.ExternalApplication.InputDataKey" - private val EXTERNAL_RESULT_DATA_KEY = "ru.m4bank.ExternalApplication.ResultDataKey" + private val externalOperationTypeKey = "ru.m4bank.ExternalApplication.OperationTypeKey" + private val externalInputDataKey = "ru.m4bank.ExternalApplication.InputDataKey" + private val externalResultDataKey = "ru.m4bank.ExternalApplication.ResultDataKey" - private val BANK_CHANNEL = "channel:com.amanKassa/bank" - private val ACTIVITY_CHANNEL = "channel:com.amanKassa/activity" + private val bankChannel = "channel:com.amanKassa/bank" private lateinit var _result: MethodChannel.Result override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { - GeneratedPluginRegistrant.registerWith(flutterEngine); - //MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this)); + GeneratedPluginRegistrant.registerWith(flutterEngine) + //MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this)) - MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(MethodChannel.MethodCallHandler { call, result -> - _result = result; - if(call.method == "init") { - operationPayment(call); - } else if(call.method == "version") { - result.success(Build.VERSION.SDK_INT.toString()) - } else { - result.notImplemented() + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, bankChannel).setMethodCallHandler { call, result -> + _result = result + when (call.method) { + "pay" -> { + operationPayment(call) + } + "refund" -> { + operationRefund(call) + } + "reversal" -> { + operationReversal(call) + } + "closeDay" -> { + operationCloseDay(call) + } + "version" -> { + result.success(Build.VERSION.SDK_INT.toString()) + } + else -> { + result.notImplemented() + } } - - }) + } } - private fun getOperationList(call: MethodCall) { - val token: String = call.argument("token").toString() - val operationParameters = createOperationParameters(token); - println(operationParameters.toString()); - println(JsonForTests.getOperationsListJson(token)); - startOperation(OperationType.OPERATIONS_LIST, - JsonForTests.getOperationsListJson(operationParameters.authToken)) - - } +// private fun getOperationList(call: MethodCall) { +// val token: String = call.argument("token").toString() +// val operationParameters = createOperationParameters(token) +// startOperation(OperationType.OPERATIONS_LIST, +// JsonForExternalCall.getOperationsListJson(operationParameters.authToken)) +// +// } private fun operationPayment(call: MethodCall) { val token = call.argument("token").toString() - val operationParameters = createOperationParameters(token); - println(operationParameters.toString()); - println(JsonForTests.getPaymentCardJson(operationParameters.authToken)); - startOperation(OperationType.PAYMENT, JsonForTests.getPaymentCardJson(operationParameters.authToken)) + var amount: Long = 0 + if (call.argument("amount") != null) { + amount = call.argument("amount")!!.toLong() + } + val operationParameters = createOperationParameters(token) + startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString())) + } + private fun operationRefund(call: MethodCall) { + val token = call.argument("token").toString() + val terminalId = call.argument("terminalId").toString() + val operDay = call.argument("operDay").toString() + val transNum = call.argument("transNum").toString() + val amount = call.argument("amount").toString() + val operationParameters = createOperationParameters(token) + startOperation(OperationType.REFUND, JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount)) + } + + private fun operationReversal(call: MethodCall) { + val token = call.argument("token").toString() + val terminalId = call.argument("terminalId").toString() + val operDay = call.argument("operDay").toString() + val transNum = call.argument("transNum").toString() + val operationParameters = createOperationParameters(token) + startOperation(OperationType.REVERSAL, JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum)) + } + + private fun operationCloseDay(call: MethodCall) { + val token = call.argument("token").toString() + val operationParameters = createOperationParameters(token) + startOperation(OperationType.CLOSE_DAY, JsonForExternalCall.getCloseDayJson(operationParameters.authToken)) } - - private fun createOperationParameters(token: String): OperationParameters { - return OperationParameters(authToken = token, operDay = "", terminalId = "", transNum = ""); + private fun createOperationParameters(token: String, operDay: String = "", terminalId: String = "", transNum: String = ""): OperationParameters { + return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum) } private fun startOperation(operationType: OperationType, inputJsonData: String?) { val intent = Intent() intent.component = ComponentName("ru.m4bank.softpos.halyk", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity") intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP - //intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP - intent.putExtra(EXTERNAL_OPERATION_TYPE_KEY, operationType.code) - intent.putExtra(EXTERNAL_INPUT_DATA_KEY, inputJsonData) + // intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP + intent.putExtra(externalOperationTypeKey, operationType.code) + intent.putExtra(externalInputDataKey, inputJsonData) startActivityForResult(intent, externalApplicationRequestCode) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - if(requestCode == externalApplicationRequestCode) { - println("---------------"); - println(requestCode); - println(resultCode); - println(data); + if (requestCode == externalApplicationRequestCode) { + println("---------------") + println(requestCode) + println(resultCode) + println(data) if (data != null) { - println(data.getStringExtra(EXTERNAL_RESULT_DATA_KEY)) - }; - println("---------------"); + println(data.getStringExtra(externalResultDataKey)) + } + println("---------------") if (requestCode == externalApplicationRequestCode && resultCode == Activity.RESULT_OK && data != null) { - println(data.getStringExtra(EXTERNAL_RESULT_DATA_KEY)); - Toast.makeText(this, data.getStringExtra(EXTERNAL_RESULT_DATA_KEY), Toast.LENGTH_LONG).show() + println(data.getStringExtra(externalResultDataKey)) + Toast.makeText(this, data.getStringExtra(externalResultDataKey), Toast.LENGTH_LONG).show() + _result.success(data.getStringExtra(externalResultDataKey)) } else { + _result.error("008", "Error while apps connecting", "aaa") Toast.makeText(this, "Error while apps connecting", Toast.LENGTH_SHORT).show() } // if (resultCode == Activity.RESULT_OK) { @@ -106,8 +142,6 @@ class MainActivity: FlutterActivity() { } - - } data class OperationParameters(val authToken: String, val terminalId: String, val operDay: String, val transNum: String) \ No newline at end of file diff --git a/android/app/src/main/kotlin/kz/com/aman/kassa/bank/JsonForTests.kt b/android/app/src/main/kotlin/kz/com/aman/kassa/bank/JsonForExternalCall.kt similarity index 54% rename from android/app/src/main/kotlin/kz/com/aman/kassa/bank/JsonForTests.kt rename to android/app/src/main/kotlin/kz/com/aman/kassa/bank/JsonForExternalCall.kt index fc4b4b0..6360943 100644 --- a/android/app/src/main/kotlin/kz/com/aman/kassa/bank/JsonForTests.kt +++ b/android/app/src/main/kotlin/kz/com/aman/kassa/bank/JsonForExternalCall.kt @@ -1,8 +1,8 @@ package kz.com.aman.kassa.bank; -object JsonForTests { +object JsonForExternalCall { - fun getPaymentCardJson(authToken: String): String { + fun getPaymentCardJson(authToken: String, amount: String): String { return """{ "credentials" : { "authorizationToken": "$authToken" @@ -11,14 +11,14 @@ object JsonForTests { "instrument": "CARD", "amountData" : { "currencyCode": "398", - "amount": "6000", + "amount": "$amount", "amountExponent": "2" }, "goods" : { "product": [{ - "name": "Печеньки", - "price": "3000", - "quantity": "2", + "name": "Товар", + "price": "$amount", + "quantity": "1", "quantityExponent": "0", "taxRate": "TAX_20", "accountingSubject": "PRODUCT" @@ -28,33 +28,7 @@ object JsonForTests { }""" } - fun getPaymentCashJson(authToken: String): String { - return """{ - "credentials" : { - "authorizationToken": "$authToken" - }, - "operationData" : { - "instrument": "CASH", - "amountData" : { - "currencyCode": "643", - "amount": "6000", - "amountExponent": "2" - }, - "goods" : { - "product": [{ - "name": "Печеньки", - "price": "3000", - "quantity": "2", - "quantityExponent": "0", - "taxRate": "TAX_20", - "accountingSubject": "PRODUCT" - }] - } - } - }""" - } - - fun getRefundCardJson(authToken: String, terminalId: String, operDay: String, transNum: String): String { + fun getRefundCardJson(authToken: String, terminalId: String, operDay: String, transNum: String, amount: String): String { return """{ "credentials" :{ "authorizationToken": "$authToken" @@ -62,7 +36,7 @@ object JsonForTests { "operationData" :{ "instrument": "CARD", "amountData" : { - "currencyCode": "643", + "currencyCode": "348", "amount": "6000", "amountExponent": "2" }, @@ -75,42 +49,6 @@ object JsonForTests { }""" } - fun getRefundCashJson(authToken: String, terminalId: String, operDay: String, transNum: String): String { - return """{ - "credentials" :{ - "authorizationToken": "$authToken" - }, - "operationData" :{ - "instrument": "CASH", - "amountData" : { - "currencyCode": "643", - "amount": "6000", - "amountExponent": "2" - }, - "parentTransaction" : { - "terminalId": "$terminalId", - "operationDay": "$operDay", - "transactionNumber": "$transNum" - } - } - }""" - } - - fun getReversalJson(authToken: String, terminalId: String, operDay: String, transNum: String): String { - return """{ - "credentials" : { - "authorizationToken": "$authToken" - }, - "operationData" : { - "parentTransaction" : { - "terminalId": "$terminalId", - "operationDay": "$operDay", - "transactionNumber": "$transNum" - } - } - }""" - } - fun getCloseDayJson(authToken: String): String { return """{ "credentials" : { @@ -135,4 +73,70 @@ object JsonForTests { } }""" } + + fun getReversalJson(authToken: String, terminalId: String, operDay: String, transNum: String): String { + return """{ + "credentials" : { + "authorizationToken": "$authToken" + }, + "operationData" : { + "parentTransaction" : { + "terminalId": "$terminalId", + "operationDay": "$operDay", + "transactionNumber": "$transNum" + } + } + }""" + } + +// fun getPaymentCashJson(authToken: String): String { +// return """{ +// "credentials" : { +// "authorizationToken": "$authToken" +// }, +// "operationData" : { +// "instrument": "CASH", +// "amountData" : { +// "currencyCode": "643", +// "amount": "6000", +// "amountExponent": "2" +// }, +// "goods" : { +// "product": [{ +// "name": "Печеньки", +// "price": "3000", +// "quantity": "2", +// "quantityExponent": "0", +// "taxRate": "TAX_20", +// "accountingSubject": "PRODUCT" +// }] +// } +// } +// }""" +// } + +// +// fun getRefundCashJson(authToken: String, terminalId: String, operDay: String, transNum: String): String { +// return """{ +// "credentials" :{ +// "authorizationToken": "$authToken" +// }, +// "operationData" :{ +// "instrument": "CASH", +// "amountData" : { +// "currencyCode": "643", +// "amount": "6000", +// "amountExponent": "2" +// }, +// "parentTransaction" : { +// "terminalId": "$terminalId", +// "operationDay": "$operDay", +// "transactionNumber": "$transNum" +// } +// } +// }""" +// } + + + } \ No newline at end of file diff --git a/lib/core/models/card_data.dart b/lib/core/models/card_data.dart index 8fe0014..212df60 100644 --- a/lib/core/models/card_data.dart +++ b/lib/core/models/card_data.dart @@ -1,32 +1,35 @@ class CardData { final int transactionNumber; - final String cardExpiryDate; + final int operationDay; + final int terminalId; final String cardNumber; - final String transactionType; - final String cardPaymentSystemType; + final String cardholderName; final String authorizationCode; + final String transactionType; - CardData({this.transactionNumber, this.cardExpiryDate, this.cardNumber, this.transactionType, this.cardPaymentSystemType, this.authorizationCode}); + CardData({this.transactionNumber, this.operationDay, this.cardNumber, this.cardholderName, this.authorizationCode, this.terminalId, this.transactionType }); static CardData fromJson(Map json) { return json != null ? CardData( transactionNumber: json['transactionNumber'], - cardExpiryDate: json['cardExpiryDate'], + operationDay: json['operationDay'], + terminalId: json['terminalId'], cardNumber: json['cardNumber'], - transactionType: json['transactionType'], - cardPaymentSystemType: json['cardPaymentSystemType'], + cardholderName: json['cardholderName'], authorizationCode: json['authorizationCode'], + transactionType: json['transactionType'], ) : null; } Map toJson() => { 'transactionNumber': transactionNumber, - 'cardExpiryDate': cardExpiryDate, + 'operationDay': operationDay, 'cardNumber': cardNumber, - 'transactionType': transactionType, - 'cardPaymentSystemType': cardPaymentSystemType, + 'cardholderName': cardholderName, 'authorizationCode': authorizationCode, + 'terminalId' : terminalId, + 'transactionType' : transactionType, }; } \ No newline at end of file diff --git a/lib/core/models/halyk_response_dao.dart b/lib/core/models/halyk_response_dao.dart new file mode 100644 index 0000000..c99c421 --- /dev/null +++ b/lib/core/models/halyk_response_dao.dart @@ -0,0 +1,133 @@ +/// result : {"code":"0","description":"Successfully completed","hostResponse":{"code":"0","description":"Successfully completed"}} +/// transaction : {"terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}} + +class HalykResponse { + ResultBean result; + TransactionBean transaction; + + HalykResponse({this.result, this.transaction}); + + static HalykResponse fromMap(Map map) { + if (map == null) return null; + HalykResponse halykResponseBean = HalykResponse(); + halykResponseBean.result = ResultBean.fromMap(map['result']); + halykResponseBean.transaction = TransactionBean.fromMap(map['transaction']); + return halykResponseBean; + } + + Map toJson() => + { + "result": result, + "transaction": transaction, + }; +} + +/// terminalId : "123321" +/// operationDay : "4" +/// transactionNumber : "69" +/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"} + +class TransactionBean { + int terminalId; + int operationDay; + int transactionNumber; + InstrumentSpecificDataBean instrumentSpecificData; + + static TransactionBean fromMap(Map map) { + if (map == null) return null; + TransactionBean transactionBean = TransactionBean(); + transactionBean.terminalId = map['terminalId']; + transactionBean.operationDay = map['operationDay']; + transactionBean.transactionNumber = map['transactionNumber']; + transactionBean.instrumentSpecificData = InstrumentSpecificDataBean.fromMap(map['instrumentSpecificData']); + return transactionBean; + } + + Map toJson() => + { + "terminalId": terminalId, + "operationDay": operationDay, + "transactionNumber": transactionNumber, + "instrumentSpecificData": instrumentSpecificData, + }; +} + +/// authorizationCode : "000000" +/// rrn : "1234567890" +/// cardholderName : "IVAN IVANOV" +/// maskedPan : "123456******7890" + +class InstrumentSpecificDataBean { + String authorizationCode; + String rrn; + String cardholderName; + String maskedPan; + + static InstrumentSpecificDataBean fromMap(Map map) { + if (map == null) return null; + InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean(); + instrumentSpecificDataBean.authorizationCode = map['authorizationCode']; + instrumentSpecificDataBean.rrn = map['rrn']; + instrumentSpecificDataBean.cardholderName = map['cardholderName']; + instrumentSpecificDataBean.maskedPan = map['maskedPan']; + return instrumentSpecificDataBean; + } + + Map toJson() => + { + "authorizationCode": authorizationCode, + "rrn": rrn, + "cardholderName": cardholderName, + "maskedPan": maskedPan, + }; +} + +/// code : "0" +/// description : "Successfully completed" +/// hostResponse : {"code":"0","description":"Successfully completed"} + +class ResultBean { + int code; + String description; + HostResponseBean hostResponse; + + ResultBean({this.code, this.description}); + + static ResultBean fromMap(Map map) { + if (map == null) return null; + ResultBean resultBean = ResultBean(); + resultBean.code = map['code']; + resultBean.description = map['description']; + resultBean.hostResponse = HostResponseBean.fromMap(map['hostResponse']); + return resultBean; + } + + Map toJson() => + { + "code": code, + "description": description, + "hostResponse": hostResponse, + }; +} + +/// code : "0" +/// description : "Successfully completed" + +class HostResponseBean { + String code; + String description; + + static HostResponseBean fromMap(Map map) { + if (map == null) return null; + HostResponseBean hostResponseBean = HostResponseBean(); + hostResponseBean.code = map['code']; + hostResponseBean.description = map['description']; + return hostResponseBean; + } + + Map toJson() => + { + "code": code, + "description": description, + }; +} \ No newline at end of file diff --git a/lib/core/services/ApiService.dart b/lib/core/services/ApiService.dart index e88c0ab..1401908 100644 --- a/lib/core/services/ApiService.dart +++ b/lib/core/services/ApiService.dart @@ -6,6 +6,7 @@ import 'package:aman_kassa_flutter/core/models/halyk_post_session.dart'; import 'package:aman_kassa_flutter/redux/state/user_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/views/login/login_view.dart'; +import 'package:crypto/crypto.dart'; import 'package:device_info/device_info.dart'; import 'package:aman_kassa_flutter/core/models/message.dart'; import 'package:aman_kassa_flutter/core/models/response.dart'; @@ -67,6 +68,9 @@ class ApiService extends BaseService { } Future halykPosToken(String token, login, password) async { + String salt = '!=uF:w1N_Salh?1gVSJ#eGfJYHA(wS4D'; + String hash = md5.convert(utf8.encode('$login$salt')).toString(); + print(hash); Map requestBody = {'login': login, 'password': password}; var response = await requestFormData('/getpostoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false); return HalykPosSession.fromJson(jsonDecode(response)); @@ -163,9 +167,9 @@ class ApiService extends BaseService { String url = '$endpoint$point'; if(this._test) { url = '$test_endpoint$point'; - if(posEndPoint){ - url = '$pos_endpoint$point'; - } + } + if(posEndPoint){ + url = '$pos_endpoint$point'; } var uri = Uri.parse(url); diff --git a/lib/core/services/BankService.dart b/lib/core/services/BankService.dart index bd66af4..0ece79d 100644 --- a/lib/core/services/BankService.dart +++ b/lib/core/services/BankService.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:aman_kassa_flutter/core/base/base_service.dart'; import 'package:aman_kassa_flutter/core/locator.dart'; -import 'package:aman_kassa_flutter/core/models/aman_dao.dart'; +import 'file:///D:/Work/serik/Flutter/aman-kassa-flutter/lib/core/models/halyk_response_dao.dart'; import 'package:aman_kassa_flutter/core/models/close_day_data.dart'; import 'package:aman_kassa_flutter/core/models/halyk_post_session.dart'; import 'package:aman_kassa_flutter/core/models/transaction_item.dart'; @@ -9,6 +9,8 @@ import 'package:aman_kassa_flutter/core/services/ApiService.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; +import '../models/aman_dao.dart'; + class BankService extends BaseService { final ApiService _api = locator(); @@ -40,168 +42,44 @@ class BankService extends BaseService { - Future init({String token}) async { - - //Intent intent = new Intent (); - // intent.setComponent (new ComponentName ("ru.m4bank.softpos", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")); - // intent.setFlags (Intent.FLAG_ACTIVITY_SINGLE_TOP); - // intent.putExtra (OPERATION_TYPE_KEY, operationType); - // operationType - see the section "List of supported operations" intent.putExtra (INPUT_DATA_KEY, inputJsonData); - // inputJsonData - json string containing input data for the operation startActivityForResult (intent, INTENT_REQUEST_CODE); - // INTENT_REQUEST_CODE - the value specified by the user API is used to filter the received result in onActivityResult - // List result; - // try { - // Intent intent = Intent() - // ..setAction(Action.ACTION_ALL_APPS) - // ..putExtra("ru.m4bank.softpos", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity") - // ..putExtra("ru.m4bank.ExternalApplication.OperationTypeKey", "OPERATIONS_LIST"); - // - // - // result = await intent.startActivityForResult(); - // } catch (e, stack) { - // log.e("BankService", e, stack); - // } - // log.i(result); - // - // return true; + Future closeDay({ String token}) async { try { - String response = await _channel.invokeMethod('init', { - 'serverUrl': _url, - 'token': token - }); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao.success; - } catch (e, stack) { - log.e("BankService", e, stack); - return false; - } - } - - Future connect() async { - try { - String response = await _channel.invokeMethod("connection"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao.success; - } catch (e, stack) { - log.e("BankService", e, stack); - return false; - } - } - - Future currency() async { - try { - String response = await _channel.invokeMethod("currency"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao.success; - } catch (e, stack) { - log.e("BankService", e, stack); - return false; - } - } - - Future permissions() async { - try { - String response = await _channel.invokeMethod("permissions"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao.success; - } catch (e, stack) { - log.e("BankService", e, stack); - return false; - } - } - - Future auth({String login, String password}) async { - try { - String response = await _channel.invokeMethod("auth", - {'login': login, 'password': password}); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); + String response = await _channel.invokeMethod("closeDay", {'token': token }); + HalykResponse dao = HalykResponse.fromMap(json.decode(response)); return dao; } catch (e, stack) { log.e("BankService", e, stack); - return new AmanDao(msg: 'Ошибка авторизации'); + return new HalykResponse(result: ResultBean(description: 'Ошибка при закрытии дня', code: -1)); } } - Future closeDay() async { - try { - String response = await _channel.invokeMethod("closeDay"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao; - } catch (e, stack) { - log.e("BankService", e, stack); - return new AmanDao(msg: 'Ошибка при закрытии дня'); - } - } - - Future pay({double amount}) async { + Future pay({double amount, String token}) async { try { double total = amount * 100; log.i('total: $total, ${total.toInt()}'); - String response = await _channel.invokeMethod("pay", {'amount': total.toInt()}); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); + String response = await _channel.invokeMethod("pay", {'amount': total.toInt(), 'token': token }); + HalykResponse dao = HalykResponse.fromMap(json.decode(response)); return dao; } catch (e, stack) { log.e("BankService", e, stack); - return new AmanDao(msg: 'Ошибка оплаты'); + return new HalykResponse(result: ResultBean(description: 'Ошибка оплаты', code: -1)); } } - Future findTransaction({int transactionNumber, String authorizationCode}) async { + Future refund({double amount, String token, int terminalId, int operDay, int transNum }) async { try { - log.i('transactionNumber: $transactionNumber'); - String response = await _channel.invokeMethod("findTransaction", {'transactionNumber': transactionNumber, 'authorizationCode': authorizationCode}); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); + String response = await _channel.invokeMethod("refund", { + 'amount': amount.toInt(), 'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum + }); + HalykResponse dao = HalykResponse.fromMap(json.decode(response)); return dao; } catch (e, stack) { log.e("BankService", e, stack); - return new AmanDao(msg: 'Ошибка при поиске транзакии банка'); + return new HalykResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1)); } } - Future refund() async { - try { - String response = await _channel.invokeMethod("refund"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao; - } catch (e, stack) { - log.e("BankService", e, stack); - return new AmanDao(msg: 'Ошибка при возврате'); - } - } - - Future shutdown() async { - try { - String response = await _channel.invokeMethod("shutdown"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao.success; - } catch (e, stack) { - log.e("BankService", e, stack); - return false; - } - } - - Future cancel() async { - try { - String response = await _channel.invokeMethod("cancel"); - AmanDao dao = AmanDao.fromJson(json.decode(response)); - log.i('${dao.success} - ${dao.msg}'); - return dao.success; - } catch (e, stack) { - log.e("BankService", e, stack); - return false; - } - } CloseDayData closeDayDataConvert(dynamic rows) { final DateFormat formatter = DateFormat('dd.MM.yyyy'); diff --git a/lib/test/foo.dart b/lib/test/foo.dart index 47ce671..0a1b901 100644 --- a/lib/test/foo.dart +++ b/lib/test/foo.dart @@ -1,4 +1,8 @@ // Define a function. +import 'dart:convert'; + +import 'package:crypto/crypto.dart'; + void printInteger(int aNumber) { print('The number is $aNumber.'); // Print to console. } @@ -8,4 +12,7 @@ void main() { String dataMatrix = "00000046208262nZ2qnLHODVFWktT"; String numberText = dataMatrix.replaceAll(RegExp("[a-zA-Z]"), ''); print(int.parse(numberText)); + String salt = '!=uF:w1N_Salh?1gVSJ#eGfJYHA(wS4D'; + String hash = md5.convert(utf8.encode('uvaissov@gmail.com$salt')).toString(); + print(hash); } \ No newline at end of file diff --git a/lib/views/bank_setting/bank_setting_view.dart b/lib/views/bank_setting/bank_setting_view.dart index f318196..201225a 100644 --- a/lib/views/bank_setting/bank_setting_view.dart +++ b/lib/views/bank_setting/bank_setting_view.dart @@ -31,16 +31,16 @@ class _BankSettingViewState extends State { BankState state = Redux.store.state.bankState; _emailController = new TextEditingController(text: state.login); _passwordController = new TextEditingController(text: state.password); - permissions(); + //permissions(); } - Future permissions() async { - try { - await _bankService.permissions(); - } on PlatformException { - - } - } + // Future permissions() async { + // try { + // await _bankService.permissions(); + // } on PlatformException { + // + // } + // } @override diff --git a/lib/views/check/image_show_container.dart b/lib/views/check/image_show_container.dart index 2c8303c..910bc67 100644 --- a/lib/views/check/image_show_container.dart +++ b/lib/views/check/image_show_container.dart @@ -2,22 +2,27 @@ import 'dart:convert'; import 'dart:io'; import 'package:aman_kassa_flutter/core/entity/Voucher.dart'; import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/models/check_data.dart'; import 'package:aman_kassa_flutter/core/models/check_image_modal.dart'; import 'package:aman_kassa_flutter/core/models/aman_dao.dart'; import 'package:aman_kassa_flutter/core/models/card_data.dart'; import 'package:aman_kassa_flutter/core/models/dialog_models.dart'; +import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/route_names.dart'; import 'package:aman_kassa_flutter/core/services/BankService.dart'; +import 'package:aman_kassa_flutter/core/services/DataService.dart'; import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/actions/user_actions.dart'; import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/ui_helpers.dart'; import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart'; -import 'package:aman_kassa_flutter/views/payment/payment_view.dart'; +import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart'; +import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart'; import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:flutter/cupertino.dart'; @@ -27,6 +32,8 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart import 'package:esys_flutter_share/esys_flutter_share.dart'; import 'package:url_launcher/url_launcher.dart'; +import '../../core/models/aman_dao.dart'; + class ImageShowContainer extends StatefulWidget { final ImageShowModel showModel; @@ -37,8 +44,10 @@ class ImageShowContainer extends StatefulWidget { } class _ImageShowContainerState extends State { + final PrinterBluetoothManager printerManager = PrinterBluetoothManager(); final DialogService _dialogService = locator(); + final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT; bool _printing = false; @@ -154,6 +163,8 @@ class _MyFloatingActionButtonState extends State { bool showFab = true; DialogService _dialog = locator(); NavigatorService _navigatorService = locator(); + final GlobalKey _keyLoader = new GlobalKey(); + final DataService _dataService = locator(); double sheetHeight = 260; @@ -164,8 +175,35 @@ class _MyFloatingActionButtonState extends State { Widget build(BuildContext context) { - return showFab - ? FloatingActionButton( + if (showFab) { + return Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment") FloatingActionButton( + backgroundColor: redColor, + child: Icon( + Icons.settings_backup_restore, + color: whiteColor, + ), + onPressed: () async { + _navigatorService.replace(HomeViewRoute); + AmanDao response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total); + if(response.success) { + pressRefund(); + } else { + _dialog.showDialog(description: response.msg ); + } + + + }, + heroTag: null, + ) else SizedBox( + height: 0, + ), + SizedBox( + height: 10, + ), + FloatingActionButton( child: Icon(Icons.share), onPressed: () { var bottomSheetController = showBottomSheet( @@ -181,7 +219,7 @@ class _MyFloatingActionButtonState extends State { color: Colors.grey[300], spreadRadius: 5) ]), - height: sheetHeight, + height: 260, child: Column( children: [ verticalSpaceSmall, @@ -204,17 +242,63 @@ class _MyFloatingActionButtonState extends State { BusyButtonIcon( title: 'Поделиться', onPressed: shareFile, - mainColor: redColor, + mainColor: yellowColor, icon: Icons.share, ), ], ))); + showFloatingActionButton(false); bottomSheetController.closed.then((value) { showFloatingActionButton(true); }); }, - ) - : Container(); + ), + ], + ); + } else { + return Container(); + } + } + + pressRefund() async { + Dialogs.showLoadingDialog(context, _keyLoader); + try { + AppState _state = Redux.store.state; + String _token = _state.userState.user.token; + CardData _cardData = widget.data.cardData; + CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher.data)); + Response response = await _dataService.refundM4Bank( + token: _token, + cardData: _cardData, + checkData: _checkData + ); + if (response != null) { + if (response.operation) { + String message = response.body['message']; + String check = response.body['check']; + var checkText = response.body['check_text']; + String url = response?.body['link']; + print('url : $url'); + Redux.store.dispatch(checkMoney); + Redux.store.dispatch(openSmenaPseudo); + Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); + _navigatorService.replace(HomeViewRoute); + _navigatorService.push(ImageShowRoute, + arguments: ImageShowModel(data: new CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: message, url: url)); + } else if (!response.operation && + ![401, 402, 403, 412, 500].contains(response.status)) { + Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); + _dialog.showDialog(description: response.body['message']); + } else { + Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); + } + } else { + Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); + } + } catch (e) { + print(e); + Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); + } } void shareFile() async { @@ -269,4 +353,5 @@ class _MyFloatingActionButtonState extends State { showFab = value; }); } + } diff --git a/lib/views/history/history_view.dart b/lib/views/history/history_view.dart index 7f0467c..5e5ceee 100644 --- a/lib/views/history/history_view.dart +++ b/lib/views/history/history_view.dart @@ -106,7 +106,7 @@ class _HistoryViewState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(dateFormat.format(voucher.dateTime)), - cardData != null ? Text('№ ${cardData.cardNumber} exp: ${cardData.cardExpiryDate}') : Text(''), + cardData != null ? Text('№ ${cardData.cardNumber} holder: ${cardData.cardholderName}') : Text(''), ], ), trailing: Icon(Icons.arrow_right), diff --git a/lib/views/home/tabs/AdditionalTab.dart b/lib/views/home/tabs/AdditionalTab.dart index 45487b9..005ac63 100644 --- a/lib/views/home/tabs/AdditionalTab.dart +++ b/lib/views/home/tabs/AdditionalTab.dart @@ -2,8 +2,9 @@ import 'dart:convert'; import 'package:aman_kassa_flutter/core/entity/Voucher.dart'; import 'package:aman_kassa_flutter/core/locator.dart'; -import 'package:aman_kassa_flutter/core/models/aman_dao.dart'; + import 'package:aman_kassa_flutter/core/models/close_day_data.dart'; +import 'package:aman_kassa_flutter/core/models/halyk_response_dao.dart'; import 'package:aman_kassa_flutter/core/models/money.dart'; import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/models/dialog_models.dart'; @@ -17,7 +18,6 @@ import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; import 'package:aman_kassa_flutter/redux/actions/user_actions.dart'; import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart'; import 'package:aman_kassa_flutter/redux/constants/setting_const.dart'; -import 'package:aman_kassa_flutter/redux/state/bank_state.dart'; import 'package:aman_kassa_flutter/redux/state/setting_state.dart'; import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart'; @@ -27,6 +27,7 @@ import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button.dart'; import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart'; import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart'; import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart'; +import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; @@ -233,30 +234,12 @@ class _AdditionalTabState extends State { return; } - //Инициализация - bool initialized = await _bankService.init(); - if (!initialized) { - setState(() { - isClosePosBusy = false; - }); - return; - } - //Проверка связи - bool connected = await _bankService.connect(); - if (!connected) { - setState(() { - isClosePosBusy = false; - }); - return; - } - //Авторизация - BankState bankState = Redux.store.state.bankState; - AmanDao authDao = await _bankService.auth( - login: bankState.login, password: bankState.password); - if (!authDao.success) { - if (authDao.msg != null) { - _dialog.showDialog(description: authDao.msg); + HalykResponse closeDayDao = (await closeDayHalykPos()) as HalykResponse; + + if (closeDayDao.result.code != 0) { + if (closeDayDao.result.description != null) { + _dialog.showDialog(description: closeDayDao.result.description); } setState(() { isClosePosBusy = false; @@ -264,36 +247,24 @@ class _AdditionalTabState extends State { return; } - AmanDao closeDayDao = await _bankService.closeDay(); - - if (!closeDayDao.success) { - if (closeDayDao.msg != null) { - _dialog.showDialog(description: closeDayDao.msg); - } - setState(() { - isClosePosBusy = false; - }); - return; - } - - - CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.rows); - - User user = Redux.store.state.userState.user; - _dataService.insertVoucher( - user: user, - name: closeDayData.title, - data: jsonEncode(closeDayData.toJson()), - total: closeDayData.totalAmount.toDouble(), - type: VoucherTypeCloseDayPosReport); - - // _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!'); - setState(() { - isClosePosBusy = false; - }); - - _navigator.push(CloseDayShowRoute, - arguments: closeDayData); + // + // CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.rows); + // + // User user = Redux.store.state.userState.user; + // _dataService.insertVoucher( + // user: user, + // name: closeDayData.title, + // data: jsonEncode(closeDayData.toJson()), + // total: closeDayData.totalAmount.toDouble(), + // type: VoucherTypeCloseDayPosReport); + // + // // _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!'); + // setState(() { + // isClosePosBusy = false; + // }); + // + // _navigator.push(CloseDayShowRoute, + // arguments: closeDayData); } @override diff --git a/lib/views/payment/halyk_pos_service.dart b/lib/views/payment/halyk_pos_service.dart new file mode 100644 index 0000000..4e36c0b --- /dev/null +++ b/lib/views/payment/halyk_pos_service.dart @@ -0,0 +1,92 @@ +import 'package:aman_kassa_flutter/core/locator.dart'; +import 'package:aman_kassa_flutter/core/logger.dart'; +import 'file:///D:/Work/serik/Flutter/aman-kassa-flutter/lib/core/models/halyk_response_dao.dart'; +import 'package:aman_kassa_flutter/core/services/DataService.dart'; +import 'package:aman_kassa_flutter/core/services/dialog_service.dart'; +import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; +import 'package:aman_kassa_flutter/redux/store.dart'; +import 'package:logger/logger.dart'; +import '../../core/models/aman_dao.dart'; +import '../../core/models/card_data.dart'; +import '../../core/models/halyk_post_session.dart'; +import '../../core/services/BankService.dart'; +import '../../redux/state/bank_state.dart'; + +BankService _bankService = locator(); +DialogService _dialogService = locator(); +final DataService _dataService = locator(); +final NavigatorService _navigatorService = locator(); +Logger log = getLogger('PaymentNfcView'); + +Future> paymentHalykPos(double total) async { + //Авторизация + String token = Redux.store.state.userState.user.token; + BankState bankState = Redux.store.state.bankState; + //права доступа + HalykPosSession session = + await _bankService.renewToken(token: token, login: bankState.login, password: bankState.password); + if (session.token == null) { + return AmanDao(success: false, msg: 'Отказано в доступе к API банка'); + } + + //Инициализация + HalykResponse response = await _bankService.pay(token: session.token, amount: total); + if (response.result.code == 0) { + CardData cardData = new CardData( + authorizationCode: response.transaction.instrumentSpecificData.authorizationCode, + cardholderName: response.transaction.instrumentSpecificData.cardholderName, + cardNumber: response.transaction.instrumentSpecificData.maskedPan, + operationDay: response.transaction.operationDay, + transactionNumber: response.transaction.transactionNumber, + terminalId: response.transaction.terminalId, + transactionType: 'payment' + ); + return AmanDao(msg: response.result.description, success: true, data: cardData); + } + return AmanDao(msg: response.result.description, success: false); +} + +Future> refundHalykPos(CardData refundData, double total) async { + //Авторизация + String token = Redux.store.state.userState.user.token; + BankState bankState = Redux.store.state.bankState; + //права доступа + HalykPosSession session = + await _bankService.renewToken(token: token, login: bankState.login, password: bankState.password); + if (session.token == null) { + return AmanDao(success: false, msg: 'Отказано в доступе к API банка'); + } + HalykResponse response = await _bankService.refund(token: session.token, amount: total, operDay: refundData.operationDay, terminalId: refundData.terminalId, transNum: refundData.transactionNumber ); + if (response.result.code == 0) { + CardData cardData = new CardData( + authorizationCode: response.transaction.instrumentSpecificData.authorizationCode, + cardholderName: response.transaction.instrumentSpecificData.cardholderName, + cardNumber: response.transaction.instrumentSpecificData.maskedPan, + operationDay: response.transaction.operationDay, + transactionNumber: response.transaction.transactionNumber, + terminalId: response.transaction.terminalId, + transactionType: 'payment' + ); + return AmanDao(msg: response.result.description, success: true, data: cardData); + } + return AmanDao(msg: response.result.description, success: false); +} + +Future closeDayHalykPos() async { + //Авторизация + String token = Redux.store.state.userState.user.token; + BankState bankState = Redux.store.state.bankState; + //права доступа + HalykPosSession session = + await _bankService.renewToken(token: token, login: bankState.login, password: bankState.password); + if (session.token == null) { + return new HalykResponse(result: ResultBean(description: 'Отказано в доступе к API банка', code: -1)); + } + //Инициализация + HalykResponse response = await _bankService.closeDay(token: session.token); + return response; +} + + + + diff --git a/lib/views/payment/payment_view.dart b/lib/views/payment/payment_view.dart index fb46ad6..336e345 100644 --- a/lib/views/payment/payment_view.dart +++ b/lib/views/payment/payment_view.dart @@ -30,7 +30,11 @@ import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart'; import 'package:flutter/material.dart'; import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_screenutil/screenutil.dart'; -import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; +import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart'; + +import '../../core/models/aman_dao.dart'; +import '../../core/models/card_data.dart'; +import '../../core/models/card_data.dart'; class PaymentView extends StatefulWidget { final PaymentModel model; @@ -60,7 +64,7 @@ class _PaymentViewState extends State { _bankInit() async { int version = await _bankService.version(); - if(version>=24){ + if (version >= 24) { setState(() { isBankApiAccess = true; }); @@ -114,9 +118,10 @@ class _PaymentViewState extends State { String dataTitle() => widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат'; - String dataText() => widget.model.operationType == OperationTypePay - ? 'К оплате' - : 'К возврату'; + String dataText() => + widget.model.operationType == OperationTypePay + ? 'К оплате' + : 'К возврату'; StoreConnector buildStoreConnector() { if (widget.model.mode == SettingModeCalc) { @@ -152,21 +157,21 @@ class _PaymentViewState extends State { children: [ Expanded( child: BusyButton( - title: 'Оплатить картой', - onPressed: () { - pressPayment('card'); - }, - mainColor: primaryColor, - )), + title: 'Оплатить картой', + onPressed: () { + pressPayment('card', null); + }, + mainColor: primaryColor, + )), horizontalSpaceSmall, Expanded( child: BusyButton( - title: 'Наличными', - onPressed: () { - pressPayment('cash'); - }, - mainColor: greenColor, - )), + title: 'Наличными', + onPressed: () { + pressPayment('cash', null); + }, + mainColor: greenColor, + )), ], ), ), @@ -178,83 +183,87 @@ class _PaymentViewState extends State { ), Container( child: BusyButton( - title: 'Отмена', - onPressed: () { - Navigator.pop(context); - }, - mainColor: redColor, - )), + title: 'Отмена', + onPressed: () { + Navigator.pop(context); + }, + mainColor: redColor, + )), ], ), ); } Widget _nfsButtonRender() { - if(!isBankApiAccess || widget.model.operationType != OperationTypePay){ + if (!isBankApiAccess || widget.model.operationType != OperationTypePay) { return Container(); } return StoreConnector( - converter: (store) => store.state.bankState, - builder: (_, state) { - if(state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1 ){ - return Container(); - } - return InkWell( - onTap: () { - _navigatorService.push(PaymentNfcViewRoute, - arguments: widget.model); - }, - splashColor: halykColor.withOpacity(0.4), - borderRadius: BorderRadius.circular(10.0), - highlightColor: halykColor.withOpacity(0.1), - child: Container( - width: ScreenUtil().setSp(100.0), - padding: const EdgeInsets.symmetric(vertical: 8.0), - decoration: BoxDecoration( + converter: (store) => store.state.bankState, + builder: (_, state) { + if (state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1) { + return Container(); + } + return InkWell( + onTap: () async { + AmanDao data = await paymentHalykPos(100); + if (data.success) { + pressPayment(widget.model.operationType, data.data); + } else { + _dialogService.showDialog(description: data.msg); + } + }, + splashColor: halykColor.withOpacity(0.4), + borderRadius: BorderRadius.circular(10.0), + highlightColor: halykColor.withOpacity(0.1), + child: Container( + width: ScreenUtil().setSp(100.0), + padding: const EdgeInsets.symmetric(vertical: 8.0), + decoration: BoxDecoration( borderRadius: BorderRadius.circular(10.0) - ), - child: Column( - children: [ - Container( - width: ScreenUtil().setSp(80.0), - height: ScreenUtil().setSp(80.0), - margin: const EdgeInsets.only(bottom: 8.0), - decoration: BoxDecoration( - border: Border.all(color: Colors.white), - borderRadius: BorderRadius.circular(10.0), - image: DecorationImage( - image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth - ), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 5, - blurRadius: 7, - offset: Offset(0, 3), // changes position of shadow - ), - ], - ), - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // children: [ - // Icon( - // MdiIcons.nfc, - // color: halykColor, - // size: ScreenUtil().setSp(20.0), - // ), - // Text('Tap2Phone',style: TextStyle(fontSize: ScreenUtil().setSp(10.0), color: halykColor, fontWeight: FontWeight.bold ),), - // ], - // ), - ], - ), ), - ); - } + child: Column( + children: [ + Container( + width: ScreenUtil().setSp(80.0), + height: ScreenUtil().setSp(80.0), + margin: const EdgeInsets.only(bottom: 8.0), + decoration: BoxDecoration( + border: Border.all(color: Colors.white), + borderRadius: BorderRadius.circular(10.0), + image: DecorationImage( + image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth + ), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // children: [ + // Icon( + // MdiIcons.nfc, + // color: halykColor, + // size: ScreenUtil().setSp(20.0), + // ), + // Text('Tap2Phone',style: TextStyle(fontSize: ScreenUtil().setSp(10.0), color: halykColor, fontWeight: FontWeight.bold ),), + // ], + // ), + ], + ), + ), + ); + } ); } - pressPayment(String type) async { + pressPayment(String type, CardData cardData) async { setState(() { isBusy = true; }); @@ -276,7 +285,9 @@ class _PaymentViewState extends State { operationType: widget.model.operationType, tradeType: _tradeType, calcItems: calcItems, - mode: _mode); + mode: _mode, + cardData: cardData + ); setState(() { isBusy = false; }); @@ -297,14 +308,17 @@ class _PaymentViewState extends State { Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); _navigatorService.pop(); _navigatorService.push(ImageShowRoute, - arguments: ImageShowModel(data:new CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: message, url: url )); + arguments: ImageShowModel(data: new CheckImageModal( + base64Data: check, textData: checkText != null ? jsonEncode(checkText) : null), + title: message, + url: url)); } else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) { Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); _dialogService.showDialog(description: response.body['message']); - } else if(!response.operation && response.body['message'] != null) { + } else if (!response.operation && response.body['message'] != null) { Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); _dialogService.showDialog(description: response.body['message']); - } else { + } else { Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); } } else { diff --git a/lib/views/payment_nfc/payment_nfc_view.dart b/lib/views/payment_nfc/payment_nfc_view.dart index 37f6483..6989187 100644 --- a/lib/views/payment_nfc/payment_nfc_view.dart +++ b/lib/views/payment_nfc/payment_nfc_view.dart @@ -85,15 +85,6 @@ class _PaymentNfcViewState extends State { return; } - //Инициализация - bool initialized = await _bankService.init(token: session.token); - log.i(initialized); - if (1 == 1) { - setState(() { - status = 4; - }); - return; - } //права доступа @@ -131,41 +122,41 @@ class _PaymentNfcViewState extends State { //Проверка связи - bool connected = await _bankService.connect(); - log.i(connected); - if (!connected) { - setState(() { - status = 5; - }); - return; - } + // bool connected = await _bankService.connect(); + // log.i(connected); + // if (!connected) { + // setState(() { + // status = 5; + // }); + // return; + // } - AmanDao authDao = await _bankService.auth( - login: bankState.login, password: bankState.password); - if (!authDao.success) { - setState(() { - status = 6; - }); - - if (authDao.msg != null) { - log.i(authDao.msg); - _dialogService.showDialog(description: authDao.msg); - } - return; - } - - //валюта - bool currency = await _bankService.currency(); - log.i(currency); - if (!currency) { - setState(() { - status = 4; - }); - return; - } + // AmanDao authDao = await _bankService.auth( + // login: bankState.login, password: bankState.password); + // if (!authDao.success) { + // setState(() { + // status = 6; + // }); + // + // if (authDao.msg != null) { + // log.i(authDao.msg); + // _dialogService.showDialog(description: authDao.msg); + // } + // return; + // } + // + // //валюта + // bool currency = await _bankService.currency(); + // log.i(currency); + // if (!currency) { + // setState(() { + // status = 4; + // }); + // return; + // } if(widget.model.voucher == null) { - pay(); + //pay(); } else { refund(); } @@ -173,35 +164,35 @@ class _PaymentNfcViewState extends State { refund() async { CardData _cardData = widget.model.cardData; - AmanDao findTransaction = await _bankService.findTransaction(transactionNumber: _cardData.transactionNumber, authorizationCode: _cardData.authorizationCode); - if(!findTransaction.success){ - _dialogService.showDialog(description: findTransaction.msg); - setState(() { - status = 8; - }); - return; - } + // AmanDao findTransaction = await _bankService.findTransaction(transactionNumber: _cardData.transactionNumber, authorizationCode: _cardData.authorizationCode); + // if(!findTransaction.success){ + // _dialogService.showDialog(description: findTransaction.msg); + // setState(() { + // status = 8; + // }); + // return; + // } + // + // setState(() { + // status = 1; + // isPhoneScaled = true; + // }); - setState(() { - status = 1; - isPhoneScaled = true; - }); - - AmanDao refundDao = await _bankService.refund(); - if (!refundDao.success) { - int _status = 7; - - setState(() { - status = _status; - isPhoneScaled = false; - }); - - if (refundDao.msg != null) { - log.i(refundDao.msg); - _dialogService.showDialog(description: refundDao.msg); - } - return; - } + // AmanDao refundDao = await _bankService.refund(); + // if (!refundDao.success) { + // int _status = 7; + // + // setState(() { + // status = _status; + // isPhoneScaled = false; + // }); + // + // if (refundDao.msg != null) { + // log.i(refundDao.msg); + // _dialogService.showDialog(description: refundDao.msg); + // } + // return; + // } setState(() { status = 9; @@ -209,61 +200,62 @@ class _PaymentNfcViewState extends State { }); //check - pressRefund('card' , refundDao.data); + //pressRefund('card' , refundDao.data); } - pay() async { - //Платеж - num total = 0.0; - if (widget.model.mode == SettingModeCalc) { - total = totalCalc(Redux.store.state.calcState.calcItems); - } else { - total = totalKassa(Redux.store.state.kassaState.kassaItems); - } - setState(() { - status = 1; - isPhoneScaled = true; - }); - - log.i('total: $total'); - AmanDao payDao = await _bankService.pay(amount: total); - if (!payDao.success) { - int _status = 7; - if (payDao.data != null ) { - if("onWrongApiCalled" == payDao.data.toString()) { - cancel(); - } else if("notAuthorized" == payDao.data.toString() ) { - cancel(); - _status = 6; - } - } - - setState(() { - status = _status; - isPhoneScaled = false; - }); - - if (payDao.msg != null) { - log.i(payDao.msg); - _dialogService.showDialog(description: payDao.msg); - } - return; - } - - setState(() { - status = 3; - isPhoneScaled = false; - }); - - //check - pressPayment('card' , payDao.data); - } + // pay() async { + // //Платеж + // num total = 0.0; + // if (widget.model.mode == SettingModeCalc) { + // total = totalCalc(Redux.store.state.calcState.calcItems); + // } else { + // total = totalKassa(Redux.store.state.kassaState.kassaItems); + // } + // + // setState(() { + // status = 1; + // isPhoneScaled = true; + // }); + // + // log.i('total: $total'); + // AmanDao payDao = await _bankService.pay(amount: total); + // if (!payDao.success) { + // int _status = 7; + // if (payDao.data != null ) { + // if("onWrongApiCalled" == payDao.data.toString()) { + // cancel(); + // } else if("notAuthorized" == payDao.data.toString() ) { + // cancel(); + // _status = 6; + // } + // } + // + // setState(() { + // status = _status; + // isPhoneScaled = false; + // }); + // + // if (payDao.msg != null) { + // log.i(payDao.msg); + // _dialogService.showDialog(description: payDao.msg); + // } + // return; + // } + // + // setState(() { + // status = 3; + // isPhoneScaled = false; + // }); + // + // //check + // pressPayment('card' , payDao.data); + // } cancel() async { - bool isCanceled = await _bankService.cancel(); - _navigatorService.pop(); + // bool isCanceled = await _bankService.cancel(); + // _navigatorService.pop(); } pressPayment(String type, dynamic cardDataDynamic) async { @@ -302,7 +294,6 @@ class _PaymentNfcViewState extends State { String check = response.body['check']; var checkText = response.body['check_text']; String url = response?.body['link']; - print('url : $url'); if (_mode == SettingModeCalc) { Redux.store.dispatch(cleanCalcItems); } else if (_mode == SettingModeKassa) { @@ -335,61 +326,11 @@ class _PaymentNfcViewState extends State { } } - pressRefund(String type, dynamic cardDataDynamic) async { - setState(() { - isBusy = true; - }); - Dialogs.showLoadingDialog(context, _keyLoader); - try { - AppState _state = Redux.store.state; - String _token = _state.userState.user.token; - CardData _cardData = cardDataDynamic != null ? CardData.fromJson(cardDataDynamic) : null; - CheckData _checkData = CheckData.fromJson(json.decode(widget.model.voucher.data)); - Response response = await _dataService.refundM4Bank( - token: _token, - cardData: _cardData, - checkData: _checkData - ); - setState(() { - isBusy = false; - }); - if (response != null) { - if (response.operation) { - String message = response.body['message']; - String check = response.body['check']; - var checkText = response.body['check_text']; - String url = response?.body['link']; - print('url : $url'); - Redux.store.dispatch(checkMoney); - Redux.store.dispatch(openSmenaPseudo); - Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); - _navigatorService.replace(HomeViewRoute); - _navigatorService.push(ImageShowRoute, - arguments: ImageShowModel(data: new CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: message, url: url)); - } else if (!response.operation && - ![401, 402, 403, 412, 500].contains(response.status)) { - Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); - _dialogService.showDialog(description: response.body['message']); - } else { - Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); - } - } else { - Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); - } - } catch (e) { - print(e); - Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); - } finally { - //Navigator.of(context, rootNavigator: true).pop(); - setState(() { - isBusy = false; - }); - } - } + @override void dispose() { - _bankService.shutdown(); + //_bankService.shutdown(); super.dispose(); } @@ -464,7 +405,7 @@ class _PaymentNfcViewState extends State { show: true, acceptText: 'Повторить', acceptCallback: () async { - await _bankService.shutdown(); + //await _bankService.shutdown(); start(); }, declineText: 'Отмена', @@ -478,7 +419,7 @@ class _PaymentNfcViewState extends State { show: true, acceptText: 'Повторить', acceptCallback: () async { - await _bankService.shutdown(); + //await _bankService.shutdown(); start(); }, declineText: 'Отмена', @@ -492,7 +433,7 @@ class _PaymentNfcViewState extends State { show: true, acceptText: 'Повторить', acceptCallback: () { - pay(); + //pay(); }, declineText: 'Отмена', declineCallback: () { diff --git a/pubspec.lock b/pubspec.lock index ea18bb5..cf57921 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -86,7 +86,7 @@ packages: source: hosted version: "2.1.1" crypto: - dependency: transitive + dependency: "direct main" description: name: crypto url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index 21ca0f0..11b3846 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -37,6 +37,7 @@ dependencies: esc_pos_bluetooth: ^0.2.8 esc_pos_utils: ^0.3.6 # no edit for esc_pos_bluetooth: ^0.2.8 charset_converter: ^1.0.3 + crypto: ^2.1.5 dev_dependencies: flutter_test: sdk: flutter