public async Task <PersonalInformationViewModel> GetPersonalInformation(string returnUrl) { var userFullData = await _personalDataService.GetAsync(CurrentClientId); var model = Mapper.Map <PersonalInformationViewModel>(userFullData) ?? new PersonalInformationViewModel(); model.ReturnUrl = returnUrl; model.NextStepUrl = null; /*GetStepUrl("CountryOfResidence", returnUrl);*/ model.PrevStepUrl = null; return(model); }
public FxPaygatePaymentUrlInputValidationModel( IHttpContextAccessor httpContextAccessor, IAssetsHelper assetHelper, IAssetDisclaimersClient assetDisclaimersClient, IPaymentSystemClient paymentSystemClient, IPersonalDataService personalDataService, IClientAccountClient clientAccountService, IAssetsService assetsService, IKycStatusService kycStatusService, ITierClient tierClient, IRateCalculatorClient rateCalculatorClient) { _assetsHelper = assetHelper; _assetDisclaimersClient = assetDisclaimersClient; _clientAccountService = clientAccountService; _assetsService = assetsService; _kycStatusService = kycStatusService; _tierClient = tierClient; _rateCalculatorClient = rateCalculatorClient; _clientId = httpContextAccessor.HttpContext.User?.Identity?.Name; var paymentLimitsTask = paymentSystemClient.GetPaymentLimitsAsync(); var pdTask = personalDataService.GetAsync(_clientId); Task.WhenAll(paymentLimitsTask, pdTask).GetAwaiter().GetResult(); _paymentLimitsResponse = paymentLimitsTask.Result; _personalData = pdTask.Result; RegisterRules(); }
private async Task <ClientModel> GetClientModel() { var personalDataTask = _personalDataService.GetAsync(_requestContext.ClientId); var cashoutBlockTask = _clientAccountClient.ClientSettings.GetCashOutBlockSettingsAsync(_requestContext.ClientId); var backupDoneTask = _clientAccountClient.ClientSettings.GetBackupSettingsAsync(_requestContext.ClientId); var kycStatusTask = _kycStatusService.GetKycStatusAsync(_requestContext.ClientId); await Task.WhenAll(personalDataTask, cashoutBlockTask, backupDoneTask, kycStatusTask); var personalData = personalDataTask.Result; return(new ClientModel { Id = new Guid(_requestContext.ClientId), TradesBlocked = cashoutBlockTask.Result.TradesBlocked, BackupDone = backupDoneTask.Result.BackupDone, KycStatus = kycStatusTask.Result.ToString(), PersonalData = new PersonalDataModel { Country = personalData.Country, CountryFromID = personalData.CountryFromID, CountryFromPOA = personalData.CountryFromPOA } }); }
public async Task <ClaimsIdentity> CreateUserIdentityAsync(string clientId, string email, string userName) { var personalData = await _personalDataService.GetAsync(clientId); var claims = new List <Claim> { new Claim(ClaimTypes.Name, email), new Claim(ClaimTypes.NameIdentifier, clientId), new Claim(OpenIdConnectConstants.Claims.Email, email) }; if (!string.IsNullOrEmpty(personalData.FirstName)) { claims.Add(new Claim(OpenIdConnectConstants.Claims.GivenName, personalData.FirstName)); } if (!string.IsNullOrEmpty(personalData.LastName)) { claims.Add(new Claim(OpenIdConnectConstants.Claims.FamilyName, personalData.LastName)); } if (!string.IsNullOrEmpty(personalData.Country)) { claims.Add(new Claim(OpenIdConnectConstantsExt.Claims.Country, personalData.Country)); } var documents = (await GetDocumentListAsync(clientId)).ToList(); if (documents.Any()) { claims.Add(new Claim(OpenIdConnectConstantsExt.Claims.Documents, string.Join(",", documents))); } return(new ClaimsIdentity(new GenericIdentity(userName, "Token"), claims)); }
public void GenerateFromSwiftDetails(ICashOutRequest request, string initialRequestId, DateTime dateOfTransaction) { Task.Run(async() => { if (request == null || string.IsNullOrWhiteSpace(initialRequestId)) { return; } var swiftFields = request.PaymentFields.DeserializeJson <Swift>(); var pd = await _personalDataService.GetAsync(request.ClientId); var htmlContent = "<!DOCTYPE html><html><head><title>Cash out request</title></head><body><div style=\"font-family: Geneva, Arial, Helvetica, sans-serif; width: 650px; margin:20px auto;\"><div style=\"width:650px;\"><img src=\"https://lkefiles.blob.core.windows.net/images/emails/logo_emails.png\" height=\"40\" alt=\"Lykke logo\" /></div><table style=\"margin:auto;width:650px;border: none;background-color: #fff;\"><tr><td style=\"text-align:center;padding:0 40px 0 40px;\"><img src=\"https://lkefiles.blob.core.windows.net:443/images/emails/withdraw-icon.png\" width=\"200\" alt=\"Letter image\" /></td></tr><tr><td style=\"text-align:center;\"><span style=\"font-size: 1.4em; font-weight: bold;\">Cash Out Request <br/>(@[Amount] @[Asset] for @[UserEmail]) <br/>Processed</span></td></tr><tr><td style=\"padding:20px 40px 60px 40px;\"><table style=\"border-collapse:collapse\"><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">SWIFT / ABA Routing</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[Bic]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Name of the bank</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[BankName]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Beneficiary's Account number (IBAN)</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[AccNumber]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Name of the account holder</span></td><td style=\"word-break:break-all; padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[AccName]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Country of the account holder</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[AccHolderCountry]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Zip Code of the account holder</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[AccHolderZipCode]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">City of the account holder</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[AccHolderCity]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Address of the account holder</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[AccHolderAddress]</span></td></tr><tr style=\"border-top: 1px solid #8C94A0; border-bottom: 1px solid #8C94A0;\"><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #8C94A0;\">Date of the transaction</span><br/><span style=\"font-size: 1.1em;color: #8C94A0;\">(Year/Month/Date)</span></td><td style=\"padding:15px 0 15px 0;\" width=\"260\"><span style=\"font-size: 1.1em;color: #3F4D60;\">@[DateOfTransaction]</span></td></tr></table></td></tr></table></div></body></html>"; htmlContent = htmlContent.Replace("@[Amount]", request.Amount.ToString()); htmlContent = htmlContent.Replace("@[Asset]", request.AssetId); htmlContent = htmlContent.Replace("@[UserEmail]", pd.Email); htmlContent = htmlContent.Replace("@[Bic]", swiftFields.Bic); htmlContent = htmlContent.Replace("@[BankName]", swiftFields.BankName); htmlContent = htmlContent.Replace("@[AccNumber]", swiftFields.AccNumber); htmlContent = htmlContent.Replace("@[AccName]", swiftFields.AccName); htmlContent = htmlContent.Replace("@[AccHolderCountry]", swiftFields.AccHolderCountry); htmlContent = htmlContent.Replace("@[AccHolderZipCode]", swiftFields.AccHolderZipCode); htmlContent = htmlContent.Replace("@[AccHolderCity]", swiftFields.AccHolderCity); htmlContent = htmlContent.Replace("@[AccHolderAddress]", swiftFields.AccHolderAddress); htmlContent = htmlContent.Replace("@[DateOfTransaction]", dateOfTransaction.ToString("yyyy/MM/dd")); await HtmlToPdfAsync(htmlContent, SwiftDetailsBlobName(request.ClientId, initialRequestId), $"{dateOfTransaction:yyyyMMdd}_withdrawal {pd.FullName}.pdf"); await SaveSwiftPdfReportToGoogleDriveAsync(request.ClientId, initialRequestId, request.AssetId); }); }
public async Task <IActionResult> EmailRequestAsync(EmailRequestCommand cmd) { var swiftCredentials = await _swiftCredentialsService.GetAsync(cmd.RegulationId, cmd.AssetId); var pd = await _personalDataService.GetAsync(cmd.ClientId); var asset = await _assetsService.TryGetAssetAsync(cmd.AssetId); _cqrsEngine.PublishEvent(new SwiftCredentialsRequestedEvent { Email = pd.Email, ClientName = pd.FullName, Amount = cmd.Amount, Year = DateTime.UtcNow.Year.ToString(), AccountName = swiftCredentials.AccountName, AccountNumber = swiftCredentials.AccountNumber, AssetId = swiftCredentials.AssetId, AssetSymbol = asset.Symbol ?? asset.DisplayId, BankAddress = swiftCredentials.BankAddress, Bic = swiftCredentials.BIC, CompanyAddress = swiftCredentials.CompanyAddress, CorrespondentAccount = swiftCredentials.CorrespondentAccount, PurposeOfPayment = await _purposeOfPaymentBuilder.Build( swiftCredentials.PurposeOfPayment, cmd.ClientId, cmd.AssetId), RegulatorId = swiftCredentials.RegulatorId }, SwiftCredentialsBoundedContext.Name); return(Ok()); }
public async Task SendReminderEmail(IClientReminder reminder) { await _clientReminderRepository.DeleteAsync(reminder); var clientAcc = await _clientAccountService.GetClientByIdAsync(reminder.ClientId); if (clientAcc == null) { await _log.WriteInfoAsync(nameof(ClientReminderService), nameof(SendReminderEmail), $"client {reminder.ClientId} reminder cannot be processed - no client account found"); } else { var pd = await _personalDataService.GetAsync(reminder.ClientId); if (pd == null) { await _log.WriteInfoAsync(nameof(ClientReminderService), nameof(SendReminderEmail), $"client {reminder.ClientId} reminder cannot be processed - no personal data found"); } else { var reminderData = new KycRegReminderData { Year = DateTime.UtcNow.Year.ToString(), FullName = String.IsNullOrWhiteSpace(pd.FullName) ? pd.FirstName + " " + pd.LastName : pd.FullName, Date = DateTime.UtcNow.ToString("MMM dd, hh:mm tt", CultureInfo.InvariantCulture), Subject = "Lykke Wallet" }; await _emailSender.SendEmailAsync(clientAcc.PartnerId, clientAcc.Email, reminderData); // send email reminder await _log.WriteInfoAsync(nameof(ClientReminderService), nameof(SendReminderEmail), $"client {reminder.ClientId} reminder processed - email sent"); } } }
public async Task <IActionResult> GetAvailableMethods() { var model = new WithdrawalMethodsResponse(); try { var assetsTask = _assetsHelper.GetAssetsAvailableToClientAsync(_requestContext.ClientId, _requestContext.PartnerId); var pdTask = _personalDataService.GetAsync(_requestContext.ClientId); await Task.WhenAll(assetsTask, pdTask); var assets = assetsTask.Result.ToList(); var pd = pdTask.Result; var cryptos = new WithdrawalMethod { Name = "Cryptos", Assets = assets .Where(x => x.BlockchainWithdrawal) .Select(x => x.Id) .ToList() }; var swift = new WithdrawalMethod { Name = "Swift", Assets = assets .Where(x => x.SwiftWithdrawal && (!_blockedWithdawalSettings.AssetByCountry.ContainsKey(x.Id) || !_blockedWithdawalSettings.AssetByCountry[x.Id] .Contains(pd.CountryFromPOA, StringComparer.InvariantCultureIgnoreCase))) .Select(x => x.Id) .ToList() }; model.WithdrawalMethods = new List <WithdrawalMethod> { cryptos, swift }; } catch (Exception ex) { _log.Error(ex, "Error getting available methods", context: $"clientId: {_requestContext.ClientId}, partnerId: {_requestContext.PartnerId}"); model.WithdrawalMethods = new List <WithdrawalMethod> { new WithdrawalMethod { Name = "Cryptos", Assets = Array.Empty <string>() }, new WithdrawalMethod { Name = "Swift", Assets = Array.Empty <string>() } }; } return(Ok(model)); }
public bool IsUnitedKingdom() { var clientId = _requestContext.ClientId; var personalData = _personalDataService.GetAsync(clientId).Result; return(personalData.CountryFromPOA == UnitedKingdomIso3Code); }
public async Task <TierInfoResponse> GetClientTierInfoAsync(string clientId) { var clientTask = _clientAccountClient.ClientAccountInformation.GetByIdAsync(clientId); var pdTask = _personalDataService.GetAsync(clientId); await Task.WhenAll(clientTask, pdTask); ClientInfo client = clientTask.Result; IPersonalData pd = pdTask.Result; if (pd == null) { throw new ValidationApiException(HttpStatusCode.NotFound, "Client not found"); } var tierInfo = await _tiersService.GetClientTierInfoAsync(client.Id, client.Tier, pd.CountryFromPOA); return(_mapper.Map <TierInfoResponse>(tierInfo)); }
public async Task <IActionResult> UserInfo() { try { var personalDataTask = _personalDataService.GetAsync(_requestContext.ClientId); var isKycNeededTask = _kycStatusService.IsKycNeededAsync(_requestContext.ClientId); await Task.WhenAll(personalDataTask, isKycNeededTask); IPersonalData personalData = personalDataTask.Result; bool isKycNeeded = isKycNeededTask.Result; return(Ok(new UserInfoResponseModel { Email = personalData?.Email, FirstName = personalData?.FirstName, LastName = personalData?.LastName, KycStatus = (isKycNeeded ? KycStatus.NeedToFillData : KycStatus.Ok).ToApiModel() })); } catch (Exception e) { _log.Error(e, $"clientId = {_requestContext.ClientId}"); return(StatusCode((int)HttpStatusCode.InternalServerError)); } }
private async Task FinalizeCommonTransfer(IBitcoinTransaction transaction, TransferContextData contextData) { foreach (var transfer in contextData.Transfers) { await _transferEventsRepository.SetIsSettledIfExistsAsync(transfer.ClientId, transfer.OperationId, true); var clientData = await _personalDataService.GetAsync(transfer.ClientId); if (transfer.Actions?.CashInConvertedOkEmail != null) { await _srvEmailsFacade.SendTransferCompletedEmail(clientData.Email, clientData.FullName, transfer.Actions.CashInConvertedOkEmail.AssetFromId, transfer.Actions.CashInConvertedOkEmail.AmountFrom, transfer.Actions.CashInConvertedOkEmail.AmountLkk, transfer.Actions.CashInConvertedOkEmail.Price, transaction.BlockchainHash); } if (transfer.Actions?.SendTransferEmail != null) { await _srvEmailsFacade.SendDirectTransferCompletedEmail(clientData.Email, clientData.FullName, transfer.Actions.SendTransferEmail.AssetId, transfer.Actions.SendTransferEmail.Amount, transaction.BlockchainHash); } if (transfer.Actions?.PushNotification != null) { var clientAcc = await _clientAccountsRepository.GetByIdAsync(transfer.ClientId); var asset = await _assetsService.TryGetAssetAsync(transfer.Actions.PushNotification.AssetId); await _appNotifications.SendAssetsCreditedNotification(new[] { clientAcc.NotificationsId }, transfer.Actions.PushNotification.Amount, transfer.Actions.PushNotification.AssetId, string.Format(TextResources.CreditedPushText, transfer.Actions.PushNotification.Amount.GetFixedAsString(asset.Accuracy), transfer.Actions.PushNotification.AssetId)); } } await _paymentTransactionsRepository.SetStatus(transaction.TransactionId, PaymentStatus.NotifyProcessed); }
public async Task <IActionResult> SetupGoogle2FaVerify([FromBody] GoogleSetupVerifyRequest model) { try { if (await _confirmationCodesClient.Google2FaClientHasSetupAsync(_requestContext.ClientId)) { throw LykkeApiErrorException.BadRequest(LykkeApiErrorCodes.Service.SecondFactorAlreadySetup); } var pd = await _personalDataService.GetAsync(_requestContext.ClientId); var resp = await _confirmationCodesClient.Google2FaVerifySetupAsync( new VerifySetupGoogle2FaRequest { ClientId = _requestContext.ClientId, Phone = pd.ContactPhone, SmsCode = model.Code, GaCode = model.GaCode }); return(Ok(new GoogleSetupVerifyResponse { IsValid = resp.IsValid })); } catch (ApiException e) { switch (e.StatusCode) { case HttpStatusCode.BadRequest: throw LykkeApiErrorException.BadRequest(LykkeApiErrorCodes.Service.InconsistentState); case HttpStatusCode.Forbidden: throw LykkeApiErrorException.BadRequest(LykkeApiErrorCodes.Service.MaxAttemptsReached); } throw; } }
private async Task Execute(ITimerTrigger timer, TimerTriggeredHandlerArgs args, CancellationToken cancellationToken) { var limitsReached = await _limitsService.GetAllLimitReachedAsync(); if (limitsReached.Count == 0) { return; } var clientIds = limitsReached.Select(x => x.ClientId).Distinct().ToArray(); var clients = (await _clientAccountClient.ClientAccountInformation.GetClientsByIdsAsync( new ClientIdsRequest { Ids = clientIds })).ToList(); var personalDatas = (await _personalDataService.GetAsync(clientIds)).ToList(); foreach (var limit in limitsReached) { var client = clients.FirstOrDefault(x => x.Id == limit.ClientId); var pd = personalDatas.FirstOrDefault(x => x.Id == limit.ClientId); if (client == null || pd == null) { _log.Warning("Client or personal data not found", context: limit.ClientId); continue; } var currentLimitSettingsTask = _limitsService.GetClientLimitSettingsAsync(limit.ClientId, client.Tier, pd.CountryFromPOA); var checkAmountTask = _limitsService.GetClientDepositAmountAsync(limit.ClientId); await Task.WhenAll(currentLimitSettingsTask, checkAmountTask); if (currentLimitSettingsTask.Result?.MaxLimit == null) { continue; } var checkAmount = checkAmountTask.Result; if (checkAmount < currentLimitSettingsTask.Result.MaxLimit.Value) { await _limitsService.RemoveLimitReachedAsync(limit.ClientId); _log.Info("Limit reached removed", context: limit.ClientId); } } }
public async Task <ISpiderCheckResult> CheckAsync(string clientId) { var personalData = await _personalDataService.GetAsync(clientId); if (personalData == null) { throw new InvalidOperationException($"No personal data for ClientId:{clientId} but spider check requested"); } var request = new checkPerson(FormRequest(personalData)); var result = await PerformCheck(request); var mappedResult = MapResult(personalData, result); return(await _repository.AddAsync(mappedResult)); }
private async Task <ClientModel> GetClientModel() { var personalData = await _personalDataService.GetAsync(_requestContext.ClientId); return(new ClientModel { Id = new Guid(_requestContext.ClientId), TradesBlocked = (await _clientAccountClient.GetCashOutBlockAsync(personalData.Id)).TradesBlocked, BackupDone = (await _clientAccountClient.GetBackupAsync(personalData.Id)).BackupDone, KycStatus = (await _kycStatusService.GetKycStatusAsync(personalData.Id)).ToString(), PersonalData = new PersonalDataModel { Country = personalData.Country, CountryFromID = personalData.CountryFromID, CountryFromPOA = personalData.CountryFromPOA } }); }
private async Task SendWhitelistEmail(string clientId, string asset, string address, string tag) { var clientAccountTask = _clientAccountService.ClientAccountInformation.GetByIdAsync(clientId); var pdTask = _personalDataService.GetAsync(clientId); await Task.WhenAll(clientAccountTask, pdTask); var clientAccount = clientAccountTask.Result; var pd = pdTask.Result; var template = await _templateFormatter.FormatAsync("AddressWhitelistedTemplate", clientAccount.PartnerId, "EN", new { FullName = pd.FullName, Asset = asset, Address = address, Tag = tag ?? "---", Year = DateTime.UtcNow.Year }); var msgData = new PlainTextData { Sender = pd.Email, Subject = template.Subject, Text = template.HtmlBody }; await _emailSender.SendEmailAsync(clientAccount.PartnerId, pd.Email, msgData); }
public async Task <IActionResult> GetLastByDate(string clientId) { var lastPaymentTransaction = await _paymentTransactionsService.GetLastByDateAsync(clientId); var personalData = await _personalDataService.GetAsync(clientId); if (personalData == null) { return(BadRequest("A user with such an clientId does not exist.")); } var isCreditVoucherOrFxpaygate = lastPaymentTransaction != null && (lastPaymentTransaction.PaymentSystem == CashInPaymentSystem.CreditVoucher || lastPaymentTransaction.PaymentSystem == CashInPaymentSystem.Fxpaygate); var result = isCreditVoucherOrFxpaygate ? PaymentTransactionResponse.Create(lastPaymentTransaction, personalData) : PaymentTransactionResponse.Create(personalData); result.Country = _countryComponent.GetCountryIso3Code(result.Country); return(Ok(result)); }
public async Task <IActionResult> UserInfo() { IPersonalData personalData; try { personalData = await _personalDataService.GetAsync(_requestContext.ClientId); } catch (Exception e) { await _log.WriteErrorAsync(nameof(ClientController), nameof(UserInfo), $"clientId = {_requestContext.ClientId}", e); return(StatusCode((int)HttpStatusCode.InternalServerError)); } return(Ok(new UserInfoResponseModel { Email = personalData?.Email, FirstName = personalData?.FirstName, LastName = personalData?.LastName })); }
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); } }
public async Task Handle(SwiftCashoutCreatedEvent evt) { var client = await _personalDataService.GetAsync(evt.ClientId); await _cashoutRequestLogRepository.AddRecordAsync("Client", evt.RequestId, client.FullName, client.Email, CashoutRequestStatus.Pending, evt.VolumeSize); }
public async Task <IActionResult> DisplayUserProfile(string id) { if (!id.IsGuid()) { return(View("ProfileNotFound")); } var streamsIds = await _streamsIdRepository.GetStreamsIdsAsync(); var userStreamsId = streamsIds.FirstOrDefault(x => x.StreamsId == id); if (userStreamsId == null) { return(View("ProfileNotFound")); } var clientId = userStreamsId.ClientId; var profile = await _personalDataService.GetAsync(clientId); if (profile == null) { return(View("ProfileNotFound")); } var avatars = await _personalDataService.GetClientAvatarsAsync(new List <string> { clientId }); var user = UserModel.GetAuthenticatedUser(User.Identity); if (profile.Id == user.Id && profile.FirstName != user.FirstName) { var newIdentity = ClaimsHelper.UpdateFirstNameClaim(User.Identity, profile.FirstName); var principal = new ClaimsPrincipal(); principal.AddIdentity(newIdentity); await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal); } var commentsViewModel = new CommentsViewModel { CommentsList = await GetUserComments(profile.Email), CommentAvatar = avatars[clientId] }; var userProfileViewModel = new UserProfileViewModel { Profile = profile, AvatarUrl = avatars[clientId], WinningsSum = await GetUserWinnigsSum(profile.Email), CreatedProjects = await GetCreatedProjects(profile.Email), ParticipatedProjects = await GetParticipatedProjects(profile.Email), WonProjects = await GetWonProjects(profile.Email), Comments = commentsViewModel, AuthLink = _settings.LykkeStreams.Authentication.Authority, IsLykkeMember = await IsUserLykkeMember(profile.Email), ExpertedProjects = await GetExpertedProjects(profile.Email) }; return(View("~/Views/UserProfile/UserProfile.cshtml", userProfileViewModel)); }
public async Task Handle(ClientDepositedEvent evt, ICommandSender commandSender) { var clientAccountTask = _clientAccountClient.ClientAccountInformation.GetByIdAsync(evt.ClientId); var pdTask = _personalDataService.GetAsync(evt.ClientId); await Task.WhenAll(clientAccountTask, pdTask); ClientInfo clientAccount = clientAccountTask.Result; IPersonalData pd = pdTask.Result; if (clientAccount == null) { return; } await _limitsService.SaveDepositOperationAsync(_mapper.Map <DepositOperation>(evt)); LimitSettings currentLimitSettings = await _limitsService.GetClientLimitSettingsAsync(evt.ClientId, clientAccount.Tier, pd.CountryFromPOA); if (currentLimitSettings?.MaxLimit == null) { return; } var checkAmountTask = _limitsService.GetClientDepositAmountAsync(evt.ClientId); var pushSettingsTask = _clientAccountClient.ClientSettings.GetPushNotificationAsync(evt.ClientId); await Task.WhenAll(checkAmountTask, pushSettingsTask); var checkAmount = checkAmountTask.Result; var pushSettings = pushSettingsTask.Result; if (checkAmount > currentLimitSettings.MaxLimit.Value) { await _limitsService.SetLimitReachedAsync(evt.ClientId, checkAmount, currentLimitSettings.MaxLimit.Value, evt.BaseAsset); if (pushSettings.Enabled && !string.IsNullOrEmpty(clientAccount.NotificationsId)) { await SendPushNotificationAsync(clientAccount.PartnerId, clientAccount.NotificationsId, "PushLimitReachedTemplate", new { }, commandSender); } } if (checkAmount <= currentLimitSettings.MaxLimit.Value) { bool needNotification = _settingsService.IsLimitReachedForNotification(checkAmount, currentLimitSettings.MaxLimit.Value); if (!needNotification) { return; } if (pushSettings.Enabled && !string.IsNullOrEmpty(clientAccount.NotificationsId)) { await SendPushNotificationAsync(clientAccount.PartnerId, clientAccount.NotificationsId, "PushLimitPercentReachedTemplate", new { CurrentAmount = checkAmount, Limit = currentLimitSettings.MaxLimit.Value, Percent = Math.Round(checkAmount / currentLimitSettings.MaxLimit.Value * 100), FullName = pd.FullName, Asset = evt.BaseAsset }, commandSender); } } }
private async Task SendNotificationAsync(TierUpgradeRequestChangedEvent evt, ICommandSender commandSender) { var clientAccTask = _clientAccountClient.ClientAccountInformation.GetByIdAsync(evt.ClientId); var personalDataTask = _personalDataService.GetAsync(evt.ClientId); var pushSettingsTask = _clientAccountClient.ClientSettings.GetPushNotificationAsync(evt.ClientId); await Task.WhenAll(clientAccTask, personalDataTask, pushSettingsTask); var clientAcc = clientAccTask.Result; var personalData = personalDataTask.Result; var pushSettings = pushSettingsTask.Result; bool pushEnabled = pushSettings.Enabled && !string.IsNullOrEmpty(clientAcc.NotificationsId); Task <EmailMessage> emailTemplateTask = Task.FromResult <EmailMessage>(null); Task <EmailMessage> pushTemplateTask = Task.FromResult <EmailMessage>(null); string type = string.Empty; try { switch (evt.NewStatus) { case KycStatus.Ok: var tierInfo = await _tiersService.GetClientTierInfoAsync(evt.ClientId, clientAcc.Tier, personalData.CountryFromPOA); bool noAmountTemplate = tierInfo.CurrentTier.MaxLimit == 0; string upgradeTemplate = tierInfo.CurrentTier.Tier == AccountTier.Advanced ? "TierUpgradedToProTemplate" : "TierUpgradedTemplate"; emailTemplateTask = _templateFormatter.FormatAsync(noAmountTemplate ? "TierUpgradedNoAmountTemplate" : upgradeTemplate, clientAcc.PartnerId, "EN", new { Tier = evt.Tier.ToString(), Year = DateTime.UtcNow.Year, Amount = $"{tierInfo.CurrentTier.MaxLimit} {tierInfo.CurrentTier.Asset}", //TODO: remove when TierUpgradedTemplate will be updated (@[UpgradeText] removed) UpgradeText = string.Empty }); if (pushEnabled) { pushTemplateTask = _templateFormatter.FormatAsync(noAmountTemplate ? "PushTierUpgradedNoAmountTemplate" : "PushTierUpgradedTemplate", clientAcc.PartnerId, "EN", new { Tier = evt.Tier.ToString(), Amount = $"{tierInfo.CurrentTier.MaxLimit} {tierInfo.CurrentTier.Asset}" }); } type = NotificationType.TierUpgraded.ToString(); break; case KycStatus.NeedToFillData: var documents = await _kycDocumentsService.GetCurrentDocumentsAsync(evt.ClientId); var declinedDocuments = documents .Where(item => item.Status.Name == CheckDocumentPorcess.DeclinedState.Name) .ToArray(); if (declinedDocuments.Length > 0) { string documentsAsHtml = GetDocumentsInfo(declinedDocuments); emailTemplateTask = _templateFormatter.FormatAsync("DeclinedDocumentsTemplate", clientAcc.PartnerId, "EN", new { FullName = personalData.FullName, DocumentsAsHtml = documentsAsHtml, Year = DateTime.UtcNow.Year }); } if (pushEnabled) { pushTemplateTask = _templateFormatter.FormatAsync("PushKycNeedDocumentsTemplate", clientAcc.PartnerId, "EN", new { }); } type = NotificationType.KycNeedToFillDocuments.ToString(); break; case KycStatus.Rejected: emailTemplateTask = _templateFormatter.FormatAsync("TierUpgradeRejectedTemplate", clientAcc.PartnerId, "EN", new { FullName = personalData.FullName, Tier = evt.Tier.ToString(), Year = DateTime.UtcNow.Year }); break; } } finally { await Task.WhenAll(emailTemplateTask, pushTemplateTask); var sendEmailTask = Task.CompletedTask; if (emailTemplateTask.Result != null) { var msgData = new PlainTextData { Sender = personalData.Email, Subject = emailTemplateTask.Result.Subject, Text = emailTemplateTask.Result.HtmlBody }; sendEmailTask = _emailSender.SendEmailAsync(clientAcc.PartnerId, personalData.Email, msgData); } if (pushEnabled && pushTemplateTask.Result != null) { commandSender.SendCommand(new TextNotificationCommand { NotificationIds = new[] { clientAcc.NotificationsId }, Type = type, Message = pushTemplateTask.Result.Subject }, PushNotificationsBoundedContext.Name); } await sendEmailTask; } }
public async Task ChangePhoneAsync(string clientId, string phoneNumber, string changer) { var dataBefore = await _personalDataService.GetAsync(clientId); await _clientAccountsRepository.ChangePhoneAsync(clientId, phoneNumber); await _personalDataService.ChangeContactPhoneAsync(clientId, phoneNumber); var dataAfter = await _personalDataService.GetAsync(clientId); await _auditLogRepository.AddAuditRecordAsync(clientId, dataBefore, dataAfter, AuditRecordType.PersonalData, changer); }
public async Task <IActionResult> Post(PaymentUrlDataRequest model) { if (string.IsNullOrWhiteSpace(model.AssetId)) { model.AssetId = LykkeConstants.UsdAssetId; } var phoneNumberE164 = model.Phone.PreparePhoneNum().ToE164Number(); var countryAsIso3 = _countryComponent.GetCountryIso3Code(model.Country); var pd = await _personalDataService.GetAsync(model.ClientId); CashInPaymentSystem paymentSystem; switch (model.DepositOption) { case DepositOption.BankCard: paymentSystem = CashInPaymentSystem.Fxpaygate; break; case DepositOption.Other: paymentSystem = CashInPaymentSystem.CreditVoucher; break; default: paymentSystem = CashInPaymentSystem.Unknown; break; } var transactionId = await _paymentUrlDataService.GenerateNewTransactionIdAsync(); const string formatOfDateOfBirth = "yyyy-MM-dd"; var info = OtherPaymentInfo.Create( model.FirstName, model.LastName, model.City, model.Zip, model.Address, countryAsIso3, model.Email, phoneNumberE164, pd.DateOfBirth?.ToString(formatOfDateOfBirth), model.OkUrl, model.FailUrl, model.CancelUrl) .ToJson(); var bankCardsFee = await _feeCalculatorClient.GetBankCardFees(); var asset = await _assetsService.AssetGetAsync(model.AssetId); var feeAmount = Math.Round(model.Amount * bankCardsFee.Percentage, 15); var feeAmountTruncated = feeAmount.TruncateDecimalPlaces(asset.Accuracy, true); var urlData = await _paymentUrlDataService.GetUrlDataAsync( paymentSystem.ToString(), transactionId, model.ClientId, model.Amount + feeAmountTruncated, model.AssetId, model.WalletId, countryAsIso3, info); await _paymentTransactionEventLogService.InsertPaymentTransactionEventLogAsync(new PaymentTransactionEventLog { PaymentTransactionId = transactionId, Message = "Payment Url has created", DateTime = DateTime.UtcNow, TechData = urlData.PaymentUrl, Who = model.ClientId }); if (!string.IsNullOrEmpty(urlData.ErrorMessage)) { await _log.WriteWarningAsync(nameof(PaymentUrlDataController), nameof(Post), model.ToJson(), urlData.ErrorMessage, DateTime.UtcNow); return(BadRequest(new { message = urlData.ErrorMessage })); } await _paymentTransactionsService.InsertPaymentTransactionAsync( new PaymentTransaction { Amount = model.Amount, Status = PaymentStatus.Created, PaymentSystem = paymentSystem, FeeAmount = feeAmountTruncated, Id = transactionId, ClientId = model.ClientId, AssetId = model.AssetId, DepositedAssetId = model.AssetId, WalletId = model.WalletId, Created = DateTime.UtcNow, Info = info }); await _paymentTransactionEventLogService.InsertPaymentTransactionEventLogAsync(new PaymentTransactionEventLog { PaymentTransactionId = transactionId, Message = "Registered", DateTime = DateTime.UtcNow, TechData = string.Empty, Who = model.ClientId }); // mode=iframe is for Mobile version if (!string.IsNullOrWhiteSpace(urlData.PaymentUrl)) { urlData.PaymentUrl = urlData.PaymentUrl + (urlData.PaymentUrl.Contains("?") ? "&" : "?") + "mode=iframe"; } var result = new PaymentUrlDataResponse { Url = urlData.PaymentUrl, OkUrl = urlData.OkUrl, FailUrl = urlData.FailUrl, CancelUrl = urlData.CancelUrl, }; return(Ok(result)); }
private async Task <IEnumerable <KycOfficersPerformanceRow> > GenerateKycOfficersPerformance(DateTime from) { var startDate = from; var endDate = DateTime.Today.AddDays(-1); var datesArray = Enumerable.Range(0, 1 + endDate.Subtract(startDate).Days) .Select(offset => startDate.AddDays(offset)) .ToArray(); List <KycStatusLogRecord> auditLogEntities = null; var reportRows = new List <KycOfficersPerformanceRow>(); foreach (var startOfDay in datesArray) { try { var existedJsonRows = await _reportRepository.GetKycOfficersPerformanceJsonRows(startOfDay, startOfDay); if (existedJsonRows.Any()) { continue; } if (auditLogEntities == null) { auditLogEntities = await GetKycStatusLogRecords(startDate, endDate); } var itemsTodayGroups = auditLogEntities.Where(i => i.Date >= startOfDay && i.Date < startOfDay.AddDays(1)) .GroupBy(i => i.KycOfficer) .ToList(); if (!itemsTodayGroups.Any()) { await _reportRepository.InsertRow(KycOfficersPerformanceRow.MakeNoDataRow(startOfDay)); } foreach (var itemsToday in itemsTodayGroups) { var kycOfficer = itemsToday.Key; List <KycOfficersPerformanceRow> onBoarded = new List <KycOfficersPerformanceRow>(); List <KycOfficersPerformanceRow> declined = new List <KycOfficersPerformanceRow>(); List <KycOfficersPerformanceRow> toResubmit = new List <KycOfficersPerformanceRow>(); foreach (var row in itemsToday.OrderBy(i => i.Date)) { if ((row.StatusCurrent == KycStatus.ReviewDone || row.StatusCurrent == KycStatus.Ok) && IsPending(row)) { onBoarded.Add( new KycOfficersPerformanceRow() { ReportDay = startOfDay, KycOfficer = kycOfficer, Operation = KycOfficerReportOperationType.OnBoarded, ClientId = row.ClientId }); } if ((row.StatusCurrent == KycStatus.RestrictedArea || row.StatusCurrent == KycStatus.Rejected) && IsPending(row)) { declined.Add( new KycOfficersPerformanceRow() { ReportDay = startOfDay, KycOfficer = kycOfficer, Operation = KycOfficerReportOperationType.Declined, ClientId = row.ClientId }); } if (row.StatusCurrent == KycStatus.NeedToFillData && IsPending(row)) { toResubmit.Add( new KycOfficersPerformanceRow() { ReportDay = startOfDay, KycOfficer = kycOfficer, Operation = KycOfficerReportOperationType.ToResubmit, ClientId = row.ClientId }); } } reportRows.AddRange(onBoarded); reportRows.AddRange(declined); reportRows.AddRange(toResubmit); if (onBoarded.Count == 0 && declined.Count == 0 && toResubmit.Count == 0) { await _reportRepository.InsertRow(KycOfficersPerformanceRow.MakeNoDataRow(startOfDay)); } } } catch (Exception ex) { await _log.WriteErrorAsync("SrvReports", "GenerateKycOfficersPerformance (process day)", startOfDay.ToString(), ex); } } var clientIds = reportRows.Select(row => row.ClientId).Where(id => !string.IsNullOrEmpty(id)).Distinct(); if (reportRows.Count > 0) { var personalData = (await _personalDataService.GetAsync(clientIds)).ToDictionary(key => key.Id, val => val.Email); foreach (var reportRow in reportRows) { try { reportRow.ClientEmail = string.Empty; if (string.IsNullOrWhiteSpace(reportRow.ClientId)) { continue; } if (personalData.ContainsKey(reportRow.ClientId)) { reportRow.ClientEmail = personalData[reportRow.ClientId]; } await _reportRepository.InsertRow(reportRow); } catch (Exception ex) { await _log.WriteErrorAsync("SrvReports", "GenerateKycOfficersPerformance (insert new rows)", null, ex); } } } return(reportRows); }
public async Task <ClientSwiftCredentials> GetSwiftCredentialsAsync(string clientId, string legalEntityId, string assetId) { var clientSwiftCredentials = await _clientSwiftCredentialsCache.GetAsync(clientId, legalEntityId, assetId); if (clientSwiftCredentials != null) { return(clientSwiftCredentials); } var asset = await _assetsServiceWithCache.TryGetAssetAsync(assetId); if (asset == null) { await _log.WriteWarningAsync(nameof(ClientService), nameof(GetSwiftCredentialsAsync), new { clientId, legalEntityId, assetId }.ToJson(), "Asset not found."); return(null); } var swiftCredentialsList = await _swiftCredentialsRepository.FindAsync(legalEntityId, assetId); if (swiftCredentialsList.Count > 1) { await _log.WriteWarningAsync(nameof(ClientService), nameof(GetSwiftCredentialsAsync), new { legalEntityId, assetId }.ToJson(), "Ambiguous swift credentials."); return(null); } var swiftCredentials = swiftCredentialsList.FirstOrDefault(); if (swiftCredentials == null) { await _log.WriteWarningAsync(nameof(ClientService), nameof(GetSwiftCredentialsAsync), new { clientId, legalEntityId, assetId }.ToJson(), "Swift credentials not found."); return(null); } var personalData = await _personalDataService.GetAsync(clientId); if (personalData == null) { await _log.WriteWarningAsync(nameof(ClientService), nameof(GetSwiftCredentialsAsync), new { clientId, legalEntityId, assetId }.ToJson(), "Personal data not found."); return(null); } var assetTitle = string.IsNullOrEmpty(asset.DisplayId) ? asset.Id : asset.DisplayId; var purposeOfPayment = string.Format(swiftCredentials.PurposeOfPaymentFormat, assetTitle, personalData.Email?.Replace("@", ".")); clientSwiftCredentials = new ClientSwiftCredentials { Bic = swiftCredentials.Bic, AccountName = swiftCredentials.AccountName, AccountNumber = swiftCredentials.AccountNumber, PurposeOfPayment = purposeOfPayment, BankAddress = swiftCredentials.BankAddress, CompanyAddress = swiftCredentials.CompanyAddress, CorrespondentAccount = swiftCredentials.CorrespondentAccount }; await _clientSwiftCredentialsCache.SetAsync(clientId, legalEntityId, assetId, clientSwiftCredentials); return(clientSwiftCredentials); }