コード例 #1
0
        public bool VoidTransaction(string operationID, out string errorText)
        {
            errorText = null;

            ActiveXConnectAPI api = GetAPI();

            if (api == null)
            {
                errorText = "Failed to load API library...";
                return(false);
            }

            ConsoleGui.Info($"Voiding [{operationID}]...");
            api.Void(operationID);
            ConsoleGui.Info($"Waiting OnVoidResult...");
            if (!ProcessEventsUntil(api, "OnVoidResult", 100))
            {
                errorText = "Timeout waiting for OnVoidResult";
                return(false);
            }

            if (api.OperationResult != "OK")
            {
                errorText = api.Text;
                return(false);
            }

            return(true);
        }
コード例 #2
0
        private void PerformGetTranState()
        {
            string errorText;

            ConsoleGui.Info($"\n*** GETTRANSTATE");
            var selectedObjects = PickTransaction(
                Prompt: "Select transaction",
                ShowClosedDocs: true,
                PreAuthOnly: true
                );

            var document    = selectedObjects.SelectedDocument;
            var transaction = selectedObjects.SelectedTransaction;

            if (transaction == null)
            {
                ConsoleGui.Warning("No transaction selected");
                return;
            }

            ConsoleGui.Info($"Selected {document.DocumentNr} (Amount:{transaction.AmountAuthorized} OperationId:{transaction.OperationID})");
            ConsoleGui.Info($"Calling GetTranState method...");
            if (API.GetTranState(transaction.OperationID, transaction.Cryptogram, out errorText, out var state, out var resultCryptogram))
            {
                if (!"Undefined".Equals(state))
                {
                    transaction.State = state;
                }
                transaction.Cryptogram = resultCryptogram;
                DocumentManager.SaveDocumentToFile(document);

                ConsoleGui.Ok($"Transaction state: {state}");
            }
コード例 #3
0
        public bool CloseDay(string operatorID, string operatorName)
        {
            ActiveXConnectAPI api = GetAPI();

            if (api == null)
            {
                return(false);
            }

            if (!UnlockDevice("999", "John", "", 0, ""))
            {
                ConsoleGui.Error("Failed to unlock device");
                return(false);
            }

            ConsoleGui.Info("CloseDay method called");
            api.CloseDay(operatorID, operatorName);

            if (!ProcessEventsUntil(api, "OnCloseDayResult", 130))
            {
                return(false);
            }

            string result = api.OperationResult;

            ConsoleGui.Info($"OnCloseDayResult received with result={result}");
            return(result == "OK");
        }
コード例 #4
0
 public static void SetWorkingPath(string Path)
 {
     if (!System.IO.Directory.Exists(Path))
     {
         throw new Exception($"Direcotry not exist [{Path}]");
     }
     WorkingDir = Path;
     ConsoleGui.Info($"Using dir [{WorkingDir}]");
 }
コード例 #5
0
        /*
         * void PreIncrement(long Amount, string OperationID, Array Cryptogram);
         * void PreComplete(long Amount, string OperationID, Array Cryptogram);
         * void GetTranState(string DocumentNr, string OperationID, Array Cryptogram);
         */
        public long PreIncrement(
            long NewAmount,
            string CurrencyCode,
            string OperationId,
            byte[] Cryptogram,
            out string NewState,
            out byte[] NewCryptogram,
            out string errorText)
        {
            errorText     = null;
            NewState      = null;
            NewCryptogram = null;

            var api = GetAPI();

            if (api == null)
            {
                errorText = "Failed to load API library";
                return(0);
            }

            // No Card needed for PreIncrement
            //var IsCardValid = WaitForCard(
            //    api: api,
            //    requiredFlag: "AllowPreauthorize",
            //    ExpectedCardCurrency: CurrencyCode,
            //    lastFourDigits: out var lastFourDigits,
            //    errorText: out errorText);
            //if (!IsCardValid) return 0;

            api.PreIncrement(NewAmount, OperationId, Cryptogram);
            ConsoleGui.Info($"PreIncrement() method called");

            var IsTranStateReceived = WaitTranState(api, null, OperationId, Cryptogram, out errorText);

            if (!IsTranStateReceived)
            {
                return(0);
            }

            var operationResult = api.OperationResult;

            if (operationResult != "OK")
            {
                errorText = api.Text;
                // if (string.IsNullOrEmpty(errorText)) errorText = $"operationResult={operationResult}";
                return(0);
            }

            NewState      = api.State;
            NewCryptogram = api.Cryptogram.ToBytes();

            // TODO: validation

            return(api.AmountAuthorized);
        }
コード例 #6
0
 static void Main(string[] args)
 {
     try
     {
         Console.WriteLine("ECR implementation example v2.0");
         ReadCliArgs(args);
         new ECR().Run();
     }
     catch (Exception ex)
     {
         ConsoleGui.Error(ex.ToString());
         Console.WriteLine("Press enter to exit...");
         Console.ReadLine();
     }
 }
コード例 #7
0
        private void PerformVoidPartial()
        {
            ConsoleGui.Info($"\n*** PARTIALVOID");
            var selectedItem = PickTransaction(
                Prompt: "Select transaction to be voided"
                );

            var transaction = selectedItem.SelectedTransaction;
            var document    = selectedItem.SelectedDocument;

            if (transaction == null)
            {
                ConsoleGui.Warning("No transaction selected");
                return;
            }

            var voidAmount = ConsoleGui.EnterValue <long>("Enter amount to be voided");

            if (!API.UnlockDevice("999", "John", "VOID", 0, ""))
            {
                ConsoleGui.Error("Failed to unlock device. Void will not be performed");
                return;
            }

            string errorText;

            if (API.VoidPartialTransaction(transaction.OperationID, transaction.AmountAuthorized, voidAmount, out errorText))
            {
                if (transaction.AmountAuthorized == voidAmount)
                {
                    transaction.IsVoided     = true;
                    transaction.AmountVoided = transaction.AmountAuthorized;
                }
                else
                {
                    transaction.AmountAuthorized -= voidAmount;
                    transaction.AmountVoided     += voidAmount;
                }

                DocumentManager.SaveDocumentToFile(document);

                ConsoleGui.Ok("Transaction was voided");
            }
            else
            {
                ConsoleGui.Error($"Failed to void transaction: {errorText}");
            }
        }
コード例 #8
0
        bool WaitForCard(
            ActiveXConnectAPI api,
            string requiredFlag,
            string ExpectedCardCurrency,
            out string lastFourDigits,
            out string errorText)
        {
            errorText      = null;
            lastFourDigits = null;

            ConsoleGui.Info("*** Please insert card");
            while (true)
            {
                if (!ProcessEventsUntil(api, "OnCard", 30))
                {
                    errorText = "Timeout waiting for card to be inserted into device";
                    return(false);
                }

                if (ContainsFlag(api.Flags, requiredFlag))
                {
                    ConsoleGui.Ok("CARD is payment card");
                    break;
                }
                else
                {
                    ConsoleGui.Warning("Not payment card. Probably it's loyalty/discount card, so calculate discount/loyalty points here... and wait for next CARD event");
                }
            }

            if (api.CurrencyCode != ExpectedCardCurrency)
            {
                errorText = $"Currency mismatch. Expecting:{ExpectedCardCurrency} reveiced:[{api.CurrencyCode}]";
                return(false);
            }

            if (ContainsFlag(api.Flags, "ReqLastFourDigits"))
            {
                lastFourDigits = ConsoleGui.EnterValue <string>("Please enter last 4 digits of the card");
            }

            return(true);
        }
コード例 #9
0
        public bool CloseDocument(Document document)
        {
            ConsoleGui.Info($"Closing document {document.DocumentNr}");

            ActiveXConnectAPI api = GetAPI();

            if (api == null)
            {
                return(false);
            }

            var operationIdList = new List <string>();

            if (document.Transactions != null)
            {
                foreach (var i in document.Transactions)
                {
                    operationIdList.Add(i.OperationID);
                }
            }

            ConsoleGui.Info("Calling DocClosed() method...");
            api.DocClosed(document.DocumentNr, operationIdList.ToArray());

            if (!ProcessEventsUntil(api, "OnDocClosedResult", 15))
            {
                return(false);
            }

            string result = api.OperationResult;

            if (result == "OK")
            {
                ConsoleGui.Ok($"OnDocClosedResult event received with OperationResult:{result}");
            }
            else
            {
                ConsoleGui.Error($"OnDocClosedResult event received with OperationResult:{result}");
            }

            return(result == "OK");
        }
コード例 #10
0
        bool WaitTranState(ActiveXConnectAPI api, string DocumentNr, string OperationID, byte[] Cryptogram, out string errorText)
        {
            const int TIMEOUT_SECONDS = 100;

            errorText = null;

            if (!ProcessEventsUntil(api, "OnTranState", TIMEOUT_SECONDS))
            {
                ConsoleGui.Error("Timeout waiting for OnTranState, trying to perform GetTranState by DocumentNr...");

                ConsoleGui.Info("Calling GetTranState method...");
                api.GetTranState(DocumentNr, OperationID, Cryptogram);

                if (!ProcessEventsUntil(api, "OnTranState", TIMEOUT_SECONDS))
                {
                    errorText = "Timeout waiting for OnTranState";
                    return(false);
                }
            }
            ConsoleGui.Ok("OnTranState received");
            return(true);
        }
コード例 #11
0
        private void GsmPurchase()
        {
            var doc = new Document();

            // It is very important that we "save" document even before we try any GSM operation.
            // This way we can guarantee that docclosed will be sent even if computer power is lost / application crashes or some other fatal error occurs.
            DocumentManager.SaveDocumentToFile(doc);

            string errorText;

            string data = ConsoleGui.EnterValue <string>("Enter GSM barcode to be queried");

            if (API.GsmPurchase(out errorText, data, doc) <= 0)
            {
                ConsoleGui.Error("GSM purchase failed: " + errorText);
            }
            else
            {
                ConsoleGui.Ok("GSM purchase succeeded");
            }

            AttemptToCloseUnclosedDocuments();
        }
コード例 #12
0
        private void PerformVoid()
        {
            ConsoleGui.Info($"\n*** VOID");
            var selectedItem = PickTransaction(
                Prompt: "Select transaction"
                );

            var document    = selectedItem.SelectedDocument;
            var transaction = selectedItem.SelectedTransaction;

            if (transaction == null)
            {
                ConsoleGui.Warning("No transaction selected");
                return;
            }

            if (!API.UnlockDevice("999", "John", "VOID", 0, ""))
            {
                ConsoleGui.Error("Failed to unlock device. Void will not be performed");
                return;
            }

            string errorText;

            if (API.VoidTransaction(transaction.OperationID, out errorText))
            {
                transaction.IsVoided = true;
                DocumentManager.SaveDocumentToFile(document);

                ConsoleGui.Ok("Transaction was voided");
            }
            else
            {
                ConsoleGui.Error($"Failed to void transaction. {errorText}");
            }
        }
コード例 #13
0
        /// <summary>
        /// Processes events until event of expected type is received.
        /// </summary>
        /// <param name="api">COM object</param>
        /// <param name="expectedEventType">Event type to wait for. When this event is received method returns true</param>
        /// <param name="timeoutInSeconds">Timeout in seconds to wait for expected event</param>
        /// <returns>True if expected event was received before timeout. Otherwise returns false.</returns>
        private bool ProcessEventsUntil(ActiveXConnectAPI api, string expectedEventType, int timeoutInSeconds)
        {
            ConsoleGui.Info($"Waiting for [{expectedEventType}] event...");

            Stopwatch sw = Stopwatch.StartNew();

            api.PollEvent(200);

            string ev = api.EventType;

            while (ev != expectedEventType)
            {
                switch (ev)
                {
                case "OnPrompt":
                {
                    Console.WriteLine(api.PromptText);
                    string input = Console.ReadLine();

                    api.Input(input);
                    if (!ProcessEventsUntil(api, "OnInputResult", 15))
                    {
                        return(false);
                    }

                    if (api.OperationResult != "OK")
                    {
                        return(false);
                    }
                }
                break;

                case "OnPrint":
                {
                    api.GetNextReceipt();
                    while (!String.IsNullOrEmpty(api.ReceiptText))
                    {
                        Console.WriteLine("Printing received receipt:");
                        Console.WriteLine("ReceiptIsClientData: {0}", api.ReceiptIsClientData);
                        Console.WriteLine("ReceiptIsMerchantCopy: {0}", api.ReceiptIsMerchantCopy);
                        Console.WriteLine("Document nr: {0}", api.ReceiptDocumentNr);

                        Console.WriteLine("--------------------------");
                        Console.WriteLine(api.ReceiptText);
                        Console.WriteLine("--------------------------");

                        api.GetNextReceipt();
                    }
                }
                break;

                case "OnSelect":
                {
                    Console.WriteLine(api.Text);

                    string input = Console.ReadLine();
                    api.Input(input);
                    if (!ProcessEventsUntil(api, "OnInputResult", 15))
                    {
                        return(false);
                    }

                    if (api.OperationResult != "OK")
                    {
                        return(false);
                    }
                }
                break;

                case "OnDisplayText":
                {
                    Console.WriteLine("--------------");
                    Console.WriteLine(api.DisplayText);
                    Console.WriteLine("--------------");
                }
                break;

                case "OnMessageBox":
                {
                    Console.WriteLine("-----------------");
                    Console.WriteLine(api.MessageBoxText);
                    Console.WriteLine("-----------------");

                    string[] validButtons = null;
                    switch (api.MessageBoxType)
                    {
                    case "Ok":
                        validButtons = new[] { "Ok" };
                        break;

                    case "YesNo":
                        validButtons = new[] { "Yes", "No" };
                        break;

                    case "OkCancel":
                        validButtons = new[] { "Ok", "Cancel" };
                        break;

                    case "YesNoCancel":
                        validButtons = new[] { "Yes", "No", "Cancel" };
                        break;
                    }

                    Console.WriteLine("Please choose on of following buttons:");
                    for (int i = 0; i < validButtons.Length; i++)
                    {
                        Console.WriteLine("{0} {1}", i + 1, validButtons[i]);
                    }

                    int index;
                    if (!Int32.TryParse(Console.ReadLine(), out index))
                    {
                        Console.WriteLine("You must enter a number from the list above");
                        return(false);
                    }
                    index--;
                    if (index < 0 || index >= validButtons.Length)
                    {
                        Console.WriteLine("You must enter a number from the list above");
                        return(false);
                    }
                    else
                    {
                        api.Click(validButtons[index]);
                        ProcessEventsUntil(api, "OnClickResult", 15);
                    }
                }
                break;

                case "OnTranState":
                    Console.WriteLine("--------------");
                    Console.WriteLine(api.Text);
                    Console.WriteLine("--------------");
                    break;

                default:
                {
                    if (!String.IsNullOrEmpty(ev))
                    {
                        ConsoleGui.Warning($"Ignoring event:[{ev}]");         //   OperationResult:[{api?.OperationResult}]
                    }
                }
                break;
                }

                if (sw.ElapsedMilliseconds > timeoutInSeconds * 1000)
                {
                    ConsoleGui.Warning($"Waiting for [{expectedEventType}] timed-out.");
                    return(false);
                }

                api.PollEvent((int)(timeoutInSeconds * 1000 - sw.ElapsedMilliseconds));
                ev = api.EventType;
            }

            return(true);
        }
コード例 #14
0
        public long PreAuthorize(
            long amount,
            string documentNr,
            string currencyCode,
            out string errorText,
            out string operationID,
            out string state,
            out byte[] cryptogram)
        {
            errorText   = null;
            operationID = null;
            cryptogram  = null;
            state       = null;

            var api = GetAPI();

            if (api == null)
            {
                errorText = "Failed to load API library";
                return(0);
            }


            var IsCardValid = WaitForCard(
                api: api,
                requiredFlag: "AllowPreauthorize",
                ExpectedCardCurrency: currencyCode,
                lastFourDigits: out var lastFourDigits,
                errorText: out errorText);

            if (!IsCardValid)
            {
                return(0);
            }

            api.PreAuthorize(amount, documentNr, lastFourDigits);
            ConsoleGui.Info("PreAuthorize method called");

            var IsTranStateReceived = WaitTranState(api, documentNr, null, null, out errorText);

            if (!IsTranStateReceived)
            {
                return(0);
            }

            if (api.DocumentNr != documentNr)
            {
                errorText = String.Format($"DocumentNr mismatch. Expecting:[{documentNr}] received:[{api.DocumentNr}]");
                return(0);
            }

            ConsoleGui.Info($"State:[{api.State}] CryptLenght:[{api.Cryptogram?.Length}]");

            if (api.OperationResult != "OK")
            {
                errorText = api.Text;
                return(0);
            }

            operationID = api.OperationID;
            state       = api.State;
            cryptogram  = api.Cryptogram.ToBytes();

            if (api.AmountAuthorized == 0)
            {
                errorText = "PreAuthorization declined";
            }

            return(api.AmountAuthorized);
        }
コード例 #15
0
        public long Authorize(long amount, string documentNr, string currencyCode, out string errorText, out string operationID)
        {
            errorText   = null;
            operationID = null;

            ActiveXConnectAPI a = GetAPI();

            if (a == null)
            {
                errorText = "Failed to load API library";
                return(0);
            }

            ConsoleGui.Info("*** Please insert card");
            while (true)
            {
                if (!ProcessEventsUntil(a, "OnCard", 30))
                {
                    errorText = "Timeout waiting for card to be inserted into device";
                    return(0);
                }

                if (ContainsFlag(a.Flags, "AllowAuthorize"))
                {
                    ConsoleGui.Ok("CARD is payment card");
                    break;
                }
                else
                {
                    ConsoleGui.Warning("This is not payment card, most probably it's loyalty/discount card, so calculate discount/loyalty points here... and wait for next CARD event");
                }
            }

            if (a.CurrencyCode != currencyCode)
            {
                errorText = String.Format("Currency '{0}' code is not supported", a.CurrencyCode);
                return(0);
            }

            string lastFourDigits = null;

            if (ContainsFlag(a.Flags, "ReqLastFourDigits"))
            {
                lastFourDigits = ConsoleGui.EnterValue <string>("Please enter last 4 digits of the card");
            }

            ConsoleGui.Info("calling Authorize() method...");
            a.Authorize(amount, 0, documentNr, lastFourDigits);

            if (!ProcessEventsUntil(a, "OnAuthorizeResult", 100))
            {
                errorText = "Timeout waiting for OnAuthorizeResult";
                return(0);
            }

            if (a.OperationResult != "OK")
            {
                errorText = a.Text;
                return(0);
            }

            operationID = a.OperationID;

            if (a.AmountAuthorized == 0)
            {
                errorText = "Authorization declined";
            }

            return(a.AmountAuthorized);
        }
コード例 #16
0
        public void Run()
        {
            var choice = "";

            while (true)
            {
                Console.WriteLine();
                Console.WriteLine("---------------------------");
                Console.WriteLine("    Main Menu");
                Console.WriteLine("---------------------------");
                Console.WriteLine(" 1. New tender");
                Console.WriteLine(" 2. Void transaction");
                Console.WriteLine(" 3. Close day");
                Console.WriteLine(" 4. GSM purchase");
                Console.WriteLine(" 5. Partial void");
                Console.WriteLine(" 6. PreAuthorization");
                Console.WriteLine(" 7. Increment PreAuthorization");
                Console.WriteLine(" 8. Complete PreAuthorization");
                Console.WriteLine(" 9. Get PreAuthorization state");
                Console.WriteLine(" X. Exit");
                Console.WriteLine("");

                choice = ConsoleGui.EnterValue <string>("Select a task").ToUpper();
                switch (choice)
                {
                case "Q":
                case "X":
                case "QUIT":
                case "EXIT":
                    return;

                case "1":
                {
                    NewTender();

                    ConsoleGui.Info("Trying to close document that was used for tender...");
                    bool result = AttemptToCloseUnclosedDocuments();
                    // we ignore result because it will not be error if it fails because
                    // document will be closed after next purchase or before close day
                }
                break;

                case "2":
                    PerformVoid();
                    break;

                case "3":
                    CloseDay();
                    break;

                case "4":
                    GsmPurchase();
                    break;

                case "5":
                    PerformVoidPartial();
                    break;

                case "6":
                    NewTenderPreAuthorize();
                    break;

                case "7":
                    PreIncrementGui();
                    break;

                case "8":
                    PreCompleteGui();
                    break;

                case "9":
                    PerformGetTranState();
                    break;

                case "LIST DOC":
                    PickDocuments();
                    break;


                case "LIST DOC ALL":
                    PickDocuments(ShowCloseds: true);
                    break;

                case "LIST":
                case "LIST TRAN":
                {
                    PickTransaction(ShowClosedDocs: true, ShowVoidedTrans: true);
                    break;
                }

                case "?":
                case "H":
                case "HELP":
                    Help();
                    break;

                default:
                    ConsoleGui.Warning("Unknown option");
                    break;
                }
            }
        }