private static void FillReceipts(TransactionState transactionState, IReceiptResponse response, bool reversalReceipts) { try { StringBuilder clientReceipt = new StringBuilder(); StringBuilder merchantReceipt = new StringBuilder(); foreach (Receipt receipt in transactionState.Receipts.Where(r => r.IsReversalReceipt == reversalReceipts)) { if (receipt.Flags.IsFlagSet("SGN")) response.NeedClientSignature = true; if (receipt.Flags.IsFlagSet("MC")) merchantReceipt.Append(receipt.Text); else clientReceipt.Append(receipt.Text); } response.ClientReceipt = clientReceipt.ToString(); response.MerchantReceipt = merchantReceipt.ToString(); } catch (Exception ex) { Log.Error(ex); } }
private TransactionState GetTransactionState(string documentNumber, bool createNewIfNotExists) { lock (_transactions) { #region Try to get exitsing TransactionState state; if (!string.IsNullOrEmpty(documentNumber)) { if (_transactions.TryGetValue(documentNumber, out state)) return state; } #endregion if (!createNewIfNotExists) return null; #region Create new DateTime time = DateTime.Now; documentNumber = string.IsNullOrEmpty(documentNumber) ? string.Concat("Num", time.ToString("yyyyMMddHHmmss")) : documentNumber; using ((state = new TransactionState()).CreateAutoSaveContext()) { state.Time = time; state.Language = _languageCode; state.DocumentNumber = documentNumber; } _transactions[state.DocumentNumber] = state; return state; #endregion } }
private async Task ProcessReversal(TransactionState transactionState) { using (transactionState.CreateAutoSaveContext()) { transactionState.State = TransactionStates.Reversing; transactionState.InformationText = Language.Get("reversed", transactionState.Language); _pedEvents.Clear(); DocClosedRequest docClosed = DocClosedRequest.Create(transactionState.DocumentNumber, null); _pedHub.SendData(PedId, AsyncPosPacket.PrependLength(docClosed.Serialize(_apak, PedId))); if (await _pedEvents.WaitOneAsync(AsyncPosEventTypes.Ack.ToString(), AckTimeout) == null) throw new AsyncPosException(Language.Get("no_response", transactionState.Language)); transactionState.State = TransactionStates.Reversed; Stopwatch sw = new Stopwatch(); sw.Start(); while (sw.Elapsed.TotalMilliseconds < ReversalReceiptTimeout) { var eventData = await _pedEvents.WaitOneAsync(AsyncPosEventTypes.PrintReceipt.ToString(), ReversalReceiptTimeout - (int)sw.Elapsed.TotalSeconds); if (eventData == null) continue; PrintReceipt printReceipt = PrintReceipt.Deserialize(eventData.Value); if (printReceipt.DocumentNumber != transactionState.DocumentNumber) continue; Receipt rcpt = new Receipt { Id = printReceipt.ReceiptId, Text = printReceipt.ReceiptText, Flags = printReceipt.Flags, IsReversalReceipt = true, }; transactionState.Receipts.Add(rcpt); if (printReceipt.Flags.IsFlagSet("LR")) break; } } }
private async Task ProcessAdjust(TransactionState transactionState, long newAmount) { using (transactionState.CreateAutoSaveContext()) { AdjustRequest adjustRequest = AdjustRequest.Create(transactionState.DocumentNumber, newAmount, transactionState.AuthorizationId); _pedEvents.Clear(); _pedHub.SendData(PedId, AsyncPosPacket.PrependLength(adjustRequest.Serialize(_apak, PedId))); transactionState.Receipts.Clear(); Stopwatch sw = new Stopwatch(); sw.Start(); while (sw.Elapsed.TotalMilliseconds < AuthorizationTimeout) { var eventData = await _pedEvents.WaitAnyAsync(new[] { AsyncPosEventTypes.AdjustResult.ToString(), AsyncPosEventTypes.PrintReceipt.ToString(), }, AuthorizationTimeout - (int)sw.Elapsed.TotalMilliseconds); if (eventData == null) continue; switch ((AsyncPosEventTypes)Enum.Parse(typeof(AsyncPosEventTypes), eventData.Id, true)) { case AsyncPosEventTypes.AdjustResult: { AdjustResponse result = AdjustResponse.Deserialize(eventData.Value); if (result.DocumentNumber != transactionState.DocumentNumber) break; if (!result.Approved) throw new AsyncPosException(Language.Get("cannot_confirm_partial_trans_error", transactionState.Language)); transactionState.Amount = newAmount; return; } case AsyncPosEventTypes.PrintReceipt: { PrintReceipt printReceipt = PrintReceipt.Deserialize(eventData.Value); if (printReceipt.DocumentNumber != transactionState.DocumentNumber) break; transactionState.Receipts.Add(new Receipt { Id = printReceipt.ReceiptId, Text = printReceipt.ReceiptText, Flags = printReceipt.Flags }); break; } } } throw new AsyncPosException(Language.Get("no_response", transactionState.Language)); } }
private async Task ProcessConfirm(TransactionState transactionState) { using (transactionState.CreateAutoSaveContext()) { transactionState.State = TransactionStates.Confirming; DocClosedRequest docClosed = DocClosedRequest.Create(transactionState.DocumentNumber, transactionState.AuthorizationId); _pedEvents.Clear(); _pedHub.SendData(PedId, AsyncPosPacket.PrependLength(docClosed.Serialize(_apak, PedId))); var result = await _pedEvents.WaitOneAsync(AsyncPosEventTypes.Ack.ToString(), AckTimeout); if (result == null) throw new AsyncPosException(Language.Get("no_response", transactionState.Language)); transactionState.State = TransactionStates.Confirmed; } }
private async Task ProcessAuthorization(TransactionState transactionState) { transactionState.State = TransactionStates.Authorizing; AuthorizationRequest authRequest = AuthorizationRequest.Create(transactionState.DocumentNumber, transactionState.Amount, transactionState.Cash, transactionState.CardToken, transactionState.Time, transactionState.Currency, transactionState.Language, transactionState.PreAuthorize); _pedEvents.Clear(); _pedHub.SendData(PedId, AsyncPosPacket.PrependLength(authRequest.Serialize(_apak, PedId))); Stopwatch sw = new Stopwatch(); sw.Start(); while (sw.Elapsed.TotalMilliseconds < AuthorizationTimeout) { var eventData = await _pedEvents.WaitAnyAsync(new[] { AsyncPosEventTypes.DocClosed.ToString(), AsyncPosEventTypes.AuthorizationStarted.ToString(), AsyncPosEventTypes.AuthorizationResult.ToString(), AsyncPosEventTypes.DisplayText.ToString(), AsyncPosEventTypes.GetPromptInput.ToString(), AsyncPosEventTypes.PrintReceipt.ToString(), }, AuthorizationTimeout - (int)sw.Elapsed.TotalMilliseconds); if (eventData == null) continue; switch ((AsyncPosEventTypes)Enum.Parse(typeof(AsyncPosEventTypes), eventData.Id, true)) { case AsyncPosEventTypes.GetPromptInput: { GetPromptInput prompt = GetPromptInput.Deserialize(eventData.Value); if (prompt.Rerason != GetPromptInput.PromptReasons.Last4Digits) throw new NotSupportedException("Not supported GetPromptInput request"); await SendLast4Digits(transactionState.DocumentNumber, transactionState.Last4CardNumberDigits); sw.Reset(); sw.Start(); break; } case AsyncPosEventTypes.DisplayText: { DisplayText displayText = DisplayText.Deserialize(eventData.Value); if (displayText.Reason == DisplayText.DisplayTextReasons.TimeoutWaiting) { sw.Reset(); sw.Start(); } break; } case AsyncPosEventTypes.AuthorizationResult: { AuthorizationResponse result = AuthorizationResponse.Deserialize(eventData.Value); if (result.DocumentNumber != transactionState.DocumentNumber) break; transactionState.State = result.Approved ? TransactionStates.Approved : TransactionStates.Declined; transactionState.InformationText = result.Text; transactionState.Rrn = result.Rrn; transactionState.Stan = result.Stan; transactionState.Amount = result.Amount < transactionState.Amount ? result.Amount : transactionState.Amount; transactionState.AuthorizationCode = result.AuthorizationCode; transactionState.AuthorizationId = result.AuthorizationId; transactionState.CardType = result.CardType; return; } case AsyncPosEventTypes.PrintReceipt: { PrintReceipt printReceipt = PrintReceipt.Deserialize(eventData.Value); if (printReceipt.DocumentNumber != transactionState.DocumentNumber) break; transactionState.Receipts.Add(new Receipt { Id = printReceipt.ReceiptId, Text = printReceipt.ReceiptText, Flags = printReceipt.Flags }); break; } case AsyncPosEventTypes.DocClosed: { DocClosedRequest docClosed = DocClosedRequest.Deserialize(eventData.Value); if (docClosed.DocumentNumber != transactionState.DocumentNumber) break; throw new AsyncPosException(Language.Get("cancelled", transactionState.Language)); } } } throw new AsyncPosException(Language.Get("no_response", transactionState.Language)); }
private async Task GetCardToken(TransactionState transactionState) { string cardToken = await GetOldCardToken(transactionState.Time); if (!string.IsNullOrEmpty(cardToken)) { transactionState.CardToken = cardToken; return; } DisplayText displayText = DisplayText.Create(Language.Get("insert_card", transactionState.Language), DisplayText.DisplayTextReasons.CardWaiting, DisplayText.BeepTypes.SingleLong); _pedHub.SendData(PedId, AsyncPosPacket.PrependLength(displayText.Serialize(_apak, PedId))); var result = await _pedEvents.WaitAnyAsync(new[] { AsyncPosEventTypes.DocClosed.ToString(), AsyncPosEventTypes.CardReader.ToString() }, CardWaitTimeout); if (result == null) throw new AsyncPosException(Language.Get("card_timeout", transactionState.Language)); if (result.Id == AsyncPosEventTypes.DocClosed.ToString()) throw new AsyncPosException(Language.Get("cancelled", transactionState.Language)); CardReader cardReader = CardReader.Deserialize(result.Value); if (string.IsNullOrEmpty(cardReader.Token)) throw new AsyncPosException(Language.Get("card_timeout", transactionState.Language)); transactionState.CardToken = cardReader.Token; }