public async Task Handle()
        {
            try
            {
                if (_address.Orders.Any(o => o.MerchantPayRequestStatus != MerchantPayRequestStatus.InProgress &&
                                        o.MerchantPayRequestStatus != MerchantPayRequestStatus.New))
                {
                    return;
                }
                await _log.WriteInfoAsync($"Handle {_address.Address} orders", _contextName, null);

                if (_address.Orders.All(o => o.MerchantPayRequestStatus == MerchantPayRequestStatus.New))
                {
                    var addressInfo = await GetAddressInfo();

                    if (addressInfo == null)
                    {
                        return;
                    }

                    var coinOperation = addressInfo.Operations.Select(op => op.ReceivedCoins.FirstOrDefault(rc => _address.Address.Equals(rc.Address))).FirstOrDefault();
                    var operation     = addressInfo.Operations.FirstOrDefault(op => op.ReceivedCoins.Any(rc => rc == coinOperation));
                    if (coinOperation == null || operation == null)
                    {
                        return;
                    }
                    var amount = coinOperation.Value / Math.Pow(10, 8);
                    if (Math.Abs(amount) < 0.00000001)
                    {
                        return;
                    }

                    await _log.WriteInfoAsync($"Handle {_address.Address} orders", _contextName, null);


                    var order = _address.Orders.FirstOrDefault(o => o.TransactionWaitingTime.GetRepoDateTime() >
                                                               operation.FirstSeen.ToLocalTime());
                    var isError = true;
                    if (order != null)
                    {
                        await _log.WriteInfoAsync($"Handle {order.OrderId} order", _contextName, null);

                        order.TransactionId            = coinOperation.TransactionId;
                        order.TransactionDetectionTime = operation.FirstSeen.ToLocalTime().RepoDateStr();
                        if (order.Amount.BtcEqualTo(amount))
                        {
                            await _log.WriteInfoAsync("Amounts are equal", _contextName, null);

                            order.TransactionStatus = InvoiceStatus.InProgress.ToString();
                            isError = false;
                        }
                        else
                        {
                            order.TransactionStatus =
                                (order.Amount < amount
                                ? InvoiceStatus.Overpaid
                                : InvoiceStatus.Underpaid).ToString();
                        }

                        order.MerchantPayRequestStatus =
                            isError ? MerchantPayRequestStatus.Failed : MerchantPayRequestStatus.InProgress;
                        order.MerchantPayRequestNotification |=
                            isError
                                ? MerchantPayRequestNotification.Error
                                : MerchantPayRequestNotification.InProgress;
                        order.ETag = "*";
                        await _merchantOrderRequestRepository.SaveRequestAsync(order);
                    }
                    else //LPDEV - 60
                    {
                        order = _address.Orders.First();
                        if (_address.Orders.First().TransactionWaitingTime.GetRepoDateTime() < DateTime.Now)
                        {
                            order.TransactionStatus              = InvoiceStatus.LatePaid.ToString();
                            order.MerchantPayRequestStatus       = MerchantPayRequestStatus.Failed;
                            order.MerchantPayRequestNotification = MerchantPayRequestNotification.Error;
                            order.ETag = "*";
                            await _merchantOrderRequestRepository.SaveRequestAsync(order);
                        }
                    }
                }
                else
                {
                    var transactions =
                        (await _bitcoinAggRepository.GetWalletTransactionsAsync(_address.Address)).ToList();
                    var transaction = transactions.FirstOrDefault();

                    if (transaction != null && transactions.Count == 1)
                    {
                        await _log.WriteInfoAsync(
                            $"Transaction {transaction.TransactionId} was found in {transaction.BlockNumber} block",
                            _contextName, null);

                        var blocks = _rpcClient.GetBlockCount();
                        var order  = _address.Orders.First(
                            o => o.MerchantPayRequestStatus == MerchantPayRequestStatus.InProgress);
                        if (blocks - transaction.BlockNumber >= _settings.NumberOfConfirmations)
                        {
                            order.TransactionStatus               = InvoiceStatus.Paid.ToString();
                            order.MerchantPayRequestStatus        = MerchantPayRequestStatus.Completed;
                            order.MerchantPayRequestNotification |= MerchantPayRequestNotification.Success;
                            order.ETag = "*";
                            await _merchantOrderRequestRepository.SaveRequestAsync(order);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                await _log.WriteErrorAsync($"Can't proceed {_address.Address} orders. Exception.", _contextName, e);
            }
        }
        public async Task <IActionResult> Post([FromBody] OrderRequest request)
        {
            await _merchantOrderRequestRepository.SaveRequestAsync(request);

            return(Content(request.RequestId));
        }
Example #3
0
        private async Task ProcessOrders()
        {
            var orders = await _merchantOrderRepo.GetAllAsync();


            foreach (var r in orders)
            {
                bool needSave = false;
                if ((r.MerchantPayRequestNotification & MerchantPayRequestNotification.Success) ==
                    MerchantPayRequestNotification.Success &&
                    !string.IsNullOrEmpty(r.SuccessUrl))
                {
                    await PostInfo(r.SuccessUrl, JsonConvert.SerializeObject(new PaymentSuccessReturn
                    {
                        PaymentResponse = new PaymentSuccessResponse
                        {
                            TransactionId        = r.TransactionId,
                            Currency             = r.AssetId,
                            NumberOfConfirmation = GetNumberOfConfirmation(r.SourceAddress, r.TransactionId),
                            TimeStamp            = DateTime.UtcNow.Ticks,
                            Url = $"{_settings.LykkePayBaseUrl}transaction/{r.TransactionId}"
                        }
                    }
                                                                             ), BroadcastType.Order, BroadcastMessageType.Success);

                    needSave = true;
                    r.MerchantPayRequestNotification &= ~MerchantPayRequestNotification.Success;
                }

                if ((r.MerchantPayRequestNotification & MerchantPayRequestNotification.InProgress) ==
                    MerchantPayRequestNotification.InProgress &&
                    !string.IsNullOrEmpty(r.ProgressUrl))
                {
                    await PostInfo(r.ProgressUrl, JsonConvert.SerializeObject(new PaymentInProgressReturn
                    {
                        PaymentResponse = new PaymentInProgressResponse
                        {
                            Settlement    = Settlement.TRANSACTION_DETECTED,
                            TimeStamp     = DateTime.UtcNow.Ticks,
                            Currency      = r.AssetId,
                            TransactionId = r.TransactionId
                        }
                    }), BroadcastType.Order, BroadcastMessageType.Process);

                    needSave = true;
                    r.MerchantPayRequestNotification &= ~MerchantPayRequestNotification.InProgress;
                }

                if ((r.MerchantPayRequestNotification & MerchantPayRequestNotification.Error) ==
                    MerchantPayRequestNotification.Error &&
                    !string.IsNullOrEmpty(r.ErrorUrl))
                {
                    var transferStatus = string.IsNullOrEmpty(r.TransactionStatus)
                        ? InvoiceStatus.Unpaid
                        : r.TransactionStatus.ParsePayEnum <InvoiceStatus>();
                    PaymentError paymentError;
                    switch (transferStatus)
                    {
                    case InvoiceStatus.Draft:
                    case InvoiceStatus.InProgress:
                    case InvoiceStatus.Paid:
                    case InvoiceStatus.Removed:
                        paymentError = PaymentError.TRANSACTION_NOT_DETECTED;
                        break;

                    case InvoiceStatus.LatePaid:
                    case InvoiceStatus.Unpaid:
                        paymentError = PaymentError.PAYMENT_EXPIRED;
                        break;

                    case InvoiceStatus.Overpaid:
                        paymentError = PaymentError.AMOUNT_ABOVE;
                        break;

                    case InvoiceStatus.Underpaid:
                        paymentError = PaymentError.AMOUNT_BELOW;
                        break;

                    default:
                        paymentError = PaymentError.TRANSACTION_NOT_DETECTED;
                        break;
                    }
                    await PostInfo(r.ErrorUrl, JsonConvert.SerializeObject(
                                       new PaymentErrorReturn
                    {
                        PaymentResponse = new PaymentErrorResponse
                        {
                            PaymentError = paymentError,
                            TimeStamp    = DateTime.UtcNow.Ticks
                        }
                    }), BroadcastType.Order, BroadcastMessageType.Error);

                    needSave = true;
                    r.MerchantPayRequestNotification &= ~MerchantPayRequestNotification.Error;
                }

                if (needSave)
                {
                    await _merchantOrderRepo.SaveRequestAsync(r);
                }
            }
        }