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); }
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}"); }
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"); }
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}]"); }
/* * 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); }
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(); } }
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}"); } }
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); }
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"); }
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); }
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(); }
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}"); } }
/// <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); }
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); }
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); }
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; } } }