// Methods
        /// <summary>
        /// Read security information when card has no chip - magnetic stripe only.
        /// </summary>
        /// <param name="pinpadCommunication">Pinpad communication, through which c</param>
        /// <param name="pan">Primary Account Number printed on the card.</param>
        /// <param name="amount">Transaction amount.</param>
        /// <param name="pin">Pin read.</param>
        /// <returns>Wheter is an online transaction or not.</returns>
        /// <exception cref="System.InvalidOperationException">Thrown when parameter validation fails.</exception>
        internal ResponseStatus Read(IPinpadCommunication pinpadCommunication, string pan, decimal amount, out Pin pin)
        {
            pin = null;

            // Validating data
            try { this.Validate(pinpadCommunication, amount, pan); }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Error while trying to read security info using magnetic stripe. Verify inner exception.", ex);
            }

            // Using ABECS GPN command to get pin block & KSN.
            GpnResponse response = this.SendGpn(pinpadCommunication, pan, amount);

            // Saving command response status:
            AbecsResponseStatus legacyStatus = response.RSP_STAT.Value;
            ResponseStatus      status       = ResponseStatusMapper.MapLegacyResponseStatus(legacyStatus);

            if (status == ResponseStatus.Ok)
            {
                // Magnetic stripe always validates pin online.
                pin                 = new Pin();
                pin.PinBlock        = response.GPN_PINBLK.Value.DataString;
                pin.KeySerialNumber = response.GPN_KSN.Value.DataString;
                pin.IsOnline        = true;
            }

            pin.ApplicationCryptogram = null;

            return(status);
        }
示例#2
0
 // Validation
 /// <summary>
 /// Validates parameters sent to the constructor.
 /// </summary>
 /// <exception cref="System.ArgumentNullException">When one parameter is null.</exception>
 /// <exception cref="System.ArgumentException">When one parameter is not null, but contains invalid data.</exception>
 private void Validate(IPinpadCommunication pinpadFacade)
 {
     if (pinpadFacade == null)
     {
         throw new ArgumentNullException("pinpadCommunication");
     }
 }
        /// <summary>
        /// Sends reading command using ABECS in case of a magnetic stripe card.
        /// Unexpected behavior if amount is too large (over quadrillion).
        /// </summary>
        /// <param name="pinpadCommunication"></param>
        /// <param name="pan">Primary Account Number printed on the card.</param>
        /// <param name="amount">Transaction amount.</param>
        /// <returns>ABECS GPN command response.</returns>
        private GpnResponse SendGpn(IPinpadCommunication pinpadCommunication, string pan, decimal amount)
        {
            GpnRequest request = new GpnRequest();

            // Assembling GPN command.
            request.GPN_METHOD.Value = new CryptographyMethod(KeyManagementMode.DerivedUniqueKeyPerTransaction,
                                                              CryptographyMode.TripleDataEncryptionStandard);
            request.GPN_KEYIDX.Value = (int)StoneIndexCode.EncryptionKey;
            request.GPN_WKENC.Value  = new HexadecimalData("");
            request.GPN_PAN.Value    = pan;

            // Assembling GPN mandatory entries to GPN command.
            GpnPinEntryRequest pinEntry = new GpnPinEntryRequest();

            pinEntry.GPN_MIN.Value            = PinReader.PASSWORD_MINIMUM_LENGTH;
            pinEntry.GPN_MAX.Value            = PinReader.PASSWORD_MAXIMUM_LENGTH;
            pinEntry.GPN_MSG.Value.Padding    = DisplayPaddingType.Left;
            pinEntry.GPN_MSG.Value.FirstLine  = this.GetAmountLabel(amount);
            pinEntry.GPN_MSG.Value.SecondLine = PASSWORD_LABEL;

            // Adds the entry to list of entries supported by a GPN command.
            request.GPN_ENTRIES.Value.Add(pinEntry);

            GpnResponse response = pinpadCommunication.SendRequestAndReceiveResponse <GpnResponse>(request);

            return(response);
        }
示例#4
0
        // Constructor:
        /// <summary>
        /// Creates a pinpad table adapter.
        /// </summary>
        /// <param name="pinpadCommunication">Pinpad communication, through which is possible to communicate with the pinpad.</param>
        public PinpadTable(IPinpadCommunication pinpadCommunication)
        {
            if (pinpadCommunication == null)
            {
                throw new ArgumentNullException("pinpad communication cannot be null.");
            }

            this.PinpadCommunication = pinpadCommunication;
            this.tableCollection     = new List <BaseTable>();
        }
 // Validation
 /// <summary>
 /// Validate all mandatory parameters.
 /// Throws an exception if the parameter is null or invalid.
 /// </summary>
 /// <param name="communication">Pinpad facade, through which pinpad communication are made.</param>
 /// <param name="amount">Transaction amount.</param>
 private void Validate(IPinpadCommunication communication, decimal amount)
 {
     if (communication == null)
     {
         throw new ArgumentNullException("pinpadCommunication cannot be null. Unable to communicate with the pinpad.");
     }
     if (amount <= 0)
     {
         throw new ArgumentException("amount shall be greater than 0.");
     }
 }
示例#6
0
        public void PinpadTable_Construction_ShouldThrowException_IfPinpadCommunicationIsNull()
        {
            // Assert
            Assert.Throws <ArgumentNullException>(() =>
            {
                // Arrange
                IPinpadCommunication nullPinpadCommunication = null;

                // Act
                PinpadTable table = new PinpadTable(nullPinpadCommunication);
            });
        }
        public void PinReader_Read_ShouldThrowException_IfPinpadCommunicationIsNull()
        {
            // Assert
            Assert.Throws <InvalidOperationException>(() =>
            {
                // Arrange
                IPinpadCommunication nullPinpadCommunication = null;

                // Act
                PinReader pinReader = new PinReader(nullPinpadCommunication);
            });
        }
        // ctor:
        /// <summary>
        /// Creates the instance mandatorily with a <see cref="IPinpadInfos"/> and <see cref="IPinpadCommunication"/>.
        /// Otherwise, throws exception.
        /// </summary>
        /// <param name="pinpadInformation">Informations about the device.</param>
        /// <param name="pinpadCommunication">Responsible for sending and receiving commands to and from the
        /// pinpad.</param>
        /// <exception cref="ArgumentException">If any parameters are null.</exception>
        public PinpadUpdateService(IPinpadInfos pinpadInformation, IPinpadCommunication pinpadCommunication)
        {
            if (pinpadInformation == null)
            {
                throw new ArgumentNullException(nameof(pinpadInformation));
            }
            if (pinpadCommunication == null)
            {
                throw new ArgumentNullException(nameof(pinpadInformation));
            }

            this.PinpadInfos         = pinpadInformation;
            this.PinpadCommunication = pinpadCommunication;
        }
示例#9
0
        public void EmvPinReaderTest_Read_should_throw_exception_if_null_PinpadFacade()
        {
            // Assert
            Assert.Throws <ArgumentNullException>(() =>
            {
                // Arrange
                IPinpadCommunication nullPinpadCommunication = null;
                decimal amount = 1001;

                // Act
                this.emvPinReader.Read(nullPinpadCommunication, amount,
                                       out this.dummyPin);
            });
        }
示例#10
0
        // Constructor
        /// <summary>
        /// Reads pinblock and ksn and sets it's value into this class property.
        /// Is up to the user using these infos.
        /// </summary>
        /// <param name="pinpadCommunication">PinpadFacade mandatory to this class be able to communicate with the pinpad.</param>
        /// <exception cref="System.InvalidOperationException">Thrown when one parameter validation fails.</exception>
        internal PinReader(IPinpadCommunication pinpadCommunication)
        {
            try { this.Validate(pinpadCommunication); }
            catch (Exception ex)
            {
                this.CommandStatus = ResponseStatus.InvalidParameter;
                throw new InvalidOperationException("Could not read pinpad security infos. Verify inner exception.", ex);
            }

            this.pinpadCommunication  = pinpadCommunication;
            this.CommandStatus        = ResponseStatus.Ok;
            this.chipReader           = new EmvPinReader();
            this.magneticStripeReader = new MagneticStripePinReader();
        }
示例#11
0
        public void UpdateService_Creation_ShouldThrowException_IfPinpadCommunicationIsNull()
        {
            // Assert
            Assert.Throws <ArgumentNullException>(() =>
            {
                // Arrange
                IPinpadInfos infos        = new Stubs.PinpadInfosStub();
                IPinpadCommunication comm = null;

                // Act and assert
                PinpadUpdateService pinpadUpdateService = new PinpadUpdateService(
                    infos,
                    comm);
            });
        }
        public void MagneticStripePinReader_Read_ShouldThrowException_IfPinpadCommunicationIsNull()
        {
            // Assert
            Assert.Throws <InvalidOperationException>(() =>
            {
                // Arrange
                IPinpadCommunication nullPinpadCommunication = null;

                // Act
                this.emvPinReader.Read(nullPinpadCommunication,
                                       pan: "1234567890123456",
                                       amount: 1000,
                                       pin: out this.dummyPin);
            });
        }
 // Validation
 /// <summary>
 /// Validates parameters used on internal processing.
 /// </summary>
 /// <exception cref="System.ArgumentNullException">When one parameter is null.</exception>
 /// <exception cref="System.ArgumentException">When one parameter is not null, but contains invalid data.</exception>
 private void Validate(IPinpadCommunication pinpadCommunication, decimal amount, string pan)
 {
     if (pinpadCommunication == null)
     {
         throw new ArgumentNullException("pinpadFacade cannot be null. Unable to communicate with the pinpad.");
     }
     if (amount <= 0)
     {
         throw new ArgumentException("amount should be greater than 0.");
     }
     if (pan == null)
     {
         throw new ArgumentNullException("pan");
     }
     if (pan.Length <= 0)
     {
         throw new ArgumentException("pan should not be empty.");
     }
 }
        // 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);
        }
示例#15
0
 /// <summary>
 /// Creates an instance of <see cref="IngenicoPinpadPrinter"/> with all it's properties.
 /// </summary>
 /// <param name="communication">Pinpad communication service.</param>
 /// <param name="infos">Real time pinpad information.</param>
 public IngenicoPinpadPrinter(IPinpadCommunication communication, IPinpadInfos infos)
 {
     this.Communication     = communication;
     this.PinpadInformation = infos;
     this.ItemsToPrint      = new Collection <PrinterItem>();
 }
        // 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);
        }
示例#17
0
 // Constructor
 /// <summary>
 /// Constructor that
 /// </summary>
 /// <param name="pinpadCommunication"></param>
 public PinpadTransaction(IPinpadCommunication pinpadCommunication)
 {
     this.pinReader           = new PinReader(pinpadCommunication);
     this.pinpadCommunication = pinpadCommunication;
     this.EmvTable            = new PinpadTable(pinpadCommunication);
 }
示例#18
0
 public void Setup()
 {
     this.mockedComm        = new Stubs.PinpadCommunicationStub();
     this.dummyPinpadFacade = Mock.Of <IPinpadFacade>();
     this.emvPinReader      = new EmvPinReader();
 }