public void QRCodeTransfer(string json)
        {
            QRCodeTransferTransaction tx = QRCodeTransferTransaction.FromJsonString(json);

            if (tx.Amount == 0)
            {
                throw new ValidationException("Invalid Amount");
            }

            if (!Validate.GuidValidation(tx.AccountFrom))
            {
                throw new ValidationException("Invalid AccountNumberFrom");
            }
            if (!Validate.GuidValidation(tx.AccountTo))
            {
                throw new ValidationException("Invalid AccountNumberTo");
            }
            if (!Validate.GuidValidation(tx.TrackingId))
            {
                throw new ValidationException("Invalid TrackingId");
            }

            TransactionPM tpm = new TransactionPM()
            {
                Amount                 = tx.Amount,
                TransactionType        = TransactionType.SendMoneyFromAppToCard,
                AccountNumberIdFromRef = tx.AccountFrom,
                AccountNumberIdToRef   = tx.AccountTo,
                TrackingId             = tx.TrackingId,
            };

            _transactionRepository.AddQRCodeBasedTransaction(tpm, GetCurrentUserId());
        }
        private void ValidateCommonTxDetail(TransactionPM t)
        {
            //TODO: Validate cardholder either by card crytogram of cardholder pin
            if (t.Amount > ConfigSingleton.MaxTransactionAmount)
            {
                throw new ValidationException("Invalid transaction, amount greater than max transaction amount allowed");
            }

            t.TransactionDateTime = DateTime.Now;
        }
        private int StoreTx(TransactionPM t, AccountPM accountFrom, AccountPM accountTo, CardPM cardFrom, bool useTransaction)
        {
            Action action = () =>
            {
                _context.Transactions.Add(t);
                UpdateAccountBalance(accountFrom.AccountNumberId, accountFrom.Balance = accountFrom.Balance - t.Amount);
                UpdateAccountBalance(accountTo.AccountNumberId, accountTo.Balance     = accountTo.Balance + t.Amount);
                if (cardFrom != null)
                {
                    cardFrom.AvailablegDailySpendLimit  = cardFrom.AvailablegDailySpendLimit - t.Amount;
                    cardFrom.AvailableMonthlySpendLimit = cardFrom.AvailableMonthlySpendLimit - t.Amount;
                }
            };

            if (!useTransaction)
            {
                try
                {
                    action.Invoke();
                    _context.SaveChanges();
                    return(t.TransactionId);
                }
                catch
                {
                    throw new TechnicalException("Error Occured during transaction db operation. Transaction Rolled Back");
                }
            }
            else
            {
                using (IDbContextTransaction dbTransaction = _context.Database.BeginTransaction())
                {
                    try
                    {
                        action.Invoke();
                        _context.SaveChanges();
                        dbTransaction.Commit();
                        return(t.TransactionId);
                    }
                    catch (Exception ex)
                    {
                        dbTransaction.Rollback();
                        throw new TechnicalException("Error Occured during transaction db operation. Transaction Rolled Back:" + ex.Message);
                    }
                }
            }
        }
Beispiel #4
0
        public void AddPOSTransaction(TransactionPM tx, POSTransactionPM txPos, string credentialsId)
        {
            string accountNumberIdRef = _accountRepository.GetAccountForUser(credentialsId).AccountNumberId;

            if (tx.AccountNumberIdToRef != accountNumberIdRef)
            {
                throw new ValidationException("Incorrect account to ref");
            }

            tx.AccountNumberIdFromRef = _cardsRepository.GetCard(tx.CardSerialNumberIdFrom).AccountNumberIdRef;

            txPos.TransactionDateTime    = DateTime.Now;
            tx.TransactionDateTime       = txPos.TransactionDateTime;
            txPos.AccountNumberIdToRef   = tx.AccountNumberIdToRef;
            txPos.AccountNumberIdFromRef = tx.AccountNumberIdFromRef;

            using (IDbContextTransaction dbTransaction = _context.Database.BeginTransaction())
            {
                try
                {
                    TransactionPM tpm = new TransactionPM()
                    {
                        Amount                 = tx.Amount,
                        TransactionType        = TransactionType.SendMoneyFromCardToApp,//hardcoded
                        AccountNumberIdFromRef = tx.AccountNumberIdFromRef,
                        AccountNumberIdToRef   = tx.AccountNumberIdToRef,
                        CardSerialNumberIdFrom = tx.CardSerialNumberIdFrom,
                        CardSerialNumberIdTo   = tx.CardSerialNumberIdTo,
                        CardFromEMVData        = tx.CardFromEMVData,
                    };
                    int id = _transactionRepository.AddCardBasedTransaction(tpm, credentialsId, false);
                    txPos.TransactionIdRef = id;
                    _context.POSTransactions.Add(txPos);
                    _context.SaveChanges();
                    dbTransaction.Commit();
                }
                catch (Exception ex)
                {
                    dbTransaction.Rollback();
                    throw new TechnicalException("Error Occured during transaction db operation. Transaction Rolled Back:" + ex.Message);
                }
            }
        }
        public int AddQRCodeBasedTransaction(TransactionPM t, string credentialsId, bool useTransaction)
        {
            ValidateCommonTxDetail(t);

            AccountPM accountLoggedIn = _accountsRepository.GetAccountForUser(credentialsId);
            AccountPM accountFrom     = null;
            AccountPM accountTo       = null;

            if (accountLoggedIn.AccountNumberId != t.AccountNumberIdFromRef)
            {
                throw new ValidationException("Invalid AccountNumberId");
            }

            accountTo   = GetAccount(t.AccountNumberIdToRef);
            accountFrom = accountLoggedIn; //_accountsRepository.GetAccount(transaction.AccountNumberIdFrom);
            if (accountFrom.Balance < t.Amount)
            {
                throw new ValidationException("Insufficient funds");
            }

            return(StoreTx(t, accountFrom, accountTo, null, useTransaction));
        }
        public void CardTransfer(string json)
        {
            CardTransferTransaction tx = CardTransferTransaction.FromJsonString(json);

            if (tx.Amount == 0)
            {
                throw new ValidationException("Invalid Amount");
            }

            TLV tlv = TLVasJSON.FromJSON(tx.CardFromEMVData);

            byte[] arpc = VerifyCardSignature(tlv);
            if (arpc == null)
            {
                throw new ValidationException("ARQC failure");
            }

            //TODO: only accept transactions from DC EMV cards, not EMV cards

            switch (tx.TransactionType)
            {
            case TransactionType.SendMoneyFromAppToCard:

                if (!Validate.GuidValidation(tx.AccountFrom))
                {
                    throw new ValidationException("Invalid AccountNumberFrom");
                }
                if (String.IsNullOrEmpty(tx.CardSerialTo))
                {
                    throw new ValidationException("Invalid CardSerialNumberTo");
                }

                if (!String.IsNullOrEmpty(tx.AccountTo))
                {
                    throw new ValidationException("Invalid AccountNumberTo");
                }
                if (!String.IsNullOrEmpty(tx.CardSerialFrom))
                {
                    throw new ValidationException("Invalid CardSerialNumberFrom");
                }
                break;

            case TransactionType.SendMoneyFromCardToApp:
                if (!String.IsNullOrEmpty(tx.AccountFrom))
                {
                    throw new ValidationException("Invalid AccountNumberFrom");
                }
                if (!String.IsNullOrEmpty(tx.CardSerialTo))
                {
                    throw new ValidationException("Invalid CardSerialNumberTo");
                }

                if (!Validate.GuidValidation(tx.AccountTo))
                {
                    throw new ValidationException("Invalid AccountNumberTo");
                }
                if (String.IsNullOrEmpty(tx.CardSerialFrom))
                {
                    throw new ValidationException("Invalid CardSerialNumberFrom");
                }
                break;

            default:
                throw new ValidationException("Invalid transaction type: " + tx.TransactionType);
            }

            TransactionPM tpm = new TransactionPM()
            {
                Amount                 = tx.Amount,
                TransactionType        = tx.TransactionType,
                AccountNumberIdFromRef = tx.AccountFrom,
                AccountNumberIdToRef   = tx.AccountTo,
                CardSerialNumberIdFrom = tx.CardSerialFrom,
                CardSerialNumberIdTo   = tx.CardSerialTo,
                CardFromEMVData        = tx.CardFromEMVData
            };

            _transactionRepository.AddCardBasedTransaction(tpm, GetCurrentUserId());
        }
        public int AddCardBasedTransaction(TransactionPM t, string credentialsId, bool useTransaction)
        {
            ValidateCommonTxDetail(t);

            AccountPM accountLoggedIn = _accountsRepository.GetAccountForUser(credentialsId);
            AccountPM accountFrom     = null;
            AccountPM accountTo       = null;
            CardPM    cardTo          = null;
            CardPM    cardFrom        = null;

            switch (t.TransactionType)
            {
            case TransactionType.SendMoneyFromAppToCard:
                if (accountLoggedIn.AccountNumberId != t.AccountNumberIdFromRef)
                {
                    throw new ValidationException("Invalid AccountNumberId");
                }

                cardTo = _cardsRepository.GetCard(t.CardSerialNumberIdTo);
                if (cardTo.CardState != CardState.Active)
                {
                    throw new ValidationException("Invalid card");
                }

                t.AccountNumberIdToRef = cardTo.AccountNumberIdRef;
                accountTo   = GetAccount(t.AccountNumberIdToRef);
                accountFrom = accountLoggedIn;     //_accountsRepository.GetAccount(transaction.AccountNumberIdFrom);
                if (accountFrom.Balance < t.Amount)
                {
                    throw new ValidationException("Insufficient funds");
                }
                break;

            case TransactionType.SendMoneyFromCardToApp:
                if (accountLoggedIn.AccountNumberId != t.AccountNumberIdToRef)
                {
                    throw new ValidationException("Invalid AccountNumberId");
                }

                cardFrom = _cardsRepository.GetCard(t.CardSerialNumberIdFrom);
                if (cardFrom.CardState != CardState.Active)
                {
                    throw new ValidationException("Invalid card");
                }

                if (cardFrom.AvailablegDailySpendLimit < t.Amount)
                {
                    throw new ValidationException("Daily Spend Limit Exceeded");
                }

                if (cardFrom.MonthlySpendLimit < t.Amount)
                {
                    throw new ValidationException("Monthly Spend Limit Exceeded");
                }

                if (String.IsNullOrEmpty(t.CardFromEMVData))
                {
                    throw new ValidationException("Card EMV data not supplied");
                }

                t.AccountNumberIdFromRef = cardFrom.AccountNumberIdRef;
                accountFrom = GetAccount(t.AccountNumberIdFromRef);
                accountTo   = accountLoggedIn;   //_accountsRepository.GetAccount(transaction.AccountNumberIdTo);
                if (accountFrom.Balance < t.Amount)
                {
                    throw new ValidationException("Insufficient funds");
                }
                break;

            default:
                throw new ValidationException("Invalid transaction type: " + t.TransactionType);
            }

            return(StoreTx(t, accountFrom, accountTo, cardFrom, useTransaction));
        }
Beispiel #8
0
        public void AddCardBasedPOSTransaction(string jsonTx, string jsonPosTx)
        {
            CardTransferTransaction transaction = CardTransferTransaction.FromJsonString(jsonTx);
            POSTransaction          posDetail   = POSTransaction.FromJsonString(jsonPosTx);

            if (transaction.Amount == 0)
            {
                throw new ValidationException("Invalid Amount");
            }

            //TODO: make sure data in EMV matches duplicate data fields in transaction
            TLV  tlv       = TLVasJSON.FromJSON(transaction.CardFromEMVData);
            TLV  _9F02     = tlv.Children.Get(EMVTagsEnum.AMOUNT_AUTHORISED_NUMERIC_9F02_KRN.Tag);
            long emvAmount = FormattingUtils.Formatting.BcdToLong(_9F02.Value);

            if (transaction.Amount != emvAmount)
            {
                throw new ValidationException("Invalid Amount: Card does not match Cryptogram");
            }

            if (TransactionController.VerifyCardSignature(tlv) == null)
            {
                throw new ValidationException("Invalid Cryptogram");
            }

            transaction.TransactionType = TransactionType.SendMoneyFromCardToApp;

            switch (transaction.TransactionType)
            {
            case TransactionType.SendMoneyFromCardToApp:
                if (!String.IsNullOrEmpty(transaction.AccountFrom))
                {
                    throw new ValidationException("Invalid AccountNumberFrom");
                }
                if (!String.IsNullOrEmpty(transaction.CardSerialTo))
                {
                    throw new ValidationException("Invalid CardSerialNumberTo");
                }

                if (!Validate.GuidValidation(transaction.AccountTo))
                {
                    throw new ValidationException("Invalid AccountNumberTo");
                }
                if (String.IsNullOrEmpty(transaction.CardSerialFrom))
                {
                    throw new ValidationException("Invalid CardSerialNumberFrom");
                }
                break;

            default:
                throw new ValidationException("Invalid transaction type: " + transaction.TransactionType);
            }

            if (posDetail.InvItems == null || posDetail.InvItems.Count == 0)
            {
                throw new ValidationException("Invalid items");
            }

            TransactionPM txpm = new TransactionPM()
            {
                TransactionType        = transaction.TransactionType,
                AccountNumberIdFromRef = transaction.AccountFrom,
                AccountNumberIdToRef   = transaction.AccountTo,
                CardSerialNumberIdFrom = transaction.CardSerialFrom,
                CardSerialNumberIdTo   = transaction.CardSerialTo,
                Amount          = transaction.Amount,
                CardFromEMVData = transaction.CardFromEMVData,
            };

            List <POSTransactionItemPM> items = new List <POSTransactionItemPM>();

            posDetail.InvItems.ForEach(x =>
            {
                POSTransactionItemPM tipm = new POSTransactionItemPM()
                {
                    Amount          = x.Amount,
                    Name            = x.Name,
                    Quantity        = x.Quantity,
                    InventoryItemId = x.InventoryItemId,
                };
                items.Add(tipm);
            });

            POSTransactionPM posTxpm = new POSTransactionPM()
            {
                POSTransactionItems = items,
            };

            _posRepository.AddPOSTransaction(txpm, posTxpm, GetCurrentUserId());
        }