Пример #1
0
        private async Task <ConvertOptimalByPartnerResponse> CalculateAmountFromPartnerRate
            (Guid customerId, Guid partnerId, Money18 amount, string fromCurrency, string toCurrency)
        {
            var convertOptimalByPartnerModel = new ConvertOptimalByPartnerRequest
            {
                CustomerId   = customerId,
                PartnerId    = partnerId,
                Amount       = amount,
                FromCurrency = fromCurrency,
                ToCurrency   = toCurrency
            };

            var convertOptimalByPartnerResponse =
                await _eligibilityEngineClient.ConversionRate.ConvertOptimalByPartnerAsync(convertOptimalByPartnerModel);

            return(convertOptimalByPartnerResponse);
        }
        public async Task <CustomerBalanceResponse> GetCustomerBalanceAsync(string customerId,
                                                                            CustomerBalanceRequest contract)
        {
            ValidateCustomerBalanceRequestData(customerId, contract);

            var response = new CustomerBalanceResponse
            {
                Status = CustomerBalanceStatus.OK
            };

            LocationInfoResponse locationInfoResponse = null;

            if (!string.IsNullOrWhiteSpace(contract.ExternalLocationId))
            {
                locationInfoResponse = await _partnerManagementClient.Locations.GetByExternalId2Async(contract.ExternalLocationId);

                if (locationInfoResponse == null)
                {
                    response.Status = CustomerBalanceStatus.LocationNotFound;
                    return(response);
                }
            }

            var partnerInfo = await _partnerAndLocationHelper.GetPartnerInfo(contract.PartnerId,
                                                                             locationInfoResponse);

            if (partnerInfo.PartnerAndLocationStatus != PartnerAndLocationStatus.OK)
            {
                if (partnerInfo.PartnerAndLocationStatus == PartnerAndLocationStatus.PartnerNotFound)
                {
                    response.Status = CustomerBalanceStatus.PartnerNotFound;
                }
                if (partnerInfo.PartnerAndLocationStatus == PartnerAndLocationStatus.LocationNotFound)
                {
                    response.Status = CustomerBalanceStatus.LocationNotFound;
                }

                return(response);
            }

            var customer = await _customerProfileClient.CustomerProfiles.GetByCustomerIdAsync(customerId);

            if (customer.ErrorCode == CustomerProfileErrorCodes.CustomerProfileDoesNotExist)
            {
                _log.Warning($"Customer not found with id: {customerId}", null, customerId);
                response.Status = CustomerBalanceStatus.CustomerNotFound;
                return(response);
            }

            var isValid = Guid.TryParse(customerId, out var customerIdGuid);

            if (!isValid)
            {
                _log.Warning($"Invalid customer guid id: {customerId}", null, customerId);
                response.Status = CustomerBalanceStatus.CustomerNotFound;
                return(response);
            }

            var customerBalance = await _privateBlockchainFacadeClient.CustomersApi.GetBalanceAsync(customerIdGuid);

            if (customerBalance.Error != CustomerBalanceError.None)
            {
                _log.Error(null, "Could not get customer balance", customerIdGuid);
                response.Status = CustomerBalanceStatus.CustomerNotFound;
                return(response);
            }

            response.Tokens = customerBalance.Total;

            var optimalCurrencyRateByPartnerRequest = new ConvertOptimalByPartnerRequest
            {
                CustomerId   = customerIdGuid,
                PartnerId    = Guid.Parse(contract.PartnerId),
                FromCurrency = MVNCurrencyCode,
                ToCurrency   = contract.Currency,
                Amount       = customerBalance.Total
            };

            var conversionResponse =
                await _eligibilityEngineClient.ConversionRate.ConvertOptimalByPartnerAsync(
                    optimalCurrencyRateByPartnerRequest);

            if (conversionResponse.ErrorCode != EligibilityEngineErrors.None)
            {
                _log.Error(null, "Could not get currency rate", optimalCurrencyRateByPartnerRequest);
                response.Status = _mapper.Map <CustomerBalanceStatus>(conversionResponse.ErrorCode);
                return(response);
            }

            response.FiatBalance = decimal.Parse(conversionResponse.Amount.ToString(),
                                                 CultureInfo.InvariantCulture);
            response.FiatCurrency = contract.Currency;

            return(response);
        }
Пример #3
0
        public async Task <PaymentRequestResult> InitiatePartnerPaymentAsync(IPaymentRequest paymentRequest)
        {
            #region Validation

            if (string.IsNullOrEmpty(paymentRequest.CustomerId))
            {
                throw new ArgumentNullException(nameof(paymentRequest.CustomerId));
            }

            if (string.IsNullOrEmpty(paymentRequest.PartnerId))
            {
                throw new ArgumentNullException(nameof(paymentRequest.PartnerId));
            }

            if (string.IsNullOrEmpty(paymentRequest.Currency))
            {
                throw new ArgumentNullException(nameof(paymentRequest.Currency));
            }

            var isPartnerIdValidGuid = Guid.TryParse(paymentRequest.PartnerId, out var partnerId);

            if (!isPartnerIdValidGuid)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.PartnerIdIsNotAValidGuid));
            }

            var isCustomerIdValidGuid = Guid.TryParse(paymentRequest.CustomerId, out var customerGuid);

            if (!isCustomerIdValidGuid)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.CustomerIdIsNotAValidGuid));
            }

            //We can have either amount in Tokens or in Fiat
            if (paymentRequest.FiatAmount != null && paymentRequest.TokensAmount != null)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.CannotPassBothFiatAndTokensAmount));
            }

            //Fiat or Tokens Amount must be provided
            if (paymentRequest.FiatAmount == null && paymentRequest.TokensAmount == null)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.EitherFiatOrTokensAmountShouldBePassed));
            }

            if (paymentRequest.TokensAmount != null && paymentRequest.TokensAmount <= 0)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.InvalidTokensAmount));
            }

            if (paymentRequest.FiatAmount != null && paymentRequest.FiatAmount <= 0)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.InvalidFiatAmount));
            }

            if (paymentRequest.TotalBillAmount <= 0)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.InvalidTotalBillAmount));
            }

            var customerProfile = await _customerProfileClient.CustomerProfiles.GetByCustomerIdAsync(paymentRequest.CustomerId);

            if (customerProfile.ErrorCode == CustomerProfileErrorCodes.CustomerProfileDoesNotExist)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.CustomerDoesNotExist));
            }

            var customerWalletStatus =
                await _walletManagementClient.Api.GetCustomerWalletBlockStateAsync(paymentRequest.CustomerId);

            if (customerWalletStatus.Status == CustomerWalletActivityStatus.Blocked)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.CustomerWalletBlocked));
            }

            var partnerDetails = await _partnerManagementClient.Partners.GetByIdAsync(partnerId);

            if (partnerDetails == null)
            {
                return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.PartnerDoesNotExist));
            }

            if (!string.IsNullOrEmpty(paymentRequest.LocationId))
            {
                if (partnerDetails.Locations.All(x => x.Id.ToString() != paymentRequest.LocationId))
                {
                    return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.NoSuchLocationForThisPartner));
                }
            }

            #endregion

            var paymentRequestId = Guid.NewGuid().ToString();

            paymentRequest.PaymentRequestId = paymentRequestId;

            //Blockchain does not accept null
            if (paymentRequest.LocationId == null)
            {
                paymentRequest.LocationId = "";
            }

            var convertOptimalByPartnerModel = new ConvertOptimalByPartnerRequest
            {
                CustomerId   = customerGuid,
                PartnerId    = partnerId,
                Amount       = paymentRequest.TokensAmount ?? paymentRequest.FiatAmount.Value,
                FromCurrency = paymentRequest.TokensAmount.HasValue ? _tokenSymbol : paymentRequest.Currency,
                ToCurrency   = paymentRequest.TokensAmount.HasValue ? paymentRequest.Currency : _tokenSymbol
            };

            var convertOptimalByPartnerResponse =
                await _eligibilityEngineClient.ConversionRate.ConvertOptimalByPartnerAsync(convertOptimalByPartnerModel);

            if (convertOptimalByPartnerResponse.ErrorCode != EligibilityEngineErrors.None)
            {
                if (convertOptimalByPartnerResponse.ErrorCode == EligibilityEngineErrors.PartnerNotFound)
                {
                    return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.PartnerDoesNotExist));
                }
                if (convertOptimalByPartnerResponse.ErrorCode == EligibilityEngineErrors.ConversionRateNotFound)
                {
                    return(PaymentRequestResult.Failed(PaymentRequestErrorCodes.InvalidTokensOrCurrencyRateInPartner));
                }
            }

            paymentRequest.TokensToFiatConversionRate = convertOptimalByPartnerResponse.UsedRate;

            if (paymentRequest.FiatAmount == null)
            {
                paymentRequest.FiatAmount = (decimal)convertOptimalByPartnerResponse.Amount;
            }
            else
            {
                paymentRequest.TokensAmount = convertOptimalByPartnerResponse.Amount;
            }

            var now = DateTime.UtcNow;
            paymentRequest.CustomerActionExpirationTimestamp = paymentRequest.CustomerExpirationInSeconds.HasValue
                ? now.AddSeconds(paymentRequest.CustomerExpirationInSeconds.Value)
                : now.Add(_settingsService.GetRequestsExpirationPeriod());

            await _paymentsRepository.AddAsync(paymentRequest);

            await _paymentRequestCreatedPublisher.PublishAsync(new PartnerPaymentRequestCreatedEvent
            {
                PaymentRequestId = paymentRequestId,
                CustomerId       = paymentRequest.CustomerId,
                PartnerId        = paymentRequest.PartnerId,
                Timestamp        = DateTime.UtcNow
            });

            return(PaymentRequestResult.Succeeded(PaymentRequestStatus.Created, paymentRequestId));
        }
        public async Task <ConvertOptimalByPartnerResponse> ConvertOptimalByPartnerAsync(ConvertOptimalByPartnerRequest request)
        {
            if (request.FromCurrency.ToLower() == request.ToCurrency.ToLower())
            {
                return(new ConvertOptimalByPartnerResponse
                {
                    ConversionSource = ConversionSource.Partner,
                    Amount = request.Amount,
                    UsedRate = 1
                });
            }

            OptimalAmountConvertResponse result;

            try
            {
                result = await _conversionRateService.ConvertOptimalByPartnerAsync(
                    request.PartnerId, request.CustomerId, request.FromCurrency, request.ToCurrency, request.Amount);
            }
            catch (PartnerNotFoundException e)
            {
                _log.Info(e.Message, context: request);

                return(new ConvertOptimalByPartnerResponse
                {
                    ErrorCode = EligibilityEngineErrors.PartnerNotFound,
                    ErrorMessage = e.Message
                });
            }
            catch (ConversionRateNotFoundException e)
            {
                _log.Info(e.Message, context: request);

                return(new ConvertOptimalByPartnerResponse
                {
                    ErrorCode = EligibilityEngineErrors.ConversionRateNotFound,
                    ErrorMessage = e.Message
                });
            }

            return(new ConvertOptimalByPartnerResponse
            {
                Amount = result.Amount,
                CurrencyCode = result.CurrencyCode,
                UsedRate = result.UsedRate,
                ConversionSource = Mapper.Map <ConversionSource>(result.ConversionSource),
                SpendRuleId = result.SpendRuleId
            });
        }