payment +

closeDay +-
refund -
backend_nfc
suvaissov 2021-04-27 11:18:17 +06:00
parent 93e6163ef2
commit 9d54a20f65
16 changed files with 769 additions and 602 deletions

View File

@ -11,88 +11,124 @@ import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant 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 import kz.com.aman.kassa.bank.OperationType
class MainActivity: FlutterActivity() { class MainActivity : FlutterActivity() {
private val externalApplicationRequestCode = 207 private val externalApplicationRequestCode = 207
private val EXTERNAL_OPERATION_TYPE_KEY = "ru.m4bank.ExternalApplication.OperationTypeKey" private val externalOperationTypeKey = "ru.m4bank.ExternalApplication.OperationTypeKey"
private val EXTERNAL_INPUT_DATA_KEY = "ru.m4bank.ExternalApplication.InputDataKey" private val externalInputDataKey = "ru.m4bank.ExternalApplication.InputDataKey"
private val EXTERNAL_RESULT_DATA_KEY = "ru.m4bank.ExternalApplication.ResultDataKey" private val externalResultDataKey = "ru.m4bank.ExternalApplication.ResultDataKey"
private val BANK_CHANNEL = "channel:com.amanKassa/bank" private val bankChannel = "channel:com.amanKassa/bank"
private val ACTIVITY_CHANNEL = "channel:com.amanKassa/activity"
private lateinit var _result: MethodChannel.Result private lateinit var _result: MethodChannel.Result
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine); GeneratedPluginRegistrant.registerWith(flutterEngine)
//MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this)); //MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this))
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(MethodChannel.MethodCallHandler { call, result -> MethodChannel(flutterEngine.dartExecutor.binaryMessenger, bankChannel).setMethodCallHandler { call, result ->
_result = result; _result = result
if(call.method == "init") { when (call.method) {
operationPayment(call); "pay" -> {
} else if(call.method == "version") { operationPayment(call)
}
"refund" -> {
operationRefund(call)
}
"reversal" -> {
operationReversal(call)
}
"closeDay" -> {
operationCloseDay(call)
}
"version" -> {
result.success(Build.VERSION.SDK_INT.toString()) result.success(Build.VERSION.SDK_INT.toString())
} else { }
else -> {
result.notImplemented() result.notImplemented()
} }
}
}) }
} }
private fun getOperationList(call: MethodCall) { // private fun getOperationList(call: MethodCall) {
val token: String = call.argument<String>("token").toString() // val token: String = call.argument<String>("token").toString()
val operationParameters = createOperationParameters(token); // val operationParameters = createOperationParameters(token)
println(operationParameters.toString()); // startOperation(OperationType.OPERATIONS_LIST,
println(JsonForTests.getOperationsListJson(token)); // JsonForExternalCall.getOperationsListJson(operationParameters.authToken))
startOperation(OperationType.OPERATIONS_LIST, //
JsonForTests.getOperationsListJson(operationParameters.authToken)) // }
}
private fun operationPayment(call: MethodCall) { private fun operationPayment(call: MethodCall) {
val token = call.argument<String>("token").toString() val token = call.argument<String>("token").toString()
val operationParameters = createOperationParameters(token); var amount: Long = 0
println(operationParameters.toString()); if (call.argument<Long>("amount") != null) {
println(JsonForTests.getPaymentCardJson(operationParameters.authToken)); amount = call.argument<Long>("amount")!!.toLong()
startOperation(OperationType.PAYMENT, JsonForTests.getPaymentCardJson(operationParameters.authToken)) }
val operationParameters = createOperationParameters(token)
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()))
}
private fun operationRefund(call: MethodCall) {
val token = call.argument<String>("token").toString()
val terminalId = call.argument<String>("terminalId").toString()
val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("transNum").toString()
val amount = call.argument<String>("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<String>("token").toString()
val terminalId = call.argument<String>("terminalId").toString()
val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("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<String>("token").toString()
val operationParameters = createOperationParameters(token)
startOperation(OperationType.CLOSE_DAY, JsonForExternalCall.getCloseDayJson(operationParameters.authToken))
} }
private fun createOperationParameters(token: String, operDay: String = "", terminalId: String = "", transNum: String = ""): OperationParameters {
private fun createOperationParameters(token: String): OperationParameters { return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum)
return OperationParameters(authToken = token, operDay = "", terminalId = "", transNum = "");
} }
private fun startOperation(operationType: OperationType, inputJsonData: String?) { private fun startOperation(operationType: OperationType, inputJsonData: String?) {
val intent = Intent() val intent = Intent()
intent.component = ComponentName("ru.m4bank.softpos.halyk", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity") intent.component = ComponentName("ru.m4bank.softpos.halyk", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
//intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP // intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra(EXTERNAL_OPERATION_TYPE_KEY, operationType.code) intent.putExtra(externalOperationTypeKey, operationType.code)
intent.putExtra(EXTERNAL_INPUT_DATA_KEY, inputJsonData) intent.putExtra(externalInputDataKey, inputJsonData)
startActivityForResult(intent, externalApplicationRequestCode) startActivityForResult(intent, externalApplicationRequestCode)
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
if(requestCode == externalApplicationRequestCode) { if (requestCode == externalApplicationRequestCode) {
println("---------------"); println("---------------")
println(requestCode); println(requestCode)
println(resultCode); println(resultCode)
println(data); println(data)
if (data != null) { if (data != null) {
println(data.getStringExtra(EXTERNAL_RESULT_DATA_KEY)) println(data.getStringExtra(externalResultDataKey))
}; }
println("---------------"); println("---------------")
if (requestCode == externalApplicationRequestCode && resultCode == Activity.RESULT_OK && data != null) { if (requestCode == externalApplicationRequestCode && resultCode == Activity.RESULT_OK && data != null) {
println(data.getStringExtra(EXTERNAL_RESULT_DATA_KEY)); println(data.getStringExtra(externalResultDataKey))
Toast.makeText(this, data.getStringExtra(EXTERNAL_RESULT_DATA_KEY), Toast.LENGTH_LONG).show() Toast.makeText(this, data.getStringExtra(externalResultDataKey), Toast.LENGTH_LONG).show()
_result.success(data.getStringExtra(externalResultDataKey))
} else { } else {
_result.error("008", "Error while apps connecting", "aaa")
Toast.makeText(this, "Error while apps connecting", Toast.LENGTH_SHORT).show() Toast.makeText(this, "Error while apps connecting", Toast.LENGTH_SHORT).show()
} }
// if (resultCode == Activity.RESULT_OK) { // 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) data class OperationParameters(val authToken: String, val terminalId: String, val operDay: String, val transNum: String)

View File

@ -1,8 +1,8 @@
package kz.com.aman.kassa.bank; package kz.com.aman.kassa.bank;
object JsonForTests { object JsonForExternalCall {
fun getPaymentCardJson(authToken: String): String { fun getPaymentCardJson(authToken: String, amount: String): String {
return """{ return """{
"credentials" : { "credentials" : {
"authorizationToken": "$authToken" "authorizationToken": "$authToken"
@ -11,14 +11,14 @@ object JsonForTests {
"instrument": "CARD", "instrument": "CARD",
"amountData" : { "amountData" : {
"currencyCode": "398", "currencyCode": "398",
"amount": "6000", "amount": "$amount",
"amountExponent": "2" "amountExponent": "2"
}, },
"goods" : { "goods" : {
"product": [{ "product": [{
"name": "Печеньки", "name": "Товар",
"price": "3000", "price": "$amount",
"quantity": "2", "quantity": "1",
"quantityExponent": "0", "quantityExponent": "0",
"taxRate": "TAX_20", "taxRate": "TAX_20",
"accountingSubject": "PRODUCT" "accountingSubject": "PRODUCT"
@ -28,33 +28,7 @@ object JsonForTests {
}""" }"""
} }
fun getPaymentCashJson(authToken: String): String { fun getRefundCardJson(authToken: String, terminalId: String, operDay: String, transNum: String, amount: 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 {
return """{ return """{
"credentials" :{ "credentials" :{
"authorizationToken": "$authToken" "authorizationToken": "$authToken"
@ -62,7 +36,7 @@ object JsonForTests {
"operationData" :{ "operationData" :{
"instrument": "CARD", "instrument": "CARD",
"amountData" : { "amountData" : {
"currencyCode": "643", "currencyCode": "348",
"amount": "6000", "amount": "6000",
"amountExponent": "2" "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 { fun getCloseDayJson(authToken: String): String {
return """{ return """{
"credentials" : { "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"
// }
// }
// }"""
// }
} }

View File

@ -1,32 +1,35 @@
class CardData { class CardData {
final int transactionNumber; final int transactionNumber;
final String cardExpiryDate; final int operationDay;
final int terminalId;
final String cardNumber; final String cardNumber;
final String transactionType; final String cardholderName;
final String cardPaymentSystemType;
final String authorizationCode; 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<String, dynamic> json) { static CardData fromJson(Map<String, dynamic> json) {
return json != null ? return json != null ?
CardData( CardData(
transactionNumber: json['transactionNumber'], transactionNumber: json['transactionNumber'],
cardExpiryDate: json['cardExpiryDate'], operationDay: json['operationDay'],
terminalId: json['terminalId'],
cardNumber: json['cardNumber'], cardNumber: json['cardNumber'],
transactionType: json['transactionType'], cardholderName: json['cardholderName'],
cardPaymentSystemType: json['cardPaymentSystemType'],
authorizationCode: json['authorizationCode'], authorizationCode: json['authorizationCode'],
transactionType: json['transactionType'],
) )
: null; : null;
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() =>
{ {
'transactionNumber': transactionNumber, 'transactionNumber': transactionNumber,
'cardExpiryDate': cardExpiryDate, 'operationDay': operationDay,
'cardNumber': cardNumber, 'cardNumber': cardNumber,
'transactionType': transactionType, 'cardholderName': cardholderName,
'cardPaymentSystemType': cardPaymentSystemType,
'authorizationCode': authorizationCode, 'authorizationCode': authorizationCode,
'terminalId' : terminalId,
'transactionType' : transactionType,
}; };
} }

View File

@ -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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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<String, dynamic> 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,
};
}

View File

@ -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/state/user_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/views/login/login_view.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:device_info/device_info.dart';
import 'package:aman_kassa_flutter/core/models/message.dart'; import 'package:aman_kassa_flutter/core/models/message.dart';
import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/models/response.dart';
@ -67,6 +68,9 @@ class ApiService extends BaseService {
} }
Future<HalykPosSession> halykPosToken(String token, login, password) async { Future<HalykPosSession> 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<String, String> requestBody = <String, String>{'login': login, 'password': password}; Map<String, String> requestBody = <String, String>{'login': login, 'password': password};
var response = await requestFormData('/getpostoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false); var response = await requestFormData('/getpostoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
return HalykPosSession.fromJson(jsonDecode(response)); return HalykPosSession.fromJson(jsonDecode(response));
@ -163,10 +167,10 @@ class ApiService extends BaseService {
String url = '$endpoint$point'; String url = '$endpoint$point';
if(this._test) { if(this._test) {
url = '$test_endpoint$point'; url = '$test_endpoint$point';
}
if(posEndPoint){ if(posEndPoint){
url = '$pos_endpoint$point'; url = '$pos_endpoint$point';
} }
}
var uri = Uri.parse(url); var uri = Uri.parse(url);
String body; String body;

View File

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:aman_kassa_flutter/core/base/base_service.dart'; import 'package:aman_kassa_flutter/core/base/base_service.dart';
import 'package:aman_kassa_flutter/core/locator.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/close_day_data.dart';
import 'package:aman_kassa_flutter/core/models/halyk_post_session.dart'; import 'package:aman_kassa_flutter/core/models/halyk_post_session.dart';
import 'package:aman_kassa_flutter/core/models/transaction_item.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:flutter/services.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import '../models/aman_dao.dart';
class BankService extends BaseService { class BankService extends BaseService {
final ApiService _api = locator<ApiService>(); final ApiService _api = locator<ApiService>();
@ -40,168 +42,44 @@ class BankService extends BaseService {
Future<bool> init({String token}) async { Future<HalykResponse> closeDay({ 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<String> 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;
try { try {
String response = await _channel.invokeMethod('init', <String, dynamic>{ String response = await _channel.invokeMethod("closeDay", <String, dynamic>{'token': token });
'serverUrl': _url, HalykResponse dao = HalykResponse.fromMap(json.decode(response));
'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<bool> 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<bool> 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<bool> 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<AmanDao> auth({String login, String password}) async {
try {
String response = await _channel.invokeMethod("auth",
<String, dynamic>{'login': login, 'password': password});
AmanDao dao = AmanDao.fromJson(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
return new AmanDao(msg: 'Ошибка авторизации'); return new HalykResponse(result: ResultBean(description: 'Ошибка при закрытии дня', code: -1));
} }
} }
Future<AmanDao> closeDay() async { Future<HalykResponse> pay({double amount, String token}) 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<AmanDao> pay({double amount}) async {
try { try {
double total = amount * 100; double total = amount * 100;
log.i('total: $total, ${total.toInt()}'); log.i('total: $total, ${total.toInt()}');
String response = await _channel.invokeMethod("pay", <String, dynamic>{'amount': total.toInt()}); String response = await _channel.invokeMethod("pay", <String, dynamic>{'amount': total.toInt(), 'token': token });
AmanDao dao = AmanDao.fromJson(json.decode(response)); HalykResponse dao = HalykResponse.fromMap(json.decode(response));
log.i('${dao.success} - ${dao.msg}');
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
return new AmanDao(msg: 'Ошибка оплаты'); return new HalykResponse(result: ResultBean(description: 'Ошибка оплаты', code: -1));
} }
} }
Future<AmanDao> findTransaction({int transactionNumber, String authorizationCode}) async { Future<HalykResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async {
try { try {
log.i('transactionNumber: $transactionNumber'); String response = await _channel.invokeMethod("refund", <String, dynamic>{
String response = await _channel.invokeMethod("findTransaction", <String, dynamic>{'transactionNumber': transactionNumber, 'authorizationCode': authorizationCode}); 'amount': amount.toInt(), 'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum
AmanDao dao = AmanDao.fromJson(json.decode(response)); });
log.i('${dao.success} - ${dao.msg}'); HalykResponse dao = HalykResponse.fromMap(json.decode(response));
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
return new AmanDao(msg: 'Ошибка при поиске транзакии банка'); return new HalykResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
} }
} }
Future<AmanDao> 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<bool> 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<bool> 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) { CloseDayData closeDayDataConvert(dynamic rows) {
final DateFormat formatter = DateFormat('dd.MM.yyyy'); final DateFormat formatter = DateFormat('dd.MM.yyyy');

View File

@ -1,4 +1,8 @@
// Define a function. // Define a function.
import 'dart:convert';
import 'package:crypto/crypto.dart';
void printInteger(int aNumber) { void printInteger(int aNumber) {
print('The number is $aNumber.'); // Print to console. print('The number is $aNumber.'); // Print to console.
} }
@ -8,4 +12,7 @@ void main() {
String dataMatrix = "00000046208262nZ2qnLHODVFWktT"; String dataMatrix = "00000046208262nZ2qnLHODVFWktT";
String numberText = dataMatrix.replaceAll(RegExp("[a-zA-Z]"), ''); String numberText = dataMatrix.replaceAll(RegExp("[a-zA-Z]"), '');
print(int.parse(numberText)); 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);
} }

View File

@ -31,16 +31,16 @@ class _BankSettingViewState extends State<BankSettingView> {
BankState state = Redux.store.state.bankState; BankState state = Redux.store.state.bankState;
_emailController = new TextEditingController(text: state.login); _emailController = new TextEditingController(text: state.login);
_passwordController = new TextEditingController(text: state.password); _passwordController = new TextEditingController(text: state.password);
permissions(); //permissions();
} }
Future<void> permissions() async { // Future<void> permissions() async {
try { // try {
await _bankService.permissions(); // await _bankService.permissions();
} on PlatformException { // } on PlatformException {
//
} // }
} // }
@override @override

View File

@ -2,22 +2,27 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart'; import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.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/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/aman_dao.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/card_data.dart';
import 'package:aman_kassa_flutter/core/models/dialog_models.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/route_names.dart';
import 'package:aman_kassa_flutter/core/services/BankService.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/dialog_service.dart';
import 'package:aman_kassa_flutter/core/services/navigator_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/constants/setting_const.dart';
import 'package:aman_kassa_flutter/redux/state/setting_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/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.dart'; import 'package:aman_kassa_flutter/shared/app_colors.dart';
import 'package:aman_kassa_flutter/shared/ui_helpers.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/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/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_bluetooth/esc_pos_bluetooth.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/cupertino.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:esys_flutter_share/esys_flutter_share.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../core/models/aman_dao.dart';
class ImageShowContainer extends StatefulWidget { class ImageShowContainer extends StatefulWidget {
final ImageShowModel showModel; final ImageShowModel showModel;
@ -37,8 +44,10 @@ class ImageShowContainer extends StatefulWidget {
} }
class _ImageShowContainerState extends State<ImageShowContainer> { class _ImageShowContainerState extends State<ImageShowContainer> {
final PrinterBluetoothManager printerManager = PrinterBluetoothManager(); final PrinterBluetoothManager printerManager = PrinterBluetoothManager();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT; final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT;
bool _printing = false; bool _printing = false;
@ -154,6 +163,8 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
bool showFab = true; bool showFab = true;
DialogService _dialog = locator<DialogService>(); DialogService _dialog = locator<DialogService>();
NavigatorService _navigatorService = locator<NavigatorService>(); NavigatorService _navigatorService = locator<NavigatorService>();
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
final DataService _dataService = locator<DataService>();
double sheetHeight = 260; double sheetHeight = 260;
@ -164,8 +175,35 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return showFab if (showFab) {
? FloatingActionButton( 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<CardData> 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), child: Icon(Icons.share),
onPressed: () { onPressed: () {
var bottomSheetController = showBottomSheet( var bottomSheetController = showBottomSheet(
@ -181,7 +219,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
color: Colors.grey[300], color: Colors.grey[300],
spreadRadius: 5) spreadRadius: 5)
]), ]),
height: sheetHeight, height: 260,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
verticalSpaceSmall, verticalSpaceSmall,
@ -204,17 +242,63 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
BusyButtonIcon( BusyButtonIcon(
title: 'Поделиться', title: 'Поделиться',
onPressed: shareFile, onPressed: shareFile,
mainColor: redColor, mainColor: yellowColor,
icon: Icons.share, icon: Icons.share,
), ),
], ],
))); )));
showFloatingActionButton(false);
bottomSheetController.closed.then((value) { bottomSheetController.closed.then((value) {
showFloatingActionButton(true); 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<dynamic> 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 { void shareFile() async {
@ -269,4 +353,5 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
showFab = value; showFab = value;
}); });
} }
} }

View File

@ -106,7 +106,7 @@ class _HistoryViewState extends State<HistoryView> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(dateFormat.format(voucher.dateTime)), 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), trailing: Icon(Icons.arrow_right),

View File

@ -2,8 +2,9 @@ import 'dart:convert';
import 'package:aman_kassa_flutter/core/entity/Voucher.dart'; import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
import 'package:aman_kassa_flutter/core/locator.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/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/money.dart';
import 'package:aman_kassa_flutter/core/models/response.dart'; import 'package:aman_kassa_flutter/core/models/response.dart';
import 'package:aman_kassa_flutter/core/models/dialog_models.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/user_actions.dart';
import 'package:aman_kassa_flutter/redux/actions/setting_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/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/state/setting_state.dart';
import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/redux/store.dart';
import 'package:aman_kassa_flutter/shared/app_colors.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/aman_icon_button_horizontal.dart';
import 'package:aman_kassa_flutter/widgets/fields/busy_button.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/widgets/loader/Dialogs.dart';
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
@ -233,30 +234,12 @@ class _AdditionalTabState extends State<AdditionalTab> {
return; return;
} }
//Инициализация
bool initialized = await _bankService.init();
if (!initialized) {
setState(() {
isClosePosBusy = false;
});
return;
}
//Проверка связи HalykResponse closeDayDao = (await closeDayHalykPos()) as HalykResponse;
bool connected = await _bankService.connect();
if (!connected) { if (closeDayDao.result.code != 0) {
setState(() { if (closeDayDao.result.description != null) {
isClosePosBusy = false; _dialog.showDialog(description: closeDayDao.result.description);
});
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);
} }
setState(() { setState(() {
isClosePosBusy = false; isClosePosBusy = false;
@ -264,36 +247,24 @@ class _AdditionalTabState extends State<AdditionalTab> {
return; return;
} }
AmanDao closeDayDao = await _bankService.closeDay(); //
// CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.rows);
if (!closeDayDao.success) { //
if (closeDayDao.msg != null) { // User user = Redux.store.state.userState.user;
_dialog.showDialog(description: closeDayDao.msg); // _dataService.insertVoucher(
} // user: user,
setState(() { // name: closeDayData.title,
isClosePosBusy = false; // data: jsonEncode(closeDayData.toJson()),
}); // total: closeDayData.totalAmount.toDouble(),
return; // type: VoucherTypeCloseDayPosReport);
} //
// // _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!');
// setState(() {
CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.rows); // isClosePosBusy = false;
// });
User user = Redux.store.state.userState.user; //
_dataService.insertVoucher( // _navigator.push(CloseDayShowRoute,
user: user, // arguments: closeDayData);
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 @override

View File

@ -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<BankService>();
DialogService _dialogService = locator<DialogService>();
final DataService _dataService = locator<DataService>();
final NavigatorService _navigatorService = locator<NavigatorService>();
Logger log = getLogger('PaymentNfcView');
Future<AmanDao<CardData>> 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<CardData>(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<CardData>(msg: response.result.description, success: true, data: cardData);
}
return AmanDao<CardData>(msg: response.result.description, success: false);
}
Future<AmanDao<CardData>> 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<CardData>(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<CardData>(msg: response.result.description, success: true, data: cardData);
}
return AmanDao<CardData>(msg: response.result.description, success: false);
}
Future<HalykResponse> 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;
}

View File

@ -30,7 +30,11 @@ import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:flutter_screenutil/screenutil.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 { class PaymentView extends StatefulWidget {
final PaymentModel model; final PaymentModel model;
@ -60,7 +64,7 @@ class _PaymentViewState extends State<PaymentView> {
_bankInit() async { _bankInit() async {
int version = await _bankService.version(); int version = await _bankService.version();
if(version>=24){ if (version >= 24) {
setState(() { setState(() {
isBankApiAccess = true; isBankApiAccess = true;
}); });
@ -114,7 +118,8 @@ class _PaymentViewState extends State<PaymentView> {
String dataTitle() => String dataTitle() =>
widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат'; widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
String dataText() => widget.model.operationType == OperationTypePay String dataText() =>
widget.model.operationType == OperationTypePay
? 'К оплате' ? 'К оплате'
: 'К возврату'; : 'К возврату';
@ -154,7 +159,7 @@ class _PaymentViewState extends State<PaymentView> {
child: BusyButton( child: BusyButton(
title: 'Оплатить картой', title: 'Оплатить картой',
onPressed: () { onPressed: () {
pressPayment('card'); pressPayment('card', null);
}, },
mainColor: primaryColor, mainColor: primaryColor,
)), )),
@ -163,7 +168,7 @@ class _PaymentViewState extends State<PaymentView> {
child: BusyButton( child: BusyButton(
title: 'Наличными', title: 'Наличными',
onPressed: () { onPressed: () {
pressPayment('cash'); pressPayment('cash', null);
}, },
mainColor: greenColor, mainColor: greenColor,
)), )),
@ -190,19 +195,23 @@ class _PaymentViewState extends State<PaymentView> {
} }
Widget _nfsButtonRender() { Widget _nfsButtonRender() {
if(!isBankApiAccess || widget.model.operationType != OperationTypePay){ if (!isBankApiAccess || widget.model.operationType != OperationTypePay) {
return Container(); return Container();
} }
return StoreConnector<AppState, BankState>( return StoreConnector<AppState, BankState>(
converter: (store) => store.state.bankState, converter: (store) => store.state.bankState,
builder: (_, state) { builder: (_, state) {
if(state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1 ){ if (state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1) {
return Container(); return Container();
} }
return InkWell( return InkWell(
onTap: () { onTap: () async {
_navigatorService.push(PaymentNfcViewRoute, AmanDao<CardData> data = await paymentHalykPos(100);
arguments: widget.model); if (data.success) {
pressPayment(widget.model.operationType, data.data);
} else {
_dialogService.showDialog(description: data.msg);
}
}, },
splashColor: halykColor.withOpacity(0.4), splashColor: halykColor.withOpacity(0.4),
borderRadius: BorderRadius.circular(10.0), borderRadius: BorderRadius.circular(10.0),
@ -254,7 +263,7 @@ class _PaymentViewState extends State<PaymentView> {
); );
} }
pressPayment(String type) async { pressPayment(String type, CardData cardData) async {
setState(() { setState(() {
isBusy = true; isBusy = true;
}); });
@ -276,7 +285,9 @@ class _PaymentViewState extends State<PaymentView> {
operationType: widget.model.operationType, operationType: widget.model.operationType,
tradeType: _tradeType, tradeType: _tradeType,
calcItems: calcItems, calcItems: calcItems,
mode: _mode); mode: _mode,
cardData: cardData
);
setState(() { setState(() {
isBusy = false; isBusy = false;
}); });
@ -297,11 +308,14 @@ class _PaymentViewState extends State<PaymentView> {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_navigatorService.pop(); _navigatorService.pop();
_navigatorService.push(ImageShowRoute, _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)) { } else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) {
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialogService.showDialog(description: response.body['message']); _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(); Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
_dialogService.showDialog(description: response.body['message']); _dialogService.showDialog(description: response.body['message']);
} else { } else {

View File

@ -85,15 +85,6 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
return; 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<PaymentNfcView> {
//Проверка связи //Проверка связи
bool connected = await _bankService.connect(); // bool connected = await _bankService.connect();
log.i(connected); // log.i(connected);
if (!connected) { // if (!connected) {
setState(() { // setState(() {
status = 5; // status = 5;
}); // });
return; // return;
} // }
AmanDao authDao = await _bankService.auth( // AmanDao authDao = await _bankService.auth(
login: bankState.login, password: bankState.password); // login: bankState.login, password: bankState.password);
if (!authDao.success) { // if (!authDao.success) {
setState(() { // setState(() {
status = 6; // status = 6;
}); // });
//
if (authDao.msg != null) { // if (authDao.msg != null) {
log.i(authDao.msg); // log.i(authDao.msg);
_dialogService.showDialog(description: authDao.msg); // _dialogService.showDialog(description: authDao.msg);
} // }
return; // return;
} // }
//
//валюта // //валюта
bool currency = await _bankService.currency(); // bool currency = await _bankService.currency();
log.i(currency); // log.i(currency);
if (!currency) { // if (!currency) {
setState(() { // setState(() {
status = 4; // status = 4;
}); // });
return; // return;
} // }
if(widget.model.voucher == null) { if(widget.model.voucher == null) {
pay(); //pay();
} else { } else {
refund(); refund();
} }
@ -173,35 +164,35 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
refund() async { refund() async {
CardData _cardData = widget.model.cardData; CardData _cardData = widget.model.cardData;
AmanDao findTransaction = await _bankService.findTransaction(transactionNumber: _cardData.transactionNumber, authorizationCode: _cardData.authorizationCode); // AmanDao findTransaction = await _bankService.findTransaction(transactionNumber: _cardData.transactionNumber, authorizationCode: _cardData.authorizationCode);
if(!findTransaction.success){ // if(!findTransaction.success){
_dialogService.showDialog(description: findTransaction.msg); // _dialogService.showDialog(description: findTransaction.msg);
setState(() { // setState(() {
status = 8; // status = 8;
}); // });
return; // return;
} // }
//
// setState(() {
// status = 1;
// isPhoneScaled = true;
// });
setState(() { // AmanDao refundDao = await _bankService.refund();
status = 1; // if (!refundDao.success) {
isPhoneScaled = true; // int _status = 7;
}); //
// setState(() {
AmanDao refundDao = await _bankService.refund(); // status = _status;
if (!refundDao.success) { // isPhoneScaled = false;
int _status = 7; // });
//
setState(() { // if (refundDao.msg != null) {
status = _status; // log.i(refundDao.msg);
isPhoneScaled = false; // _dialogService.showDialog(description: refundDao.msg);
}); // }
// return;
if (refundDao.msg != null) { // }
log.i(refundDao.msg);
_dialogService.showDialog(description: refundDao.msg);
}
return;
}
setState(() { setState(() {
status = 9; status = 9;
@ -209,61 +200,62 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
}); });
//check //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(() { // pay() async {
status = 1; // //Платеж
isPhoneScaled = true; // num total = 0.0;
}); // if (widget.model.mode == SettingModeCalc) {
// total = totalCalc(Redux.store.state.calcState.calcItems);
log.i('total: $total'); // } else {
AmanDao payDao = await _bankService.pay(amount: total); // total = totalKassa(Redux.store.state.kassaState.kassaItems);
if (!payDao.success) { // }
int _status = 7; //
if (payDao.data != null ) { // setState(() {
if("onWrongApiCalled" == payDao.data.toString()) { // status = 1;
cancel(); // isPhoneScaled = true;
} else if("notAuthorized" == payDao.data.toString() ) { // });
cancel(); //
_status = 6; // log.i('total: $total');
} // AmanDao payDao = await _bankService.pay(amount: total);
} // if (!payDao.success) {
// int _status = 7;
setState(() { // if (payDao.data != null ) {
status = _status; // if("onWrongApiCalled" == payDao.data.toString()) {
isPhoneScaled = false; // cancel();
}); // } else if("notAuthorized" == payDao.data.toString() ) {
// cancel();
if (payDao.msg != null) { // _status = 6;
log.i(payDao.msg); // }
_dialogService.showDialog(description: payDao.msg); // }
} //
return; // setState(() {
} // status = _status;
// isPhoneScaled = false;
setState(() { // });
status = 3; //
isPhoneScaled = false; // if (payDao.msg != null) {
}); // log.i(payDao.msg);
// _dialogService.showDialog(description: payDao.msg);
//check // }
pressPayment('card' , payDao.data); // return;
} // }
//
// setState(() {
// status = 3;
// isPhoneScaled = false;
// });
//
// //check
// pressPayment('card' , payDao.data);
// }
cancel() async { cancel() async {
bool isCanceled = await _bankService.cancel(); // bool isCanceled = await _bankService.cancel();
_navigatorService.pop(); // _navigatorService.pop();
} }
pressPayment(String type, dynamic cardDataDynamic) async { pressPayment(String type, dynamic cardDataDynamic) async {
@ -302,7 +294,6 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
String check = response.body['check']; String check = response.body['check'];
var checkText = response.body['check_text']; var checkText = response.body['check_text'];
String url = response?.body['link']; String url = response?.body['link'];
print('url : $url');
if (_mode == SettingModeCalc) { if (_mode == SettingModeCalc) {
Redux.store.dispatch(cleanCalcItems); Redux.store.dispatch(cleanCalcItems);
} else if (_mode == SettingModeKassa) { } else if (_mode == SettingModeKassa) {
@ -335,61 +326,11 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
} }
} }
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<dynamic> 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 @override
void dispose() { void dispose() {
_bankService.shutdown(); //_bankService.shutdown();
super.dispose(); super.dispose();
} }
@ -464,7 +405,7 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
show: true, show: true,
acceptText: 'Повторить', acceptText: 'Повторить',
acceptCallback: () async { acceptCallback: () async {
await _bankService.shutdown(); //await _bankService.shutdown();
start(); start();
}, },
declineText: 'Отмена', declineText: 'Отмена',
@ -478,7 +419,7 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
show: true, show: true,
acceptText: 'Повторить', acceptText: 'Повторить',
acceptCallback: () async { acceptCallback: () async {
await _bankService.shutdown(); //await _bankService.shutdown();
start(); start();
}, },
declineText: 'Отмена', declineText: 'Отмена',
@ -492,7 +433,7 @@ class _PaymentNfcViewState extends State<PaymentNfcView> {
show: true, show: true,
acceptText: 'Повторить', acceptText: 'Повторить',
acceptCallback: () { acceptCallback: () {
pay(); //pay();
}, },
declineText: 'Отмена', declineText: 'Отмена',
declineCallback: () { declineCallback: () {

View File

@ -86,7 +86,7 @@ packages:
source: hosted source: hosted
version: "2.1.1" version: "2.1.1"
crypto: crypto:
dependency: transitive dependency: "direct main"
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"

View File

@ -37,6 +37,7 @@ dependencies:
esc_pos_bluetooth: ^0.2.8 esc_pos_bluetooth: ^0.2.8
esc_pos_utils: ^0.3.6 # no edit for 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 charset_converter: ^1.0.3
crypto: ^2.1.5
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter