@Test public void testNoTransactions() { List<PaymentTransactionModel> transactions = new ArrayList<>(); when(orderModelMock.getPaymentTransactions()).thenReturn(transactions); assertEquals( AbstractWaitableAction.Transition.NOK.toString(), adyenCaptureRefundAction.execute(returnProcessModelMock) ); Mockito.verify(returnRequestModelMock).setStatus(ReturnStatus.PAYMENT_REVERSAL_FAILED); Mockito.verify(modelServiceMock).save(returnRequestModelMock); }
@Override public String execute(final ReturnProcessModel process) { LOG.debug("Process: " + process.getCode() + " in step " + getClass().getSimpleName()); final ReturnRequestModel returnRequest = process.getReturnRequest(); final List<PaymentTransactionModel> transactions = returnRequest.getOrder().getPaymentTransactions(); if (transactions.isEmpty()) { LOG.warn("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", no PaymentTransactions found"); return fail(returnRequest); } final PaymentTransactionModel transaction = transactions.get(0); final BigDecimal customRefundAmount = refundAmountCalculationService.getCustomRefundAmount(returnRequest); BigDecimal amountToRefund = null; if (customRefundAmount != null && customRefundAmount.compareTo(BigDecimal.ZERO) > 0) { amountToRefund = customRefundAmount; } else { amountToRefund = refundAmountCalculationService.getOriginalRefundAmount(returnRequest); } LOG.debug("Amount to refund " + amountToRefund); List<PaymentTransactionEntryModel> refundTransactionEntries = transaction.getEntries().stream() .filter(entry -> PaymentTransactionType.REFUND_FOLLOW_ON.equals(entry.getType())) .collect(Collectors.toList()); if (refundTransactionEntries.isEmpty()) { LOG.warn("No REFUND TXs found"); try { PaymentTransactionEntryModel transactionEntry = getPaymentService().refundFollowOn(transaction, amountToRefund); LOG.info("Refund request status: " + transactionEntry.getTransactionStatus()); if (TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) { return Transition.WAIT.name(); } } catch (final AdapterException e) { LOG.info("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", exception ocurred: " + e.getMessage()); } return fail(returnRequest); } boolean hasError = refundTransactionEntries.stream().anyMatch( entry -> TransactionStatus.REJECTED.name().equals(entry.getTransactionStatus()) || TransactionStatus.ERROR.name().equals(entry.getTransactionStatus()) ); if (hasError) { LOG.warn("Found failed REFUND transaction for ReturnRequest " + returnRequest.getCode()); return fail(returnRequest); } BigDecimal refundedAmount = refundTransactionEntries.stream() .filter( entry -> TransactionStatus.ACCEPTED.name().equals(entry.getTransactionStatus()) && TransactionStatusDetails.SUCCESFULL.name().equals(entry.getTransactionStatusDetails()) ) .map(entry -> entry.getAmount()) .reduce(new BigDecimal(0), (x, y) -> x.add(y)); refundedAmount = refundedAmount.setScale(3, BigDecimal.ROUND_FLOOR); amountToRefund = amountToRefund.setScale(3, BigDecimal.ROUND_FLOOR); LOG.debug("Refunded amount " + refundedAmount); if (refundedAmount.compareTo(amountToRefund) < 0) { LOG.debug("Waiting for the remaining amount"); return Transition.WAIT.name(); } return success(returnRequest); }
AdyenCaptureRefundAction extends AbstractWaitableAction<ReturnProcessModel> { @Override public String execute(final ReturnProcessModel process) { LOG.debug("Process: " + process.getCode() + " in step " + getClass().getSimpleName()); final ReturnRequestModel returnRequest = process.getReturnRequest(); final List<PaymentTransactionModel> transactions = returnRequest.getOrder().getPaymentTransactions(); if (transactions.isEmpty()) { LOG.warn("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", no PaymentTransactions found"); return fail(returnRequest); } final PaymentTransactionModel transaction = transactions.get(0); final BigDecimal customRefundAmount = refundAmountCalculationService.getCustomRefundAmount(returnRequest); BigDecimal amountToRefund = null; if (customRefundAmount != null && customRefundAmount.compareTo(BigDecimal.ZERO) > 0) { amountToRefund = customRefundAmount; } else { amountToRefund = refundAmountCalculationService.getOriginalRefundAmount(returnRequest); } LOG.debug("Amount to refund " + amountToRefund); List<PaymentTransactionEntryModel> refundTransactionEntries = transaction.getEntries().stream() .filter(entry -> PaymentTransactionType.REFUND_FOLLOW_ON.equals(entry.getType())) .collect(Collectors.toList()); if (refundTransactionEntries.isEmpty()) { LOG.warn("No REFUND TXs found"); try { PaymentTransactionEntryModel transactionEntry = getPaymentService().refundFollowOn(transaction, amountToRefund); LOG.info("Refund request status: " + transactionEntry.getTransactionStatus()); if (TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) { return Transition.WAIT.name(); } } catch (final AdapterException e) { LOG.info("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", exception ocurred: " + e.getMessage()); } return fail(returnRequest); } boolean hasError = refundTransactionEntries.stream().anyMatch( entry -> TransactionStatus.REJECTED.name().equals(entry.getTransactionStatus()) || TransactionStatus.ERROR.name().equals(entry.getTransactionStatus()) ); if (hasError) { LOG.warn("Found failed REFUND transaction for ReturnRequest " + returnRequest.getCode()); return fail(returnRequest); } BigDecimal refundedAmount = refundTransactionEntries.stream() .filter( entry -> TransactionStatus.ACCEPTED.name().equals(entry.getTransactionStatus()) && TransactionStatusDetails.SUCCESFULL.name().equals(entry.getTransactionStatusDetails()) ) .map(entry -> entry.getAmount()) .reduce(new BigDecimal(0), (x, y) -> x.add(y)); refundedAmount = refundedAmount.setScale(3, BigDecimal.ROUND_FLOOR); amountToRefund = amountToRefund.setScale(3, BigDecimal.ROUND_FLOOR); LOG.debug("Refunded amount " + refundedAmount); if (refundedAmount.compareTo(amountToRefund) < 0) { LOG.debug("Waiting for the remaining amount"); return Transition.WAIT.name(); } return success(returnRequest); } }
AdyenCaptureRefundAction extends AbstractWaitableAction<ReturnProcessModel> { @Override public String execute(final ReturnProcessModel process) { LOG.debug("Process: " + process.getCode() + " in step " + getClass().getSimpleName()); final ReturnRequestModel returnRequest = process.getReturnRequest(); final List<PaymentTransactionModel> transactions = returnRequest.getOrder().getPaymentTransactions(); if (transactions.isEmpty()) { LOG.warn("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", no PaymentTransactions found"); return fail(returnRequest); } final PaymentTransactionModel transaction = transactions.get(0); final BigDecimal customRefundAmount = refundAmountCalculationService.getCustomRefundAmount(returnRequest); BigDecimal amountToRefund = null; if (customRefundAmount != null && customRefundAmount.compareTo(BigDecimal.ZERO) > 0) { amountToRefund = customRefundAmount; } else { amountToRefund = refundAmountCalculationService.getOriginalRefundAmount(returnRequest); } LOG.debug("Amount to refund " + amountToRefund); List<PaymentTransactionEntryModel> refundTransactionEntries = transaction.getEntries().stream() .filter(entry -> PaymentTransactionType.REFUND_FOLLOW_ON.equals(entry.getType())) .collect(Collectors.toList()); if (refundTransactionEntries.isEmpty()) { LOG.warn("No REFUND TXs found"); try { PaymentTransactionEntryModel transactionEntry = getPaymentService().refundFollowOn(transaction, amountToRefund); LOG.info("Refund request status: " + transactionEntry.getTransactionStatus()); if (TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) { return Transition.WAIT.name(); } } catch (final AdapterException e) { LOG.info("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", exception ocurred: " + e.getMessage()); } return fail(returnRequest); } boolean hasError = refundTransactionEntries.stream().anyMatch( entry -> TransactionStatus.REJECTED.name().equals(entry.getTransactionStatus()) || TransactionStatus.ERROR.name().equals(entry.getTransactionStatus()) ); if (hasError) { LOG.warn("Found failed REFUND transaction for ReturnRequest " + returnRequest.getCode()); return fail(returnRequest); } BigDecimal refundedAmount = refundTransactionEntries.stream() .filter( entry -> TransactionStatus.ACCEPTED.name().equals(entry.getTransactionStatus()) && TransactionStatusDetails.SUCCESFULL.name().equals(entry.getTransactionStatusDetails()) ) .map(entry -> entry.getAmount()) .reduce(new BigDecimal(0), (x, y) -> x.add(y)); refundedAmount = refundedAmount.setScale(3, BigDecimal.ROUND_FLOOR); amountToRefund = amountToRefund.setScale(3, BigDecimal.ROUND_FLOOR); LOG.debug("Refunded amount " + refundedAmount); if (refundedAmount.compareTo(amountToRefund) < 0) { LOG.debug("Waiting for the remaining amount"); return Transition.WAIT.name(); } return success(returnRequest); }  }
AdyenCaptureRefundAction extends AbstractWaitableAction<ReturnProcessModel> { @Override public String execute(final ReturnProcessModel process) { LOG.debug("Process: " + process.getCode() + " in step " + getClass().getSimpleName()); final ReturnRequestModel returnRequest = process.getReturnRequest(); final List<PaymentTransactionModel> transactions = returnRequest.getOrder().getPaymentTransactions(); if (transactions.isEmpty()) { LOG.warn("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", no PaymentTransactions found"); return fail(returnRequest); } final PaymentTransactionModel transaction = transactions.get(0); final BigDecimal customRefundAmount = refundAmountCalculationService.getCustomRefundAmount(returnRequest); BigDecimal amountToRefund = null; if (customRefundAmount != null && customRefundAmount.compareTo(BigDecimal.ZERO) > 0) { amountToRefund = customRefundAmount; } else { amountToRefund = refundAmountCalculationService.getOriginalRefundAmount(returnRequest); } LOG.debug("Amount to refund " + amountToRefund); List<PaymentTransactionEntryModel> refundTransactionEntries = transaction.getEntries().stream() .filter(entry -> PaymentTransactionType.REFUND_FOLLOW_ON.equals(entry.getType())) .collect(Collectors.toList()); if (refundTransactionEntries.isEmpty()) { LOG.warn("No REFUND TXs found"); try { PaymentTransactionEntryModel transactionEntry = getPaymentService().refundFollowOn(transaction, amountToRefund); LOG.info("Refund request status: " + transactionEntry.getTransactionStatus()); if (TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) { return Transition.WAIT.name(); } } catch (final AdapterException e) { LOG.info("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", exception ocurred: " + e.getMessage()); } return fail(returnRequest); } boolean hasError = refundTransactionEntries.stream().anyMatch( entry -> TransactionStatus.REJECTED.name().equals(entry.getTransactionStatus()) || TransactionStatus.ERROR.name().equals(entry.getTransactionStatus()) ); if (hasError) { LOG.warn("Found failed REFUND transaction for ReturnRequest " + returnRequest.getCode()); return fail(returnRequest); } BigDecimal refundedAmount = refundTransactionEntries.stream() .filter( entry -> TransactionStatus.ACCEPTED.name().equals(entry.getTransactionStatus()) && TransactionStatusDetails.SUCCESFULL.name().equals(entry.getTransactionStatusDetails()) ) .map(entry -> entry.getAmount()) .reduce(new BigDecimal(0), (x, y) -> x.add(y)); refundedAmount = refundedAmount.setScale(3, BigDecimal.ROUND_FLOOR); amountToRefund = amountToRefund.setScale(3, BigDecimal.ROUND_FLOOR); LOG.debug("Refunded amount " + refundedAmount); if (refundedAmount.compareTo(amountToRefund) < 0) { LOG.debug("Waiting for the remaining amount"); return Transition.WAIT.name(); } return success(returnRequest); }  @Override String execute(final ReturnProcessModel process); @Required void setPaymentService(final PaymentService paymentService); @Required void setRefundAmountCalculationService(RefundAmountCalculationService refundAmountCalculationService); }
AdyenCaptureRefundAction extends AbstractWaitableAction<ReturnProcessModel> { @Override public String execute(final ReturnProcessModel process) { LOG.debug("Process: " + process.getCode() + " in step " + getClass().getSimpleName()); final ReturnRequestModel returnRequest = process.getReturnRequest(); final List<PaymentTransactionModel> transactions = returnRequest.getOrder().getPaymentTransactions(); if (transactions.isEmpty()) { LOG.warn("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", no PaymentTransactions found"); return fail(returnRequest); } final PaymentTransactionModel transaction = transactions.get(0); final BigDecimal customRefundAmount = refundAmountCalculationService.getCustomRefundAmount(returnRequest); BigDecimal amountToRefund = null; if (customRefundAmount != null && customRefundAmount.compareTo(BigDecimal.ZERO) > 0) { amountToRefund = customRefundAmount; } else { amountToRefund = refundAmountCalculationService.getOriginalRefundAmount(returnRequest); } LOG.debug("Amount to refund " + amountToRefund); List<PaymentTransactionEntryModel> refundTransactionEntries = transaction.getEntries().stream() .filter(entry -> PaymentTransactionType.REFUND_FOLLOW_ON.equals(entry.getType())) .collect(Collectors.toList()); if (refundTransactionEntries.isEmpty()) { LOG.warn("No REFUND TXs found"); try { PaymentTransactionEntryModel transactionEntry = getPaymentService().refundFollowOn(transaction, amountToRefund); LOG.info("Refund request status: " + transactionEntry.getTransactionStatus()); if (TransactionStatus.ACCEPTED.name().equals(transactionEntry.getTransactionStatus())) { return Transition.WAIT.name(); } } catch (final AdapterException e) { LOG.info("Unable to refund for ReturnRequest " + returnRequest.getCode() + ", exception ocurred: " + e.getMessage()); } return fail(returnRequest); } boolean hasError = refundTransactionEntries.stream().anyMatch( entry -> TransactionStatus.REJECTED.name().equals(entry.getTransactionStatus()) || TransactionStatus.ERROR.name().equals(entry.getTransactionStatus()) ); if (hasError) { LOG.warn("Found failed REFUND transaction for ReturnRequest " + returnRequest.getCode()); return fail(returnRequest); } BigDecimal refundedAmount = refundTransactionEntries.stream() .filter( entry -> TransactionStatus.ACCEPTED.name().equals(entry.getTransactionStatus()) && TransactionStatusDetails.SUCCESFULL.name().equals(entry.getTransactionStatusDetails()) ) .map(entry -> entry.getAmount()) .reduce(new BigDecimal(0), (x, y) -> x.add(y)); refundedAmount = refundedAmount.setScale(3, BigDecimal.ROUND_FLOOR); amountToRefund = amountToRefund.setScale(3, BigDecimal.ROUND_FLOOR); LOG.debug("Refunded amount " + refundedAmount); if (refundedAmount.compareTo(amountToRefund) < 0) { LOG.debug("Waiting for the remaining amount"); return Transition.WAIT.name(); } return success(returnRequest); }  @Override String execute(final ReturnProcessModel process); @Required void setPaymentService(final PaymentService paymentService); @Required void setRefundAmountCalculationService(RefundAmountCalculationService refundAmountCalculationService);  }