コード例 #1
0
        public async Task <IActionResult> GetDetailsAsync(string merchantId, string paymentRequestId)
        {
            try
            {
                IPaymentRequest paymentRequest = await _paymentRequestService.GetAsync(merchantId, paymentRequestId);

                if (paymentRequest == null)
                {
                    return(NotFound(ErrorResponse.Create("Could not find payment request")));
                }

                PaymentRequestRefund refundInfo =
                    await _paymentRequestService.GetRefundInfoAsync(paymentRequest.WalletAddress);

                PaymentRequestDetailsModel model = await _paymentRequestDetailsBuilder.Build <
                    PaymentRequestDetailsModel,
                    PaymentRequestOrderModel,
                    PaymentRequestTransactionModel,
                    PaymentRequestRefundModel>(paymentRequest, refundInfo);

                return(Ok(model));
            }
            catch (Exception ex)
            {
                await _log.WriteErrorAsync(nameof(GetDetailsAsync),
                                           new
                {
                    MerchantId       = merchantId,
                    PaymentRequestId = paymentRequestId
                }.ToJson(), ex);

                throw;
            }
        }
コード例 #2
0
        public async Task <IActionResult> GetRefundData([Guid] string paymentRequestId)
        {
            try
            {
                PaymentRequestDetailsModel paymentRequestDetails = await _payInternalClient.GetPaymentRequestDetailsAsync(User.GetMerchantId(), paymentRequestId);

                if (!IsStatusValidForRefund(paymentRequestDetails.Status, paymentRequestDetails.ProcessingError))
                {
                    _log.Warning("Attempt to refund in incorrect status, details: " + paymentRequestDetails.ToJson());

                    return(BadRequest(ErrorResponse.Create(RefundErrorType.NotAllowedInStatus.ToString())));
                }

                var paymentAsset = await _lykkeAssetsResolver.TryGetAssetAsync(paymentRequestDetails.PaymentAssetId);

                var refundData = new RefundDataResponse
                {
                    PaymentAsset          = Mapper.Map <AssetModel>(paymentAsset),
                    SourceWalletAddresses = paymentRequestDetails.Transactions.SelectMany(x => x.SourceWalletAddresses).ToList(),
                    Amount = paymentRequestDetails.Transactions.Sum(x => x.Amount)
                };

                return(Ok(refundData));
            }
            catch (Exception ex)
            {
                _log.ErrorWithDetails(ex, details: new { paymentRequestId });

                return(BadRequest(ErrorResponse.Create(PayInvoicePortalApiErrorCodes.UnexpectedError)));
            }

            bool IsStatusValidForRefund(PaymentRequestStatus status, PaymentRequestProcessingError processingError)
            {
                var invoiceStatus = status.ToInvoiceStatus(processingError);

                switch (invoiceStatus)
                {
                case InvoiceStatus.Underpaid:
                case InvoiceStatus.Overpaid:
                case InvoiceStatus.LatePaid:
                    return(true);

                default:
                    return(false);
                }
            }
        }
コード例 #3
0
        public async Task <IActionResult> CreatePaymentRequest([FromBody] CreatePaymentRequestModel request)
        {
            if (string.IsNullOrWhiteSpace(request.SettlementAsset))
            {
                return(BadRequest(PaymentErrorResponseModel.Create(PaymentErrorType.InvalidSettlementAsset)));
            }

            if (string.IsNullOrWhiteSpace(request.PaymentAsset))
            {
                return(BadRequest(PaymentErrorResponseModel.Create(PaymentErrorType.InvalidPaymentAsset)));
            }

            try
            {
                var domainRequest =
                    Mapper.Map <CreatePaymentRequest>(request,
                                                      opt => opt.Items["MerchantId"] = _headersHelper.MerchantId);

                CreatePaymentResponse createResponse =
                    await _paymentRequestService.CreatePaymentRequestAsync(domainRequest);

                PaymentRequestDetailsModel paymentRequestDetails =
                    await _paymentRequestService.GetPaymentRequestDetailsAsync(_headersHelper.MerchantId,
                                                                               createResponse.Id);

                return(Ok(paymentRequestDetails.ToStatusApiModel()));
            }
            catch (InvalidSettlementAssetException ex)
            {
                _log.Error(ex, null, $"request: {request.ToJson()}");

                return(BadRequest(PaymentErrorResponseModel.Create(PaymentErrorType.InvalidSettlementAsset)));
            }
            catch (InvalidPaymentAssetException ex)
            {
                _log.Error(ex, null, $"request: {request.ToJson()}");

                return(BadRequest(PaymentErrorResponseModel.Create(PaymentErrorType.InvalidPaymentAsset)));
            }
            catch (Exception ex)
            {
                _log.Error(ex, null, $"request: {request.ToJson()}");

                throw;
            }
        }
コード例 #4
0
        public async Task <IActionResult> GetDetailsAsync(
            [Required, RowKey] string merchantId,
            [Required, RowKey] string paymentRequestId)
        {
            IPaymentRequest paymentRequest = await _paymentRequestService.GetAsync(merchantId, paymentRequestId);

            if (paymentRequest == null)
            {
                return(NotFound(ErrorResponse.Create("Could not find payment request")));
            }

            PaymentRequestRefund refundInfo =
                await _paymentRequestService.GetRefundInfoAsync(paymentRequest.WalletAddress);

            PaymentRequestDetailsModel model = await _paymentRequestDetailsBuilder.Build <
                PaymentRequestDetailsModel,
                PaymentRequestOrderModel,
                PaymentRequestTransactionModel,
                PaymentRequestRefundModel>(paymentRequest, refundInfo);

            return(Ok(model));
        }
コード例 #5
0
        public async Task <IActionResult> Refund(string paymentRequestId, [FromQuery] string destinationAddress)
        {
            if (!paymentRequestId.IsValidPaymentRequestId())
            {
                return(BadRequest(PaymentErrorResponseModel.Create(PaymentErrorType.InvalidPaymentId)));
            }

            try
            {
                PaymentRequestDetailsModel paymentRequestDetails = await _paymentRequestService.RefundAsync(
                    new RefundRequest
                {
                    MerchantId         = _headersHelper.MerchantId,
                    PaymentRequestId   = paymentRequestId,
                    DestinationAddress = destinationAddress
                });

                return(Ok(paymentRequestDetails.ToStatusApiModel()));
            }
            catch (Exception ex)
            {
                _log.Error(ex, null, $@"request: {
                        new
                        {
                            paymentRequestId,
                            destinationAddress
                        }.ToJson()
                    }");

                if (ex is PayInternal.Client.Exceptions.RefundErrorResponseException refundEx)
                {
                    return(BadRequest(refundEx.ToErrorModel()));
                }

                return(BadRequest(PaymentErrorResponseModel.Create(PaymentErrorType.RefundIsNotAvailable)));
            }
        }
コード例 #6
0
        public static PaymentStatusResponseModel ToStatusApiModel(this PaymentRequestDetailsModel src)
        {
            PaymentStatusResponseModel response = new PaymentStatusResponseModel
            {
                Id              = src.Id,
                PaymentAsset    = src.PaymentAssetId,
                SettlementAsset = src.SettlementAssetId,
                OrderId         = src.OrderId,
                PaymentRequest  = new PaymentRequestResponseModel
                {
                    Amount       = src.Order?.PaymentAmount,
                    Address      = src.WalletAddress,
                    CreatedAt    = src.Timestamp.ToIsoDateTime(),
                    ExchangeRate = src.Order?.ExchangeRate,
                    ExpirationDt = src.DueDate.ToIsoDateTime(),
                    Transactions = src.Transactions.Any()
                        ? src.Transactions.Select(Mapper.Map <PaymentResponseTransactionModel>).ToList()
                        : null
                }
            };

            switch (src.Status)
            {
            case PaymentRequestStatus.New:

                response.PaymentStatus = PaymentRequestPublicStatuses.PaymentRequestCreated;

                break;

            case PaymentRequestStatus.Confirmed:

                response.PaymentStatus = PaymentRequestPublicStatuses.PaymentConfirmed;

                break;

            case PaymentRequestStatus.InProcess:

                response.PaymentStatus = PaymentRequestPublicStatuses.PaymentInProgress;

                break;

            case PaymentRequestStatus.Cancelled:

                response.PaymentStatus = PaymentRequestPublicStatuses.PaymentCancelled;

                break;

            case PaymentRequestStatus.Error:

                switch (src.ProcessingError)
                {
                case PaymentRequestProcessingError.PaymentAmountAbove:

                    response.PaymentStatus = PaymentRequestPublicStatuses.PaymentError;

                    response.Error = new ErrorResponseModel
                    {
                        Code = PaymentRequestErrorPublicCodes.PaymentAmountAbove
                    };

                    break;

                case PaymentRequestProcessingError.PaymentAmountBelow:

                    response.PaymentStatus = PaymentRequestPublicStatuses.PaymentError;

                    response.Error = new ErrorResponseModel
                    {
                        Code = PaymentRequestErrorPublicCodes.PaymentAmountBelow
                    };

                    break;

                case PaymentRequestProcessingError.PaymentExpired:

                    response.PaymentStatus = PaymentRequestPublicStatuses.PaymentError;

                    response.Error = new ErrorResponseModel
                    {
                        Code = PaymentRequestErrorPublicCodes.PaymentExpired
                    };

                    break;

                case PaymentRequestProcessingError.RefundNotConfirmed:

                    response.PaymentStatus = PaymentRequestPublicStatuses.RefundError;

                    response.RefundRequest = Mapper.Map <RefundRequestResponseModel>(src.Refund);

                    response.Error = new ErrorResponseModel
                    {
                        Code = PaymentRequestErrorPublicCodes.TransactionNotConfirmed
                    };

                    break;

                case PaymentRequestProcessingError.LatePaid:

                    response.PaymentStatus = PaymentRequestPublicStatuses.PaymentError;

                    response.Error = new ErrorResponseModel
                    {
                        Code = PaymentRequestErrorPublicCodes.LatePaid
                    };

                    break;

                case PaymentRequestProcessingError.UnknownPayment:

                    response.PaymentStatus = PaymentRequestPublicStatuses.PaymentError;

                    break;

                case PaymentRequestProcessingError.UnknownRefund:

                    response.PaymentStatus = PaymentRequestPublicStatuses.RefundError;

                    response.RefundRequest = Mapper.Map <RefundRequestResponseModel>(src.Refund);

                    response.Error = new ErrorResponseModel
                    {
                        Code = PaymentRequestErrorPublicCodes.RefundIsNotAvailable
                    };

                    break;

                default:
                    throw new Exception("Unknown payment request error type");
                }

                break;

            case PaymentRequestStatus.RefundInProgress:

                response.PaymentStatus = PaymentRequestPublicStatuses.RefundInProgress;

                response.RefundRequest = Mapper.Map <RefundRequestResponseModel>(src.Refund);

                break;

            case PaymentRequestStatus.Refunded:

                response.PaymentStatus = PaymentRequestPublicStatuses.RefundConfirmed;

                response.RefundRequest = Mapper.Map <RefundRequestResponseModel>(src.Refund);

                break;

            default:
                throw new Exception("Unknown payment request status");
            }

            return(response);
        }