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; })); }