/// <summary> /// Creates and sends a FNC to the pinpad. This command ends an authorization process on EMV module. /// </summary> /// <param name="issuerEmvData">EMV script to be send to the card.</param> /// <returns>FNC command status.</returns> public AbecsResponseStatus FinishTransaction(IssuerEmvDataEntry issuerEmvData) { FncRequest fnc = new FncRequest(); fnc.FNC_COMMST.Value = issuerEmvData.AuthorizationStatus; fnc.FNC_ISSMODE.Value = 0; fnc.FNC_ARC.Value = issuerEmvData.AuthorizationResponseCode; if (string.IsNullOrEmpty(issuerEmvData.IssuerRelatedData) == false && issuerEmvData.AuthorizationStatus != AcquirerCommunicationStatus.ConnectionError) { fnc.FNC_ISSDAT.Value = new HexadecimalData(issuerEmvData.IssuerRelatedData); fnc.FNC_TAGS.Value = new HexadecimalData(EmvTag.GetEmvTagsRequired()); } else { fnc.FNC_ISSDAT.Value = new HexadecimalData(""); fnc.FNC_TAGS.Value = new HexadecimalData(""); } return(this.pinpadCommunication.SendRequestAndReceiveResponse <FncResponse>(fnc).RSP_STAT.Value); }
// 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); }
private static EmvTag Parse(ref byte[] data, ref int offset) { // `start` and `i` represent cursors along our TLV data. We will move start // along until we find the start byte of our tag, length, or value. then // we will move i along until we find the end of it. Using their positions // we then extract that data, and push them forward one step to look for our // next tag, length, or value. // rawTlv: PPTTLLLVVVVVVVVPP // start: ^ // i: ^ for (int i = offset, start = offset; i < data.Length; start = i) { // 0x00 can be used as padding before, between, and after tags if (IsNullByte(rawTlv[i])) { i++; continue; } // RETRIEVE TAG if (IsMultiByteTag(rawTlv[i])) { while (!IsLastTagByte(rawTlv[++i])) { ; } } int lengthOfTag = (i - start) + 1; byte[] tag = new byte[lengthOfTag]; Array.Copy(rawTlv, start, tag, 0, lengthOfTag); start = ++i; // RETRIEVE LENGTH if (IsMultiByteLength(rawTlv[i])) { start++; i += rawTlv[i] - 0x80; } int lengthOfLength = (i - start) + 1; byte[] length = new byte[lengthOfLength]; Array.Copy(rawTlv, start, length, 0, lengthOfLength); start = ++i; // RETRIEVE VALUE int lengthOfValue = GetInt(length, 0, length.Length); byte[] value = new byte[lengthOfValue]; Array.Copy(rawTlv, start, value, 0, lengthOfValue); start = (i += lengthOfValue); // build the tag! var tlv = new EmvTag(tag, length, value); result.Add(tlv); // if this was a constructed tag, parse its value into individual Tlv children as well if (IsConstructedTag(tag[0])) { Parse(tlv.Value, tlv.Children); } }