private async Task HandleTransferReceived(string[] topics, string data)
        {
            var transferModel = _eventDecoder.DecodeTransferReceivedEvent(topics, data);

            var paymentTransfer = await _paymentTransfersRepository.GetByTransferIdAsync(transferModel.TransferId);

            if (paymentTransfer == null)
            {
                _log.Error(
                    message:
                    $"Payment transfer with id: {transferModel.TransferId} which was just received was not found in DB",
                    context: transferModel);
                return;
            }

            if (paymentTransfer.Status == PaymentTransferStatus.Pending)
            {
                await _transferTokensReservedPublisher.PublishAsync(new PaymentTransferTokensReservedEvent
                {
                    TransferId     = paymentTransfer.TransferId,
                    InvoiceId      = paymentTransfer.InvoiceId,
                    Amount         = paymentTransfer.AmountInTokens,
                    CustomerId     = paymentTransfer.CustomerId,
                    CampaignId     = paymentTransfer.SpendRuleId,
                    Timestamp      = DateTime.UtcNow,
                    InstalmentName = paymentTransfer.InstalmentName,
                    LocationCode   = paymentTransfer.LocationCode,
                });
            }

            var resultError = await _paymentsService.ProcessPaymentTransferAsync(paymentTransfer.TransferId);

            if (resultError != PaymentTransfersErrorCodes.None)
            {
                _log.Error(
                    message:
                    $"Payment transfer with id: {transferModel.TransferId} could not be processed because of error",
                    context: new { transferModel, resultError });
            }
        }
Example #2
0
        public async Task <PaymentTransfersErrorCodes> ProcessPaymentTransferAsync(string transferId)
        {
            if (string.IsNullOrEmpty(transferId))
            {
                _log.Error(message: "TransferId is empty when trying to update payment transfer status");
                throw new ArgumentNullException(nameof(transferId));
            }

            return(await _transactionScopeHandler.WithTransactionAsync(async() =>
            {
                var paymentTransfer = await _paymentTransfersRepository.GetByTransferIdAsync(transferId);
                if (paymentTransfer == null)
                {
                    _log.Warning("Payment transfer not find by transfer id", context: transferId);
                    return PaymentTransfersErrorCodes.PaymentTransferNotFound;
                }

                if (paymentTransfer.Status == PaymentTransferStatus.Processing)
                {
                    return PaymentTransfersErrorCodes.PaymentTransferAlreadyProcessing;
                }

                if (paymentTransfer.Status != PaymentTransferStatus.Pending)
                {
                    _log.Info("Payment transfer's status cannot be updated because it is not in Pending status");
                    return PaymentTransfersErrorCodes.InvalidStatus;
                }

                var walletAddressResponse = await _pbfClient.CustomersApi.GetWalletAddress(Guid.Parse(paymentTransfer.CustomerId));
                if (walletAddressResponse.Error != CustomerWalletAddressError.None)
                {
                    _log.Warning("Customer transfer does not have a BC wallet when payment transfer is being processed");
                    return PaymentTransfersErrorCodes.CustomerWalletDoesNotExist;
                }

                var payInvoiceResponse = await _realEstateIntegrationClient.Api.PayInvoiceAsync(new InvoicePayRequestModel
                {
                    CurrencyCode = paymentTransfer.Currency,
                    ReceiptNumber = paymentTransfer.ReceiptNumber,
                    CustomerAccountNumber = paymentTransfer.CustomerAccountNumber,
                    CustomerTrxId = paymentTransfer.CustomerTrxId,
                    LocationCode = paymentTransfer.LocationCode,
                    InstallmentType = paymentTransfer.InstallmentType,
                    PaidAmount = paymentTransfer.AmountInFiat,
                    OrgId = paymentTransfer.OrgId,
                });

                _log.Info("Pay invoice response",
                          context: new
                {
                    payInvoiceResponse.Status,
                    payInvoiceResponse.ErrorCode,
                    payInvoiceResponse.ReceiptNumber,
                    paymentTransfer.TransferId
                });

                var status = payInvoiceResponse.Status.ToLower() == PaidInvoiceSuccessfullyStatus
                    ? PaymentTransferStatus.Accepted
                    : PaymentTransferStatus.Rejected;

                await CreateApproveOrRejectTransactionInPbf(paymentTransfer.SpendRuleId, paymentTransfer.InvoiceId,
                                                            paymentTransfer.TransferId, status);
                await _paymentTransfersRepository.SetStatusAsync(paymentTransfer.TransferId, PaymentTransferStatus.Processing);

                _log.Info($"Successfully changed payment transfer's status to Processing", transferId);
                return PaymentTransfersErrorCodes.None;
            }));
        }