From f0a6855392a1e679fd7cae325ccf9857a8647ac3 Mon Sep 17 00:00:00 2001 From: Egor Cherniak Date: Fri, 22 May 2026 11:28:57 +0300 Subject: [PATCH 1/3] Permit pending on further processing --- .../schedule/core/CreatedDisputesService.java | 2 +- .../core/ForgottenDisputesService.java | 2 +- .../schedule/core/PendingDisputesService.java | 2 +- .../disputes/util/PaymentStatusValidator.java | 9 ++++++- .../service/CreatedDisputesServiceTest.java | 27 +++++++++++++++++++ .../service/PendingDisputesServiceTest.java | 17 ++++++++++++ 6 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/main/java/dev/vality/disputes/schedule/core/CreatedDisputesService.java b/src/main/java/dev/vality/disputes/schedule/core/CreatedDisputesService.java index 4c50bf2a..d61f3cab 100644 --- a/src/main/java/dev/vality/disputes/schedule/core/CreatedDisputesService.java +++ b/src/main/java/dev/vality/disputes/schedule/core/CreatedDisputesService.java @@ -69,7 +69,7 @@ public void callCreateDisputeRemotely(Dispute dispute) { // validate var invoicePayment = invoicingService.getInvoicePayment(dispute.getInvoiceId(), dispute.getPaymentId()); // validate - PaymentStatusValidator.checkStatus(invoicePayment); + PaymentStatusValidator.checkStatus(invoicePayment, true); enrichPaymentRiskData(dispute, invoicePayment); var providerData = providerDataService.getProviderData(dispute.getProviderId(), dispute.getTerminalId()); var providerStatus = diff --git a/src/main/java/dev/vality/disputes/schedule/core/ForgottenDisputesService.java b/src/main/java/dev/vality/disputes/schedule/core/ForgottenDisputesService.java index 00e07147..c5f02f92 100644 --- a/src/main/java/dev/vality/disputes/schedule/core/ForgottenDisputesService.java +++ b/src/main/java/dev/vality/disputes/schedule/core/ForgottenDisputesService.java @@ -42,7 +42,7 @@ public void process(Dispute dispute) { // validate var invoicePayment = invoicingService.getInvoicePayment(dispute.getInvoiceId(), dispute.getPaymentId()); // validate - PaymentStatusValidator.checkStatus(invoicePayment); + PaymentStatusValidator.checkStatus(invoicePayment, true); var providerData = providerDataService.getProviderData(dispute.getProviderId(), dispute.getTerminalId()); disputesService.updateNextPollingInterval(dispute, providerData); } catch (NotFoundException ex) { diff --git a/src/main/java/dev/vality/disputes/schedule/core/PendingDisputesService.java b/src/main/java/dev/vality/disputes/schedule/core/PendingDisputesService.java index 456ed4ce..6b70191b 100644 --- a/src/main/java/dev/vality/disputes/schedule/core/PendingDisputesService.java +++ b/src/main/java/dev/vality/disputes/schedule/core/PendingDisputesService.java @@ -52,7 +52,7 @@ public void callPendingDisputeRemotely(Dispute dispute) { // validate var invoicePayment = invoicingService.getInvoicePayment(dispute.getInvoiceId(), dispute.getPaymentId()); // validate - PaymentStatusValidator.checkStatus(invoicePayment); + PaymentStatusValidator.checkStatus(invoicePayment, true); var providerData = getProviderData(dispute); var finishCheckDisputeStatusResult = (Consumer) result -> { switch (result.getSetField()) { diff --git a/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java b/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java index 248a6b5a..c7e534ee 100644 --- a/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java +++ b/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java @@ -11,10 +11,17 @@ public class PaymentStatusValidator { public static void checkStatus(InvoicePayment invoicePayment) { + checkStatus(invoicePayment, false); + } + + public static void checkStatus(InvoicePayment invoicePayment, boolean allowPending) { var invoicePaymentStatus = invoicePayment.getPayment().getStatus(); switch (invoicePaymentStatus.getSetField()) { case CAPTURED -> throw new CapturedPaymentException(invoicePayment); - case FAILED, CANCELLED -> { + case FAILED, CANCELLED, PENDING -> { + if (!allowPending && invoicePaymentStatus.isSetPending()) { + throw new InvoicingPaymentStatusRestrictionsException(invoicePaymentStatus); + } } default -> throw new InvoicingPaymentStatusRestrictionsException(invoicePaymentStatus); } diff --git a/src/test/java/dev/vality/disputes/schedule/service/CreatedDisputesServiceTest.java b/src/test/java/dev/vality/disputes/schedule/service/CreatedDisputesServiceTest.java index 6bcc4994..4d0d2332 100644 --- a/src/test/java/dev/vality/disputes/schedule/service/CreatedDisputesServiceTest.java +++ b/src/test/java/dev/vality/disputes/schedule/service/CreatedDisputesServiceTest.java @@ -1,6 +1,7 @@ package dev.vality.disputes.schedule.service; import dev.vality.damsel.domain.InvoicePaymentCaptured; +import dev.vality.damsel.domain.InvoicePaymentPending; import dev.vality.damsel.domain.InvoicePaymentRefunded; import dev.vality.damsel.domain.InvoicePaymentStatus; import dev.vality.disputes.config.AbstractMockitoConfig; @@ -232,6 +233,32 @@ public void testSuccessWhenInvoicePaymentStatusIsCaptured() { assertEquals(DisputeStatus.succeeded, disputeDao.get(disputeId).getStatus()); } + @Test + @SneakyThrows + public void testCreatedWhenInvoicePaymentStatusIsPending() { + var paymentId = "1"; + var invoicePayment = createInvoicePayment(paymentId); + invoicePayment.getPayment().setStatus(InvoicePaymentStatus.pending(new InvoicePaymentPending())); + when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment); + when(fileStorageClient.generateDownloadUrl(any(), any())).thenReturn(wiremockAddressesHolder.getDownloadUrl()); + var terminal = createTerminal().get(); + terminal.getOptions().putAll(getOptions()); + when(dominantService.getTerminal(any())).thenReturn(terminal); + when(dominantService.getProvider(any())).thenReturn(createProvider().get()); + when(dominantService.getProxy(any())).thenReturn(createProxy().get()); + var providerMock = mock(ProviderDisputesServiceSrv.Client.class); + var providerDisputeId = UUID.randomUUID().toString(); + when(providerMock.createDispute(any())).thenReturn(createDisputeCreatedSuccessResult(providerDisputeId)); + when(providerDisputesThriftInterfaceBuilder.buildWoodyClient(any())).thenReturn(providerMock); + createdFlowHandler.mockFailStatusProviderPayment(); + var invoiceId = "20McecNnWoy"; + var disputeId = UUID.fromString(merchantApiMvcPerformer.createDispute(invoiceId, paymentId).getDisputeId()); + var dispute = disputeDao.get(disputeId); + createdDisputesService.callCreateDisputeRemotely(dispute); + assertEquals(DisputeStatus.pending, disputeDao.get(disputeId).getStatus()); + disputeDao.finishFailed(disputeId, null); + } + @Test @SneakyThrows public void createAdjustmentWhenSuccessStatusProviderPayment() { diff --git a/src/test/java/dev/vality/disputes/schedule/service/PendingDisputesServiceTest.java b/src/test/java/dev/vality/disputes/schedule/service/PendingDisputesServiceTest.java index 8122f2cc..1750ef69 100644 --- a/src/test/java/dev/vality/disputes/schedule/service/PendingDisputesServiceTest.java +++ b/src/test/java/dev/vality/disputes/schedule/service/PendingDisputesServiceTest.java @@ -1,6 +1,7 @@ package dev.vality.disputes.schedule.service; import dev.vality.damsel.domain.InvoicePaymentCaptured; +import dev.vality.damsel.domain.InvoicePaymentPending; import dev.vality.damsel.domain.InvoicePaymentRefunded; import dev.vality.damsel.domain.InvoicePaymentStatus; import dev.vality.disputes.config.AbstractMockitoConfig; @@ -142,4 +143,20 @@ public void testSuccessWhenInvoicePaymentStatusIsCaptured() { pendingDisputesService.callPendingDisputeRemotely(dispute); assertEquals(DisputeStatus.succeeded, disputeDao.get(disputeId).getStatus()); } + + @Test + @SneakyThrows + public void testPendingWhenInvoicePaymentStatusIsPending() { + var disputeId = createdFlowHandler.handleCreate(); + var providerMock = mock(ProviderDisputesServiceSrv.Client.class); + when(providerMock.checkDisputeStatus(any())).thenReturn(createDisputeStatusPendingResult()); + when(providerDisputesThriftInterfaceBuilder.buildWoodyClient(any())).thenReturn(providerMock); + var dispute = disputeDao.get(disputeId); + var invoicePayment = createInvoicePayment(dispute.getPaymentId()); + invoicePayment.getPayment().setStatus(InvoicePaymentStatus.pending(new InvoicePaymentPending())); + when(invoicingClient.getPayment(any(), any())).thenReturn(invoicePayment); + pendingDisputesService.callPendingDisputeRemotely(dispute); + assertEquals(DisputeStatus.pending, disputeDao.get(disputeId).getStatus()); + disputeDao.finishFailed(disputeId, null); + } } From 230b9eced4fe39723748d78f39bd0450bb50f812 Mon Sep 17 00:00:00 2001 From: Egor Cherniak Date: Fri, 22 May 2026 12:52:14 +0300 Subject: [PATCH 2/3] Cleanup --- .../dev/vality/disputes/util/PaymentStatusValidator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java b/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java index c7e534ee..ad5bc96a 100644 --- a/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java +++ b/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java @@ -18,8 +18,9 @@ public static void checkStatus(InvoicePayment invoicePayment, boolean allowPendi var invoicePaymentStatus = invoicePayment.getPayment().getStatus(); switch (invoicePaymentStatus.getSetField()) { case CAPTURED -> throw new CapturedPaymentException(invoicePayment); - case FAILED, CANCELLED, PENDING -> { - if (!allowPending && invoicePaymentStatus.isSetPending()) { + case FAILED, CANCELLED -> {} + case PENDING -> { + if (!allowPending) { throw new InvoicingPaymentStatusRestrictionsException(invoicePaymentStatus); } } From 87a4095b386d1177879c0423e9cce2a96e967d79 Mon Sep 17 00:00:00 2001 From: Egor Cherniak Date: Fri, 22 May 2026 12:57:12 +0300 Subject: [PATCH 3/3] Linter --- .../java/dev/vality/disputes/util/PaymentStatusValidator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java b/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java index ad5bc96a..d3e92e4d 100644 --- a/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java +++ b/src/main/java/dev/vality/disputes/util/PaymentStatusValidator.java @@ -18,7 +18,8 @@ public static void checkStatus(InvoicePayment invoicePayment, boolean allowPendi var invoicePaymentStatus = invoicePayment.getPayment().getStatus(); switch (invoicePaymentStatus.getSetField()) { case CAPTURED -> throw new CapturedPaymentException(invoicePayment); - case FAILED, CANCELLED -> {} + case FAILED, CANCELLED -> { + } case PENDING -> { if (!allowPending) { throw new InvoicingPaymentStatusRestrictionsException(invoicePaymentStatus);