예제 #1
0
        public async Task <PaymentStatusUpdateErrorCodes> ApproveByCustomerAsync(string paymentRequestId, Money18 sendingAmount, string customerId)
        {
            if (string.IsNullOrEmpty(paymentRequestId))
            {
                throw new ArgumentNullException(nameof(paymentRequestId));
            }

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

            if (sendingAmount <= 0)
            {
                return(PaymentStatusUpdateErrorCodes.InvalidAmount);
            }

            var customerBlockStatusResponse = await _walletManagementClient.Api.GetCustomerWalletBlockStateAsync(customerId);

            if (customerBlockStatusResponse.Status != CustomerWalletActivityStatus.Active)
            {
                return(PaymentStatusUpdateErrorCodes.CustomerWalletIsBlocked);
            }

            return(await _transactionScopeHandler.WithTransactionAsync(async() =>
            {
                var payment = await _paymentsRepository.GetByPaymentRequestIdAsync(paymentRequestId);

                if (payment == null)
                {
                    return PaymentStatusUpdateErrorCodes.PaymentDoesNotExist;
                }

                if (payment.CustomerId != customerId)
                {
                    return PaymentStatusUpdateErrorCodes.CustomerIdDoesNotMatch;
                }

                if (payment.Status != PaymentRequestStatus.Created)
                {
                    return PaymentStatusUpdateErrorCodes.PaymentIsInInvalidStatus;
                }

                if (payment.TokensAmount < sendingAmount)
                {
                    return PaymentStatusUpdateErrorCodes.InvalidAmount;
                }

                var calculatedFiatAmountFromPartnerRate = await CalculateAmountFromPartnerRate(Guid.Parse(payment.CustomerId),
                                                                                               Guid.Parse(payment.PartnerId),
                                                                                               sendingAmount, _tokenSymbol, payment.Currency);

                if (calculatedFiatAmountFromPartnerRate.ErrorCode == EligibilityEngineErrors.PartnerNotFound)
                {
                    return PaymentStatusUpdateErrorCodes.PartnerDoesNotExist;
                }

                if (calculatedFiatAmountFromPartnerRate.ErrorCode == EligibilityEngineErrors.ConversionRateNotFound)
                {
                    return PaymentStatusUpdateErrorCodes.InvalidTokensOrCurrencyRateInPartner;
                }

                payment.Status = PaymentRequestStatus.TokensTransferStarted;
                payment.TokensSendingAmount = sendingAmount;
                payment.FiatSendingAmount = (decimal)calculatedFiatAmountFromPartnerRate.Amount;

                await _paymentsRepository.UpdatePaymentAsync(payment);

                await _statusUpdatePublisher.PublishAsync(new PartnersPaymentStatusUpdatedEvent
                {
                    PaymentRequestId = paymentRequestId,
                    Status = payment.Status.ToContractModel()
                });

                var encodedPaymentData = _blockchainEncodingService.EncodePaymentRequestData(payment.PartnerId,
                                                                                             payment.LocationId, payment.Timestamp.ConvertToLongMs(), payment.CustomerId,
                                                                                             payment.PaymentRequestId);

                var pbfTransferResponse = await _pbfClient.GenericTransfersApi.GenericTransferAsync(
                    new GenericTransferRequestModel
                {
                    Amount = sendingAmount,
                    AdditionalData = encodedPaymentData,
                    RecipientAddress = _settingsService.GetPartnersPaymentsAddress(),
                    SenderCustomerId = customerId,
                    TransferId = paymentRequestId
                });

                if (pbfTransferResponse.Error != TransferError.None)
                {
                    return (PaymentStatusUpdateErrorCodes)pbfTransferResponse.Error;
                }

                await _paymentRequestBlockchainRepository.UpsertAsync(paymentRequestId, pbfTransferResponse.OperationId);
                return PaymentStatusUpdateErrorCodes.None;
            }));
        }