Пример #1
0
        public static object GetInfo(this IPaymentTransaction src, Type expectedType = null, bool throwExeption = false)
        {
            if (!PaymentSystemsAndOtherInfo.PsAndOtherInfoLinks.ContainsKey(src.PaymentSystem))
            {
                if (throwExeption)
                {
                    throw new Exception("Unsupported payment system for reading other info: transactionId:" + src.Id);
                }

                return(null);
            }


            var type = PaymentSystemsAndOtherInfo.PsAndOtherInfoLinks[src.PaymentSystem];

            if (expectedType != null)
            {
                if (type != expectedType)
                {
                    throw new Exception("Payment system and Other info does not match for transactionId:" + src.Id);
                }
            }


            return(Newtonsoft.Json.JsonConvert.DeserializeObject(src.Info, type));
        }
        public async Task NotifyAsync(IPaymentTransaction pt)
        {
            var pd = await _personalDataRepository.GetAsync(pt.ClientId);


            var body =
                $"Client: {pd.Email}, Payment system amount: {pt.AssetId} {pt.Amount.MoneyToStr()}, Deposited amount: {pt.DepositedAssetId} {pt.DepositedAmount}, PaymentSystem={pt.PaymentSystem}";

            await
            _emailSender.BroadcastEmailAsync(BroadcastGroup.Payments,
                                             "Payment notification Ok", body);
        }
Пример #3
0
        public async Task <bool> CheckExistsAsync(IPaymentTransaction paymentTransaction)
        {
            if (paymentTransaction == null)
            {
                throw new ArgumentNullException(nameof(paymentTransaction));
            }

            var existingRecord =
                await
                _tableStorage.GetDataAsync(
                    PaymentTransactionEntity.IndexByClient.GeneratePartitionKey(paymentTransaction.ClientId),
                    PaymentTransactionEntity.IndexByClient.GenerateRowKey(paymentTransaction.Id));

            return(existingRecord != null);
        }
Пример #4
0
        /// <summary>
        /// GetInfo as T
        /// </summary>
        /// <typeparam name="T">Return type</typeparam>
        /// <param name="src">PaymentTransactionResponse object</param>
        /// <returns>Deserialize object as T</returns>
        public static T GetInfo <T>(this IPaymentTransaction src)
        {
            if (!PaymentSystemsAndOtherInfo.PsAndOtherInfoLinks.ContainsKey(src.PaymentSystem))
            {
                throw new ArgumentException("Unsupported payment system for reading other info: transactionId:" + src.Id);
            }

            var type = PaymentSystemsAndOtherInfo.PsAndOtherInfoLinks[src.PaymentSystem];

            if (type != typeof(T))
            {
                throw new ArgumentException("Payment system and Other info does not match for transactionId:" + src.Id);
            }

            return(Newtonsoft.Json.JsonConvert.DeserializeObject <T>(src.Info));
        }
Пример #5
0
 public static PaymentTransactionEntity Create(IPaymentTransaction src)
 {
     return(new PaymentTransactionEntity
     {
         Created = src.Created,
         TransactionId = src.Id,
         Info = src.Info,
         ClientId = src.ClientId,
         AssetId = src.AssetId,
         WalletId = src.WalletId,
         Amount = src.Amount,
         FeeAmount = src.FeeAmount,
         AggregatorTransactionId = src.AggregatorTransactionId,
         DepositedAssetId = src.DepositedAssetId,
         Status = src.Status,
         PaymentSystem = src.PaymentSystem
     });
 }
Пример #6
0
        public async Task InsertAsync(IPaymentTransaction paymentTransaction)
        {
            var commonEntity = Mapper.Map <PaymentTransactionEntity>(paymentTransaction);

            commonEntity.PartitionKey = PaymentTransactionEntity.GeneratePartitionKey();
            await _tableStorage.InsertAndGenerateRowKeyAsDateTimeAsync(commonEntity, paymentTransaction.Created);

            var entityByClient = Mapper.Map <PaymentTransactionEntity>(paymentTransaction);

            entityByClient.PartitionKey = PaymentTransactionEntity.GeneratePartitionKey(paymentTransaction.ClientId);
            entityByClient.RowKey       = PaymentTransactionEntity.GenerateRowKey(paymentTransaction.Id);

            var index = AzureMultiIndex.Create(IndexPartitionKey, paymentTransaction.Id, commonEntity, entityByClient);

            await Task.WhenAll(
                _tableStorage.InsertAsync(entityByClient),
                _tableStorageIndices.InsertAsync(index)
                );
        }
Пример #7
0
        public static PaymentTransactionEntity Create(IPaymentTransaction src)
        {
            var result = new PaymentTransactionEntity
            {
                Created                 = src.Created,
                TransactionId           = src.Id,
                Info                    = src.Info,
                ClientId                = src.ClientId,
                AssetId                 = src.AssetId,
                Amount                  = src.Amount,
                AggregatorTransactionId = src.AggregatorTransactionId,
                DepositedAssetId        = src.DepositedAssetId
            };

            result.SetPaymentStatus(src.Status);

            result.SetPaymentSystem(src.PaymentSystem);

            return(result);
        }
Пример #8
0
        public async Task CreateAsync(IPaymentTransaction src)
        {
            var commonEntity = PaymentTransactionEntity.Create(src);

            commonEntity.PartitionKey = PaymentTransactionEntity.IndexCommon.GeneratePartitionKey();
            await _tableStorage.InsertAndGenerateRowKeyAsDateTimeAsync(commonEntity, src.Created);

            var entityByClient = PaymentTransactionEntity.Create(src);

            entityByClient.PartitionKey = PaymentTransactionEntity.IndexByClient.GeneratePartitionKey(src.ClientId);
            entityByClient.RowKey       = PaymentTransactionEntity.IndexByClient.GenerateRowKey(src.Id);


            var index = AzureMultiIndex.Create(IndexPartitinKey, src.Id, commonEntity, entityByClient);


            await Task.WhenAll(
                _tableStorage.InsertAsync(entityByClient),
                _tableStorageIndices.InsertAsync(index)
                );
        }
Пример #9
0
        // private async Task<bool> IsCardHolderNameValid(string clientId, CreditCardModel card)
        // {
        //     var personalData = await _personalDataService.GetAsync(clientId);
        //     return IsNameSimilar(card.CardHolder, personalData.FirstName, personalData.LastName);
        // }

        // private static bool IsNameSimilar(string cardHolderName, string firstName, string lastName)
        // {
        //     return Compare(cardHolderName.ToLower(), $"{firstName} {lastName}".ToLowerInvariant())
        //            || Compare(cardHolderName.ToLower(), $"{lastName} {firstName}".ToLowerInvariant());
        // }

        // private static bool Compare(string expected, string actual)
        // {
        //     const double allowedSimilarity = 0.8;
        //     var metric = new SimMetrics.Net.Metric.Levenstein();
        //     var v = metric.GetSimilarity(expected, actual);
        //     return v > allowedSimilarity;
        // }

        private async Task SendAntiFraudNotificationAsync(IPaymentTransaction transaction)
        {
            if (string.IsNullOrEmpty(_antifraudNotificationEmail))
            {
                return;
            }

            var clientAccount = await _clientAccountClient.ClientAccountInformation.GetByIdAsync(transaction.ClientId);

            string text = $"New deposit request (transactionId = {transaction.TransactionId}), please review";

            var msgData = new PlainTextData
            {
                Subject = "Review deposit request",
                Text    = text
            };

            await Task.WhenAll(
                _emailSender.SendEmailAsync(clientAccount.PartnerId, _antifraudNotificationEmail, msgData),
                _telegramBot.SendTextMessageAsync(_chatId, text)
                );
        }
Пример #10
0
        public async Task NotifyAsync(IPaymentTransaction pt)
        {
            string emailAddress = string.Empty;

            try
            {
                var pdTask  = _personalDataService.GetAsync(pt.ClientId);
                var accTask = _clientAccountClient.ClientAccountInformation.GetByIdAsync(pt.ClientId);

                await Task.WhenAll(pdTask, accTask);

                var acc = accTask.Result;
                var pd  = pdTask.Result;

                emailAddress = pd.Email;

                await _emailSender.SendEmailAsync(acc.PartnerId, emailAddress, new DirectTransferCompletedData
                {
                    Amount     = pt.Amount,
                    AssetId    = pt.AssetId,
                    ClientName = pd.FullName
                });

                var body = $"Client: {pd.Email}, "
                           + $"Payment system amount: {pt.AssetId} {pt.Amount:0.00}, "
                           + $"Deposited amount: {pt.DepositedAssetId} {pt.DepositedAmount}, "
                           + $"PaymentSystem: {pt.PaymentSystem}";

                // email to Payments group
                await _emailSender.BroadcastEmailAsync(acc.PartnerId, BroadcastGroup.Payments, $"{pt.PaymentSystem}, payment notification Ok", body);
            }
            catch (Exception exc)
            {
                _log.Error("PaymentOkEmailSender.NotifyAsync", exc, emailAddress);
            }
        }
Пример #11
0
        public static PaymentTransactionResponse Create(IPaymentTransaction lastPaymentTransaction, IPersonalData personalData)
        {
            if (lastPaymentTransaction.PaymentSystem != CashInPaymentSystem.CreditVoucher &&
                lastPaymentTransaction.PaymentSystem != CashInPaymentSystem.Fxpaygate)
            {
                throw new ArgumentException("Credit voucher payment system is expect for transactionID:" + lastPaymentTransaction.Id);
            }

            var info = lastPaymentTransaction.GetInfo <OtherPaymentInfo>();

            return(new PaymentTransactionResponse
            {
                Address = info.Address,
                Amount = lastPaymentTransaction.Amount,
                AssetId = lastPaymentTransaction.AssetId,
                City = info.City,
                Country = info.Country,
                Phone = personalData.ContactPhone,
                Email = personalData.Email,
                FirstName = info.FirstName,
                LastName = info.LastName,
                Zip = info.Zip
            });
        }
 public async Task InsertPaymentTransactionAsync(IPaymentTransaction model)
 {
     await _paymentTransactionsRepository.InsertAsync(model);
 }
Пример #13
0
        private async Task ProcessMessageAsync(CashTransferEvent item)
        {
            var id = item.Header.MessageId ?? item.Header.RequestId;

            try
            {
                IPaymentTransaction paymentTransaction = null;

                for (int i = 0; i < 3; i++)
                {
                    paymentTransaction = await _paymentTransactionsRepository.GetByIdForClientAsync(id, item.CashTransfer.ToWalletId);

                    if (paymentTransaction != null)
                    {
                        break;
                    }
                    await Task.Delay(2000 *(i + 1));
                }

                double volume = double.Parse(item.CashTransfer.Volume);

                if (item.CashTransfer.Fees != null)
                {
                    foreach (var fee in item.CashTransfer.Fees)
                    {
                        if (string.IsNullOrWhiteSpace(fee.Transfer?.Volume))
                        {
                            continue;
                        }

                        volume -= double.Parse(fee.Transfer.Volume);
                    }
                }

                if (paymentTransaction == null || paymentTransaction.PaymentSystem != CashInPaymentSystem.Swift)
                {
                    var cashOp = new CashOperation
                    {
                        Id       = id,
                        ClientId = item.CashTransfer.ToWalletId,
                        Asset    = item.CashTransfer.AssetId,
                        Volume   = volume,
                        DateTime = item.Header.Timestamp,
                    };

                    await _cashOperationsCollector.AddDataItemAsync(cashOp);
                }
                else
                {
                    var transfer = new CashTransferOperation
                    {
                        Id           = id,
                        FromClientId = item.CashTransfer.FromWalletId,
                        ToClientId   = item.CashTransfer.ToWalletId,
                        Asset        = item.CashTransfer.AssetId,
                        Volume       = volume,
                        DateTime     = item.Header.Timestamp,
                    };
                    await _cashTransfersCollector.AddDataItemAsync(transfer);
                }
            }
            catch (Exception exc)
            {
                _log.Error(exc, context: item);
            }
        }
        public async Task <string> GetPaymentUrl(IPaymentTransaction bankCardOrder)
        {
            var creditVoucherOtherInfo = bankCardOrder.Info.DeserializeJson <CreditVoucherOtherPaymentInfo>();

            var postModel = new CreditVouchersPostToAggregatorFormModel
            {
                Action                = _creditVouchersSettings.Action,
                AmountToPay           = bankCardOrder.Amount * 100,      // ref to API documentation
                AmountCurrency        = _creditVouchersSettings.AssetId, //TODO
                PaymentType           = _creditVouchersSettings.PaymentType,
                API_UserName          = _creditVouchersSettings.ApiUserName,
                Partner_Email         = _creditVouchersSettings.ParthnerEmail,
                OrderId               = bankCardOrder.Id,
                PaymentOKURL          = string.Format(_creditVouchersSettings.PaymentOkUrlFormat, bankCardOrder.Id),
                PaymentFailURL        = string.Format(_creditVouchersSettings.PaymentFailUrlFormat, bankCardOrder.Id),
                API_Version           = _creditVouchersSettings.ApiVersion,
                Customer_FirstName    = creditVoucherOtherInfo.FirstName,
                Customer_LastName     = creditVoucherOtherInfo.LastName,
                Customer_City         = creditVoucherOtherInfo.City,
                Customer_Zip          = creditVoucherOtherInfo.Zip,
                Customer_Address      = creditVoucherOtherInfo.Address,
                Customer_Country      = creditVoucherOtherInfo.Country,
                Customer_Email        = creditVoucherOtherInfo.Email,
                Customer_MobileNumber = creditVoucherOtherInfo.ContactPhone,
                PaymentNotifyURL      = _creditVouchersSettings.PaymentNotifyUrlFormat
            };

            postModel.CheckSumHeader = _creditVouchersSecurity.CalculateHeaderCheckSum(postModel.GetPropertiesDictionary());
            postModel.CheckSum       = _creditVouchersSecurity.CalculateCheckSum(postModel.GetPropertiesDictionary(), postModel.CheckSumHeader);

            using (var client = new HttpClient())
            {
                var postedValues = postModel.GetPropertiesDictionary().Where(p => !string.IsNullOrEmpty(p.Value)).ToList();
                var resp         = await client.PostAsync(_creditVouchersSettings.AggregatorPaymentUrl, new FormUrlEncodedContent(postedValues));

                var respContent = await resp.Content.ReadAsStringAsync();

                resp.EnsureSuccessStatusCode();

                var respModel = JsonConvert.DeserializeObject <CreditVouchersPostToAggregatorResponceModel>(respContent);
                if (respModel.Status == CreditVoucherResponceStatus.Success)
                {
                    // mode=iframe is for Mobile version
                    var result = respModel.RedirectURL +
                                 ((respModel.RedirectURL ?? "").Contains("?") ? "&" : "?") +
                                 "mode=iframe";

                    return(result);
                }

                var logResp = $"Responce from credit voucher api. " +
                              $"Url: {_creditVouchersSettings.AggregatorPaymentUrl} , " +
                              $"ResponceStatusCode: {resp.StatusCode}, " +
                              $"ResponceBody:  {respContent} ";
                var errorsDescriptions = respModel.Errors.Select(p => $"{p.Key}: {string.Join(", ", p.Value)}");

                throw new ArgumentException($"CreditVouchers validation failed:{string.Join("; ", errorsDescriptions)}. Responce: {logResp}")
                      {
                      };
            }
        }
Пример #15
0
 public static bool AreMoneyOnOurAccount(this IPaymentTransaction src)
 {
     return(src.Status == PaymentStatus.NotifyProcessed);
 }
Пример #16
0
 public static T GetInfo <T>(this IPaymentTransaction src)
 {
     return((T)GetInfo(src, typeof(T), true));
 }