public async Task <bool> NotifyAsOkAsync(string transactionId, string paymentSystemTransactionId, string sourceClientId, string who)
        {
            var pt =
                await
                _paymentTransactionsRepository.StartProcessingTransactionAsync(transactionId,
                                                                               paymentSystemTransactionId);

            if (pt == null)
            {
                await
                _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(transactionId, "N/A",
                                                                                          "Transaction not found or already processed", who));

                return(false);
            }

            await _srvBitcoinCommandProducer.TransferBetweenClientsWithNotification(pt.ClientId, sourceClientId,
                                                                                    pt.Amount, pt.AssetId);

            var resultTransaction = await
                                    _paymentTransactionsRepository.SetAsOkAsync(transactionId, pt.Amount, null);

            await
            _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(transactionId, "",
                                                                                      "Transaction processed as Ok", who));

            foreach (var notification in _paymentOkNotifications)
            {
                await notification.NotifyAsync(resultTransaction);
            }

            return(true);
        }
Ejemplo n.º 2
0
        public async Task Handle(TransferProcessedEvent evt)
        {
            ChaosKitty.Meow();

            await _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(
                                                              transactionId: evt.TransferId,
                                                              techData: "",
                                                              message: "Confirmed",
                                                              who: "Tx Detector"));
        }
Ejemplo n.º 3
0
        public async Task <CommandHandlingResult> Handle(CompleteTransferCommand cmd, IEventPublisher eventPublisher)
        {
            await _paymentTransactionsRepository.SetAsOkAsync(cmd.Id, cmd.Amount, null);

            await _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(cmd.Id, "", "Transaction processed as Ok", nameof(CompleteTransferCommand)));

            eventPublisher.PublishEvent(new TransferCompletedEvent {
                OrderId = cmd.Id
            });

            return(CommandHandlingResult.Ok());
        }
        public async Task <CommandHandlingResult> Handle(CreateTransferCommand createTransferCommand, IEventPublisher eventPublisher)
        {
            if (await _antiFraudChecker.IsPaymentSuspicious(createTransferCommand.ClientId, createTransferCommand.OrderId))
            {
                return(new CommandHandlingResult {
                    Retry = true, RetryDelay = (long)TimeSpan.FromMinutes(10).TotalMilliseconds
                });
            }

            var bankCardFees = await _feeCalculatorClient.GetBankCardFees();

            var result = await _exchangeOperationsService.TransferWithNotificationAsync(
                transferId : createTransferCommand.TransferId,
                destClientId : createTransferCommand.ClientId,
                sourceClientId : createTransferCommand.SourceClientId,
                amount : createTransferCommand.Amount,
                assetId : createTransferCommand.AssetId,
                feeClientId : _bankCardFeeClientId,
                feeSizePercentage : bankCardFees.Percentage,
                destWalletId : createTransferCommand.WalletId);

            if (!result.IsOk())
            {
                await _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(createTransferCommand.OrderId, "N/A", $"{result.Code}:{result.Message}", nameof(CreateTransferCommand)));

                return(CommandHandlingResult.Ok());
            }

            eventPublisher.PublishEvent(new TransferCreatedEvent
            {
                OrderId    = createTransferCommand.OrderId,
                TransferId = createTransferCommand.TransferId,
                ClientId   = createTransferCommand.ClientId,
                Amount     = createTransferCommand.Amount,
                AssetId    = createTransferCommand.AssetId
            });

            return(CommandHandlingResult.Ok());
        }
Ejemplo n.º 5
0
        public async Task <CommandHandlingResult> Handle(CashInCommand command, IEventPublisher eventPublisher)
        {
            var tx = await _paymentTransactionsRepository.GetByTransactionIdAsync(command.TransactionId);

            if (tx != null && (tx.Status == PaymentStatus.NotifyDeclined || tx.Status == PaymentStatus.NotifyProcessed || tx.Status == PaymentStatus.Processing))
            {
                return(CommandHandlingResult.Ok());
            }

            var transactionStatus = await _link4PayApiService.GetTransactionInfoAsync(command.TransactionId);

            if (!string.IsNullOrEmpty(transactionStatus.Card?.CardHash) && transactionStatus.OriginalTxnStatus == TransactionStatus.Successful)
            {
                await _paymentTransactionsRepository.SaveCardHashAsync(command.TransactionId, transactionStatus.Card.CardHash);

                if (tx != null)
                {
                    var evt = new CreditCardUsedEvent
                    {
                        ClientId     = tx.ClientId,
                        OrderId      = command.TransactionId,
                        CardHash     = transactionStatus.Card.CardHash,
                        CardNumber   = transactionStatus.Card.CardNo,
                        CustomerName = transactionStatus.Card.CardHolderName
                    };

                    eventPublisher.PublishEvent(evt);
                }
                else
                {
                    _log.Warning("CreditCardUsedEvent is not sent!", context: new { tranasactionId = transactionStatus.TxnReference }.ToJson());
                }
            }

            switch (transactionStatus.OriginalTxnStatus)
            {
            case TransactionStatus.Successful:
                tx = await _paymentTransactionsRepository.StartProcessingTransactionAsync(command.TransactionId);

                if (tx != null)     // initial status
                {
                    eventPublisher.PublishEvent(new ProcessingStartedEvent
                    {
                        OrderId = command.TransactionId
                    });
                }

                return(CommandHandlingResult.Ok());

            case TransactionStatus.Failed:
                await _paymentTransactionsRepository.SetStatusAsync(command.TransactionId, PaymentStatus.NotifyDeclined);

                await _paymentTransactionEventsLog.WriteAsync(
                    PaymentTransactionLogEvent.Create(
                        command.TransactionId, command.Request, "Declined by Payment status from payment system", nameof(CashInCommand)));

                return(CommandHandlingResult.Ok());

            default:
                return(new CommandHandlingResult {
                    Retry = true, RetryDelay = (long)TimeSpan.FromMinutes(1).TotalMilliseconds
                });
            }
        }
Ejemplo n.º 6
0
        public override async Task <PaymentUrlResponse> GetPaymentUrl(PaymentUrlRequest request, ServerCallContext context)
        {
            try
            {
                string errorMessage = string.Empty;
                ErrorDetails.Types.ErrorType?errorType = null;

                if (_supportedCurrencies.Any() && !_supportedCurrencies.Contains(request.Transaction.AssetId))
                {
                    errorMessage = $"Asset {request.Transaction.AssetId} is not supported";
                    errorType    = ErrorDetails.Types.ErrorType.CurrencyNotSupported;
                }

                if (_supportedCountries.Any() && !string.IsNullOrEmpty(request.Details.CountryIso3) && !_supportedCountries.Contains(request.Details.CountryIso3))
                {
                    errorMessage = $"Country {request.Details.CountryIso3} is not supported";
                    errorType    = ErrorDetails.Types.ErrorType.CountryNotSupported;
                }

                if (errorType != null)
                {
                    _log.Warning(errorMessage);

                    return(new PaymentUrlResponse
                    {
                        Error = new ErrorDetails
                        {
                            ErrorType = errorType.Value,
                            Message = errorMessage
                        }
                    });
                }

                var bankCardsFees = await _feeCalculatorClient.GetBankCardFees();

                var feeAmount   = Math.Round(request.Transaction.Amount * bankCardsFees.Percentage, 15);
                var totalAmount = (decimal)request.Transaction.Amount + (decimal)feeAmount;

                var url = await _link4PayApiService.GetPaymentUrlAsync(new CardPaymentRequest
                {
                    Merchant = new MerchantInfo {
                        CustomerId = request.Transaction.ExternalClientId, MerchantId = _link4PaySettings.ClientId
                    },
                    Transaction =
                        new TransactionInfo
                    {
                        TxnAmount    = totalAmount.ToString("F2"),
                        CurrencyCode = request.Transaction.AssetId,
                        TxnReference = request.Transaction.TransactionId,
                        Payout       = false
                    },
                    Customer = new CustomerInfo
                    {
                        BillingAddress = new AddressInfo
                        {
                            FirstName = request.Details?.FirstName,
                            LastName  = request.Details?.LastName,
                            EmailId   = request.Details?.Email,
                            MobileNo  = request.Details?.Phone
                        }
                    },
                    Url = new UrlInfo
                    {
                        SuccessUrl = $"{(string.IsNullOrEmpty(request.Urls?.OkUrl?.Trim()) ? _successUrl : request.Urls?.OkUrl)}?v=1",
                        FailUrl    = string.IsNullOrEmpty(request.Urls?.FailUrl?.Trim())
                            ? _failUrl
                            : request.Urls?.FailUrl,
                        CancelUrl = string.IsNullOrEmpty(request.Urls?.CancelUrl?.Trim())
                            ? _cancelUrl
                            : request.Urls?.CancelUrl
                    }
                });

                if (string.IsNullOrEmpty(url))
                {
                    return(new PaymentUrlResponse
                    {
                        Error = new ErrorDetails
                        {
                            ErrorType = ErrorDetails.Types.ErrorType.Unknown,
                            Message = "Error getting the payment url"
                        }
                    });
                }

                await _rawLogRepository.RegisterEventAsync(
                    RawLogEvent.Create("Payment Url has been created", request.ToJson()),
                    request.Transaction.ClientId);

                var info = OtherPaymentInfo.Create(
                    firstName: request.Details.FirstName,
                    lastName: request.Details.LastName,
                    city: string.Empty,
                    zip: string.Empty,
                    address: string.Empty,
                    country: request.Details.CountryIso3,
                    email: request.Details.Email,
                    contactPhone: request.Details.Phone,
                    dateOfBirth: string.Empty)
                           .ToJson();

                var pt = PaymentTransaction.Create(
                    request.Transaction.TransactionId,
                    CashInPaymentSystem.Link4Pay,
                    request.Transaction.ClientId,
                    request.Transaction.Amount,
                    feeAmount,
                    request.Transaction.AssetId,
                    null,
                    request.Transaction.AssetId,
                    info
                    );

                await Task.WhenAll(
                    _paymentTransactionsRepository.CreateAsync(pt),
                    _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(request.Transaction.TransactionId, "",
                                                                                              "Registered", request.Transaction.ClientId)),
                    _paymentTransactionEventsLog.WriteAsync(PaymentTransactionLogEvent.Create(request.Transaction.TransactionId, url,
                                                                                              "Payment Url has created", request.Transaction.ClientId))
                    );

                return(new PaymentUrlResponse
                {
                    PaymentUrl = url,
                    OkUrl = $"{(string.IsNullOrEmpty(request.Urls?.OkUrl?.Trim()) ? _successUrl : request.Urls?.OkUrl)}?v=1",
                    FailUrl = string.IsNullOrEmpty(request.Urls?.FailUrl?.Trim())
                        ? _failUrl
                        : request.Urls?.FailUrl,
                    CancelUrl = string.IsNullOrEmpty(request.Urls?.CancelUrl?.Trim())
                        ? _cancelUrl
                        : request.Urls?.CancelUrl
                });
            }
            catch (Exception ex)
            {
                _log.Error(ex);

                return(new PaymentUrlResponse
                {
                    Error = new ErrorDetails
                    {
                        ErrorType = ErrorDetails.Types.ErrorType.Unknown,
                        Message = "Error getting the payment url"
                    }
                });
            }
        }