Esempio n. 1
0
        private async Task <PaymentModel> GetPaymentRequest(string paymentRequestId)
        {
            var partnerPayment = await _paymentsRepository.GetByPaymentRequestIdAsync(paymentRequestId);

            if (partnerPayment == null)
            {
                throw new InvalidOperationException(
                          $"Partner Payment with id: {paymentRequestId} which was just processed was not found in DB");
            }

            return(partnerPayment);
        }
Esempio n. 2
0
        public async Task <PaymentModel> GetPaymentDetailsByPaymentId(string paymentRequestId)
        {
            if (string.IsNullOrEmpty(paymentRequestId))
            {
                throw new ArgumentNullException(nameof(paymentRequestId));
            }

            var payment = await _paymentsRepository.GetByPaymentRequestIdAsync(paymentRequestId);

            if (payment == null)
            {
                return(null);
            }

            payment.CustomerActionExpirationTimeLeftInSeconds = payment.Status == PaymentRequestStatus.Created
                ? CalculateCustomerActionExpirationTimeLeftInSeconds(payment.CustomerActionExpirationTimestamp)
                : 0;

            return(payment);
        }
Esempio n. 3
0
        public async Task HandleAsync(string operationId)
        {
            var requestBlockchainData = await _paymentRequestBlockchainRepository.GetByOperationIdAsync(operationId);

            if (requestBlockchainData == null)
            {
                return;
            }

            var paymentRequestId = requestBlockchainData.PaymentRequestId;

            var paymentRequest = await _paymentsRepository.GetByPaymentRequestIdAsync(paymentRequestId);

            switch (paymentRequest.Status)
            {
            case PaymentRequestStatus.TokensTransferStarted:
                var transferFailResult =
                    await _paymentsStatusUpdater.TokensTransferFailAsync(paymentRequestId);

                if (transferFailResult != PaymentStatusUpdateErrorCodes.None)
                {
                    _log.Error(
                        message: "Could not change payment request status to TokensTransferFailed because of error",
                        context: new
                    {
                        PaymentRequestId = paymentRequestId,
                        Error            = transferFailResult
                    });
                }
                break;

            case PaymentRequestStatus.TokensBurnStarted:
                var burnFailResult =
                    await _paymentsStatusUpdater.TokensBurnFailAsync(paymentRequestId);

                if (burnFailResult != PaymentStatusUpdateErrorCodes.None)
                {
                    _log.Error(message: "Could not change payment request status to TokensBurnFailed because of error",
                               context: new
                    {
                        PaymentRequestId = paymentRequestId,
                        Error            = burnFailResult
                    });
                }
                break;

            case PaymentRequestStatus.TokensRefundStarted:
            case PaymentRequestStatus.ExpirationTokensRefundStarted:
                var refundFailResult =
                    await _paymentsStatusUpdater.TokensRefundFailAsync(paymentRequestId);

                if (refundFailResult != PaymentStatusUpdateErrorCodes.None)
                {
                    _log.Error(
                        message:
                        "Could not change payment request status to TokensRefundFailed/ExpirationTokensRefundFailed because of error",
                        context: new { PaymentRequestId = paymentRequestId, Error = refundFailResult });
                }
                break;

            default:
                _log.Error(
                    message:
                    "Cannot change payment request status to failed because it is not in the appropriate status",
                    context: new
                {
                    PaymentRequestId = paymentRequestId,
                    CurrentStatus    = paymentRequest.Status
                });
                break;
            }
        }
Esempio n. 4
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;
            }));
        }