// Used internally /// <summary> /// Sends reading command using ABECS when card have a chip. /// </summary> /// <param name="pinpadCommunication">Pinpad communication, through which the communication with the pinpad is made.</param> /// <param name="amount">Transaction amount.</param> /// <returns>ABECS GOC command response.</returns> private GocResponse SendGoc(IPinpadCommunication pinpadCommunication, decimal amount) { GocRequest request = new GocRequest(); request.GOC_AMOUNT.Value = Convert.ToInt64(amount * 100); request.GOC_CASHBACK.Value = 0; request.GOC_EXCLIST.Value = false; request.GOC_CONNECT.Value = true; request.GOC_METHOD.Value = new CryptographyMethod(KeyManagementMode.DerivedUniqueKeyPerTransaction, CryptographyMode.TripleDataEncryptionStandard); request.GOC_KEYIDX.Value = (int)StoneIndexCode.EncryptionKey; request.GOC_WKENC.Value = new HexadecimalData("00000000000000000000000000000000"); request.GOC_RISKMAN.Value = false; request.GOC_FLRLIMIT.Value = new HexadecimalData("00000000"); request.GOC_TPBRS.Value = 0; request.GOC_TVBRS.Value = new HexadecimalData("00000000"); request.GOC_MTPBRS.Value = 0; request.GOC_TAGS1.Value = new HexadecimalData(EmvTag.GetEmvTagsRequired()); request.GOC_TAGS2.Value = new HexadecimalData(string.Empty); GocResponse response = pinpadCommunication.SendRequestAndReceiveResponse <GocResponse>(request); return(response); }
// Methods /// <summary> /// Reads the card. /// </summary> /// <param name="communication">Pinpad facade, responsible for pinpad communication and plus.</param> /// <param name="amount">Transaction amount.</param> /// <param name="pin">Pin information read.</param> /// <returns>Operation status.</returns> internal ResponseStatus Read(IPinpadCommunication communication, decimal amount, out Pin pin) { pin = null; // Validating data this.Validate(communication, amount); // Using ABECS GOC command to communicate with pinpad. GocResponse commandResponse = this.SendGoc(communication, amount); if (commandResponse == null) { if (communication.Ping() == true) { // Pinpad is connected. Time out. return(ResponseStatus.TimeOut); } else { // Pinpad loss conection. throw new PinpadDisconnectedException("Não foi possível ler a senha.\nVerifique a conexão com o pinpad."); } } // Saving command response status: AbecsResponseStatus legacyStatus = commandResponse.RSP_STAT.Value; ResponseStatus status = ResponseStatusMapper.MapLegacyResponseStatus(legacyStatus); if (status != ResponseStatus.Ok) { return(status); } //if (status == ResponseStatus.OperationCancelled) { return status; } pin = new Pin(); pin.ApplicationCryptogram = this.GetValueFromEmvData( commandResponse.GOC_EMVDAT.Value.DataString, EmvTagCode.ApplicationCryptogram); pin.CardholderNameExtended = this.GetValueFromEmvData( commandResponse.GOC_EMVDAT.Value.DataString, EmvTagCode.CardholderNameExtended); // Whether is a pin online authentication or not. if (commandResponse.GOC_PINONL.Value.HasValue == true) { pin.IsOnline = commandResponse.GOC_PINONL.Value.Value; } // If EMV data war not returned from the command: if (commandResponse.GOC_EMVDAT.HasValue == false) { return(ResponseStatus.PinBusy); } // Savind EMV data: if (commandResponse.GOC_EMVDAT.Value != null) { pin.EmvData = commandResponse.GOC_EMVDAT.Value.DataString; } if (pin.IsOnline == true && commandResponse.GOC_DECISION.Value == OfflineTransactionStatus.RequiresAuthorization) { // If it's an online transaction, that is, needs pin and ksn emv validation: pin.PinBlock = commandResponse.GOC_PINBLK.Value.DataString; pin.KeySerialNumber = commandResponse.GOC_KSN.Value.DataString; } // Returns read pin block. return(status); }