Example #1
0
        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);
            }
        }
Example #2
0
        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
            }
        }
Example #3
0
        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;
                }
            }
        }
Example #4
0
        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));
            }
        }
Example #5
0
        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;
            }
        }
Example #6
0
        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));
        }
Example #7
0
        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;
        }