killbill-aplcache

invoice, payment: Fixes #415 In addition to fixing the multiple

10/21/2015 6:50:46 PM

Details

diff --git a/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java b/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
index 0403e60..b50879e 100644
--- a/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/invoice/api/InvoiceInternalApi.java
@@ -73,4 +73,6 @@ public interface InvoiceInternalApi {
      * @param context   the callcontext
      */
     public void consumeExistingCBAOnAccountWithUnpaidInvoices(final UUID accountId, final InternalCallContext context) throws InvoiceApiException;
+
+    public Map<UUID, BigDecimal> validateInvoiceItemAdjustments(final UUID paymentId, final Map<UUID, BigDecimal> idWithAmount, final InternalTenantContext context) throws InvoiceApiException;
 }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
index b6d3059..e47f289 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
@@ -19,8 +19,10 @@ package org.killbill.billing.invoice.api;
 
 import java.math.BigDecimal;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.annotation.Nullable;
@@ -52,6 +54,7 @@ import com.google.common.base.Objects;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterables;
 
 public class InvoiceApiHelper {
@@ -119,9 +122,12 @@ public class InvoiceApiHelper {
      * @param effectiveDate       adjustment effective date, in the account timezone
      * @return the adjustment item
      */
-    public InvoiceItem createAdjustmentItem(final Invoice invoiceToBeAdjusted, final UUID invoiceItemId,
-                                            @Nullable final BigDecimal positiveAdjAmount, @Nullable final Currency currency,
-                                            final LocalDate effectiveDate, final InternalCallContext context) throws InvoiceApiException {
+    public InvoiceItem createAdjustmentItem(final Invoice invoiceToBeAdjusted,
+                                            final UUID invoiceItemId,
+                                            @Nullable final BigDecimal positiveAdjAmount,
+                                            @Nullable final Currency currency,
+                                            final LocalDate effectiveDate,
+                                            final InternalCallContext context) throws InvoiceApiException {
         final InvoiceItem invoiceItemToBeAdjusted = Iterables.<InvoiceItem>tryFind(invoiceToBeAdjusted.getInvoiceItems(),
                                                                                    new Predicate<InvoiceItem>() {
                                                                                        @Override
@@ -133,14 +139,20 @@ public class InvoiceApiHelper {
             throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
         }
 
-        // Retrieve the amount and currency if needed
-        final BigDecimal amountToAdjust = Objects.firstNonNull(positiveAdjAmount, invoiceItemToBeAdjusted.getAmount());
         // Check the specified currency matches the one of the existing invoice
         final Currency currencyForAdjustment = Objects.firstNonNull(currency, invoiceItemToBeAdjusted.getCurrency());
         if (invoiceItemToBeAdjusted.getCurrency() != currencyForAdjustment) {
             throw new InvoiceApiException(ErrorCode.CURRENCY_INVALID, currency, invoiceItemToBeAdjusted.getCurrency());
         }
 
+        // Reuse the same logic we have for the refun with item adjustment
+        final Map<UUID, BigDecimal> input = new HashMap<UUID, BigDecimal>();
+        input.put(invoiceItemId, positiveAdjAmount);
+
+        final Map<UUID, BigDecimal> output = dao.computeItemAdjustments(invoiceToBeAdjusted.getId().toString(), input, context);
+
+        // If we pass that stage, it means the validation succeeded so we just need to extract resulting amount and negate the result.
+        final BigDecimal amountToAdjust = output.get(invoiceItemId).negate();
         // Finally, create the adjustment
         return new ItemAdjInvoiceItem(UUIDs.randomUUID(),
                                       context.getCreatedDate(),
@@ -148,8 +160,7 @@ public class InvoiceApiHelper {
                                       invoiceItemToBeAdjusted.getAccountId(),
                                       effectiveDate,
                                       null,
-                                      // Note! The amount is negated here!
-                                      amountToAdjust.negate(),
+                                      amountToAdjust,
                                       currencyForAdjustment,
                                       invoiceItemToBeAdjusted.getId());
     }
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index b3da4f0..a4a7621 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -20,6 +20,7 @@ package org.killbill.billing.invoice.api.svcs;
 
 import java.math.BigDecimal;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -41,6 +42,8 @@ import org.killbill.billing.invoice.api.InvoicePayment;
 import org.killbill.billing.invoice.api.InvoicePaymentType;
 import org.killbill.billing.invoice.api.WithAccountLock;
 import org.killbill.billing.invoice.dao.InvoiceDao;
+import org.killbill.billing.invoice.dao.InvoiceDaoHelper;
+import org.killbill.billing.invoice.dao.InvoiceItemModelDao;
 import org.killbill.billing.invoice.dao.InvoiceModelDao;
 import org.killbill.billing.invoice.dao.InvoicePaymentModelDao;
 import org.killbill.billing.invoice.model.DefaultInvoice;
@@ -158,6 +161,12 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
         dao.consumeExstingCBAOnAccountWithUnpaidInvoices(accountId, context);
     }
 
+    @Override
+    public Map<UUID, BigDecimal> validateInvoiceItemAdjustments(final UUID paymentId, final Map<UUID, BigDecimal> idWithAmount, final InternalTenantContext context) throws InvoiceApiException {
+        final InvoicePayment invoicePayment = getInvoicePayment(paymentId, InvoicePaymentType.ATTEMPT, context);
+        return dao.computeItemAdjustments(invoicePayment.getInvoiceId().toString(), idWithAmount, context);
+    }
+
     private InvoicePayment getInvoicePayment(final UUID paymentId, final InvoicePaymentType type, final InternalTenantContext context) throws InvoiceApiException {
         final Collection<InvoicePayment> invoicePayments = Collections2.transform(dao.getInvoicePayments(paymentId, context), new Function<InvoicePaymentModelDao, InvoicePayment>() {
             @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 0c2b5b3..d5d3bd6 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -394,7 +394,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                                                                          amount,
                                                                                          currency,
                                                                                          effectiveDate,
-                                                                                         internalCallContextFactory.createInternalCallContext(context));
+                                                                                         internalCallContextFactory.createInternalCallContext(accountId, context));
                 invoice.addInvoiceItem(adjustmentItem);
 
                 return ImmutableList.<Invoice>of(invoice);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 0f4cdc0..8f97ea4 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -575,6 +575,16 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
     }
 
     @Override
+    public Map<UUID, BigDecimal> computeItemAdjustments(final String invoiceId, final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final InternalTenantContext context) throws InvoiceApiException {
+        return transactionalSqlDao.execute(InvoiceApiException.class, new EntitySqlDaoTransactionWrapper<Map<UUID, BigDecimal>>() {
+            @Override
+            public Map<UUID, BigDecimal> inTransaction(final EntitySqlDaoWrapperFactory entitySqlDaoWrapperFactory) throws Exception {
+                return invoiceDaoHelper.computeItemAdjustments(invoiceId, entitySqlDaoWrapperFactory, invoiceItemIdsWithNullAmounts, context);
+            }
+        });
+    }
+
+    @Override
     public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final InternalTenantContext context) {
         return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<BigDecimal>() {
             @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
index a5d1590..effce52 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDao.java
@@ -75,6 +75,10 @@ public interface InvoiceDao extends EntityDao<InvoiceModelDao, Invoice, InvoiceA
 
     InvoiceItemModelDao doCBAComplexity(InvoiceModelDao invoice, InternalCallContext context) throws InvoiceApiException;
 
+    Map<UUID, BigDecimal> computeItemAdjustments(final String invoiceId,
+                                                 final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts,
+                                                 final InternalTenantContext context) throws InvoiceApiException;
+
     /**
      * Create a refund.
      *
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
index 56beb81..407aa6f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceDaoHelper.java
@@ -34,7 +34,6 @@ import org.killbill.billing.ErrorCode;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.catalog.api.Currency;
-import org.killbill.billing.entity.EntityPersistenceException;
 import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
@@ -43,7 +42,6 @@ import com.google.common.base.Objects;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap.Builder;
 
 public class InvoiceDaoHelper {
 
@@ -65,9 +63,9 @@ public class InvoiceDaoHelper {
                                                         final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts,
                                                         final InternalTenantContext context) throws InvoiceApiException {
         // Populate the missing amounts for individual items, if needed
-        final Builder<UUID, BigDecimal> invoiceItemIdsWithAmountsBuilder = new Builder<UUID, BigDecimal>();
+        final Map<UUID, BigDecimal> outputItemIdsWithAmounts = new HashMap<UUID, BigDecimal>();
         if (invoiceItemIdsWithNullAmounts.size() == 0) {
-            return invoiceItemIdsWithAmountsBuilder.build();
+            return outputItemIdsWithAmounts;
         }
 
         // Retrieve invoice before the Refund
@@ -82,53 +80,50 @@ public class InvoiceDaoHelper {
         // If we have an item amount, we 'd like to use it, but we need to check first that it is lesser or equal than maximum allowed
         //If, not we compute maximum value we can adjust per item
         for (final UUID invoiceItemId : invoiceItemIdsWithNullAmounts.keySet()) {
-            final BigDecimal originalItemAmount = getInvoiceItemAmountForId(invoice, invoiceItemId);
-            final BigDecimal maxAdjAmount = computeItemAdjustmentAmount(invoiceItemId, originalItemAmount, invoice.getInvoiceItems());
+            final List<InvoiceItemModelDao> adjustedOrRepairedItems = entitySqlDaoWrapperFactory.become(InvoiceItemSqlDao.class).getAdjustedOrRepairedInvoiceItemsByLinkedId(invoiceItemId.toString(), context);
+            computeItemAdjustmentsForTargetInvoiceItem(getInvoiceItemForId(invoice, invoiceItemId), adjustedOrRepairedItems, invoiceItemIdsWithNullAmounts, outputItemIdsWithAmounts);
+        }
+        return outputItemIdsWithAmounts;
+    }
 
-            final BigDecimal proposedItemAmount = invoiceItemIdsWithNullAmounts.get(invoiceItemId);
-            if (proposedItemAmount != null && proposedItemAmount.compareTo(maxAdjAmount) > 0) {
-                throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_INVALID, proposedItemAmount, maxAdjAmount);
-            }
 
-            final BigDecimal itemAmountToAdjust = Objects.firstNonNull(proposedItemAmount, maxAdjAmount);
-            if (itemAmountToAdjust.compareTo(BigDecimal.ZERO) > 0) {
-                invoiceItemIdsWithAmountsBuilder.put(invoiceItemId, itemAmountToAdjust);
-            }
+    private static void computeItemAdjustmentsForTargetInvoiceItem(final InvoiceItemModelDao targetInvoiceItem, final List<InvoiceItemModelDao> adjustedOrRepairedItems, final Map<UUID, BigDecimal> inputAdjInvoiceItem, final Map<UUID, BigDecimal> outputAdjInvoiceItem) throws InvoiceApiException {
+        final BigDecimal originalItemAmount = targetInvoiceItem.getAmount();
+        final BigDecimal maxAdjLeftAmount = computeItemAdjustmentAmount(originalItemAmount, adjustedOrRepairedItems);
+
+        final BigDecimal proposedItemAmount = inputAdjInvoiceItem.get(targetInvoiceItem.getId());
+        if (proposedItemAmount != null && proposedItemAmount.compareTo(maxAdjLeftAmount) > 0) {
+            throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_INVALID, proposedItemAmount, maxAdjLeftAmount);
         }
 
-        return invoiceItemIdsWithAmountsBuilder.build();
+        final BigDecimal itemAmountToAdjust = Objects.firstNonNull(proposedItemAmount, maxAdjLeftAmount);
+        if (itemAmountToAdjust.compareTo(BigDecimal.ZERO) > 0) {
+            outputAdjInvoiceItem.put(targetInvoiceItem.getId(), itemAmountToAdjust);
+        }
     }
 
     /**
-     * @param invoiceItem                     item we are adjusting
      * @param requestedPositiveAmountToAdjust amount we are adjusting for that item
-     * @param invoiceItems                    list of all invoice items on this invoice
+     * @param adjustedOrRepairedItems        list of all adjusted or repaired linking to this item
      * @return the amount we should really adjust based on whether or not the item got repaired
      */
-    private BigDecimal computeItemAdjustmentAmount(final UUID invoiceItem, final BigDecimal requestedPositiveAmountToAdjust, final List<InvoiceItemModelDao> invoiceItems) {
+    private static BigDecimal computeItemAdjustmentAmount(final BigDecimal requestedPositiveAmountToAdjust, final List<InvoiceItemModelDao> adjustedOrRepairedItems) {
 
-        BigDecimal positiveRepairedAmount = BigDecimal.ZERO;
+        BigDecimal positiveAdjustedOrRepairedAmount = BigDecimal.ZERO;
 
-        final Collection<InvoiceItemModelDao> repairedItems = Collections2.filter(invoiceItems, new Predicate<InvoiceItemModelDao>() {
-            @Override
-            public boolean apply(final InvoiceItemModelDao input) {
-                return (input.getType() == InvoiceItemType.REPAIR_ADJ && input.getLinkedItemId().equals(invoiceItem));
-            }
-        });
-        for (final InvoiceItemModelDao cur : repairedItems) {
-            // Repair item are negative so we negate to make it positive
-            positiveRepairedAmount = positiveRepairedAmount.add(cur.getAmount().negate());
+        for (final InvoiceItemModelDao cur : adjustedOrRepairedItems) {
+            // Adjustment or repair items are negative so we negate to make it positive
+            positiveAdjustedOrRepairedAmount = positiveAdjustedOrRepairedAmount.add(cur.getAmount().negate());
         }
-        return (positiveRepairedAmount.compareTo(requestedPositiveAmountToAdjust) >= 0) ? BigDecimal.ZERO : requestedPositiveAmountToAdjust.subtract(positiveRepairedAmount);
+        return (positiveAdjustedOrRepairedAmount.compareTo(requestedPositiveAmountToAdjust) >= 0) ? BigDecimal.ZERO : requestedPositiveAmountToAdjust.subtract(positiveAdjustedOrRepairedAmount);
     }
 
-    private BigDecimal getInvoiceItemAmountForId(final InvoiceModelDao invoice, final UUID invoiceItemId) throws InvoiceApiException {
+    private InvoiceItemModelDao getInvoiceItemForId(final InvoiceModelDao invoice, final UUID invoiceItemId) throws InvoiceApiException {
         for (final InvoiceItemModelDao invoiceItem : invoice.getInvoiceItems()) {
             if (invoiceItem.getId().equals(invoiceItemId)) {
-                return invoiceItem.getAmount();
+                return invoiceItem;
             }
         }
-
         throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_NOT_FOUND, invoiceItemId);
     }
 
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
index e4245c4..4ec1a9f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.java
@@ -37,4 +37,9 @@ public interface InvoiceItemSqlDao extends EntitySqlDao<InvoiceItemModelDao, Inv
     @SqlQuery
     List<InvoiceItemModelDao> getInvoiceItemsBySubscription(@Bind("subscriptionId") final String subscriptionId,
                                                             @BindBean final InternalTenantContext context);
+
+
+    @SqlQuery
+    List<InvoiceItemModelDao> getAdjustedOrRepairedInvoiceItemsByLinkedId(@Bind("linkedItemId") final String linkedItemId,
+                                                            @BindBean final InternalTenantContext context);
 }
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
index d5d3a7f..8470a77 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/dao/InvoiceItemSqlDao.sql.stg
@@ -58,3 +58,12 @@ getInvoiceItemsBySubscription() ::= <<
   <AND_CHECK_TENANT()>
   ;
 >>
+
+getAdjustedOrRepairedInvoiceItemsByLinkedId() ::= <<
+  SELECT <allTableFields()>
+  FROM <tableName()>
+  WHERE linked_item_id = :linkedItemId
+  AND type IN ('ITEM_ADJ', 'REPAIR_ADJ')
+  <AND_CHECK_TENANT()>
+  ;
+>>
\ No newline at end of file
diff --git a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
index bb1ed4e..1a3907c 100644
--- a/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/org/killbill/billing/invoice/ddl.sql
@@ -29,6 +29,7 @@ CREATE UNIQUE INDEX invoice_items_id ON invoice_items(id);
 CREATE INDEX invoice_items_subscription_id ON invoice_items(subscription_id ASC);
 CREATE INDEX invoice_items_invoice_id ON invoice_items(invoice_id ASC);
 CREATE INDEX invoice_items_account_id ON invoice_items(account_id ASC);
+CREATE INDEX invoice_items_linked_item_id ON invoice_items(linked_item_id ASC);
 CREATE INDEX invoice_items_tenant_account_record_id ON invoice_items(tenant_record_id, account_record_id);
 
 DROP TABLE IF EXISTS invoices;
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
index aabfb60..d6a2133 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/MockInvoiceDao.java
@@ -304,6 +304,11 @@ public class MockInvoiceDao extends MockEntityDaoBase<InvoiceModelDao, Invoice, 
     }
 
     @Override
+    public Map<UUID, BigDecimal> computeItemAdjustments(final String invoiceId, final Map<UUID, BigDecimal> invoiceItemIdsWithNullAmounts, final InternalTenantContext context) throws InvoiceApiException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final InternalTenantContext context) {
         throw new UnsupportedOperationException();
     }
diff --git a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
index f3738f5..51c25da 100644
--- a/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/invoice/InvoicePaymentControlPluginApi.java
@@ -300,6 +300,19 @@ public final class InvoicePaymentControlPluginApi implements PaymentControlPlugi
                                                                                                               amountToBeRefunded,
                                                                                                               paymentControlPluginContext.getAmount())));
         }
+
+        final PluginProperty prop = getPluginProperty(pluginProperties, PROP_IPCD_REFUND_WITH_ADJUSTMENTS);
+        final boolean isAdjusted = prop != null ? Boolean.valueOf((String) prop.getValue()) : false;
+        if (isAdjusted) {
+            try {
+                invoiceApi.validateInvoiceItemAdjustments(paymentControlPluginContext.getPaymentId(), idWithAmount, internalContext);
+            } catch (InvoiceApiException e) {
+                throw new PaymentControlApiException(String.format("Refund for payment %s aborted", payment.getId()),
+                                                     new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_EXCEPTION, e.getMessage()));
+            }
+        }
+
+        return new DefaultPriorPaymentControlResult(isAborted, amountToBeRefunded);
     }
 
     private Map<UUID, BigDecimal> extractIdsWithAmountFromProperties(final Iterable<PluginProperty> properties) {
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index 71ea328..de2d296 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -415,7 +415,6 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
                                                         createPropertiesForInvoice(invoice), INVOICE_PAYMENT, callContext);
             Assert.fail("Unexpected success");
         } catch (final PaymentApiException e) {
-            assertTrue(e.getCause() instanceof PaymentControlApiException);
         }
     }