killbill-aplcache

Changes

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
index 2cc600a..8f1fa10 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/api/user/DefaultAnalyticsUserApi.java
@@ -50,12 +50,12 @@ import com.ning.billing.analytics.model.BusinessSubscriptionTransition;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.junction.api.Blockable.Type;
 import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.callcontext.TenantContext;
+import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
 import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
 import com.ning.billing.util.svcapi.tag.TagInternalApi;
 import com.ning.billing.util.tag.Tag;
@@ -77,7 +77,7 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
     private final BusinessInvoicePaymentDao bipDao;
     private final BusinessTagDao tagDao;
     private final EntitlementInternalApi entitlementInternalApi;
-    private final PaymentApi paymentApi;
+    private final PaymentInternalApi paymentApi;
     private final TagInternalApi tagInternalApi;
     private final InternalCallContextFactory internalCallContextFactory;
 
@@ -90,7 +90,7 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
                                    final BusinessInvoicePaymentDao bipDao,
                                    final BusinessTagDao tagDao,
                                    final EntitlementInternalApi entitlementInternalApi,
-                                   final PaymentApi paymentApi,
+                                   final PaymentInternalApi paymentApi,
                                    final TagInternalApi tagInternalApi,
                                    final InternalCallContextFactory internalCallContextFactory) {
         this.analyticsDao = analyticsDao;
@@ -131,7 +131,7 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
 
         // Update BIP for all invoices
         try {
-            updateBIP(account, context, internalCallContext);
+            updateBIP(account, internalCallContext);
         } catch (PaymentApiException e) {
             // Log and ignore
             log.warn(e.toString());
@@ -186,8 +186,8 @@ public class DefaultAnalyticsUserApi implements AnalyticsUserApi {
         return bundlesId;
     }
 
-    private void updateBIP(final Account account, final TenantContext tenantContext, final InternalCallContext internalCallContext) throws PaymentApiException {
-        final List<Payment> accountPayments = paymentApi.getAccountPayments(account.getId(), tenantContext);
+    private void updateBIP(final Account account, final InternalCallContext internalCallContext) throws PaymentApiException {
+        final List<Payment> accountPayments = paymentApi.getAccountPayments(account.getId(), internalCallContext);
         final Map<UUID, Payment> payments = new HashMap<UUID, Payment>();
         for (final Payment payment : accountPayments) {
             payments.put(payment.getId(), payment);
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
index 2977ace..584e817 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountDao.java
@@ -34,12 +34,12 @@ import com.ning.billing.analytics.dao.BusinessAccountSqlDao;
 import com.ning.billing.analytics.model.BusinessAccount;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
+import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
 import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 
 import com.google.inject.Inject;
@@ -51,11 +51,11 @@ public class BusinessAccountDao {
     private final BusinessAccountSqlDao sqlDao;
     private final AccountInternalApi accountApi;
     private final InvoiceInternalApi invoiceApi;
-    private final PaymentApi paymentApi;
+    private final PaymentInternalApi paymentApi;
 
     @Inject
     public BusinessAccountDao(final BusinessAccountSqlDao sqlDao, final AccountInternalApi accountApi,
-                              final InvoiceInternalApi invoiceApi, final PaymentApi paymentApi) {
+                              final InvoiceInternalApi invoiceApi, final PaymentInternalApi paymentApi) {
         this.sqlDao = sqlDao;
         this.accountApi = accountApi;
         this.invoiceApi = invoiceApi;
@@ -115,7 +115,7 @@ public class BusinessAccountDao {
                 // Retrieve payments information for these invoices
                 DateTime lastPaymentDate = null;
 
-                final List<Payment> payments = paymentApi.getAccountPayments(account.getId(), context.toTenantContext());
+                final List<Payment> payments = paymentApi.getAccountPayments(account.getId(), context);
                 if (payments != null) {
                     for (final Payment cur : payments) {
                         // Use the last payment method/type/country as the default one for the account
@@ -128,7 +128,7 @@ public class BusinessAccountDao {
             }
 
             // Retrieve payment methods
-            for (final PaymentMethod paymentMethod : paymentApi.getPaymentMethods(account, true, context.toTenantContext())) {
+            for (final PaymentMethod paymentMethod : paymentApi.getPaymentMethods(account, true, context)) {
                 if (paymentMethod.getId().equals(account.getPaymentMethodId()) && paymentMethod.getPluginDetail() != null) {
                     paymentMethodType = PaymentMethodUtils.getPaymentMethodType(paymentMethod.getPluginDetail());
                     creditCardType = PaymentMethodUtils.getCardType(paymentMethod.getPluginDetail());
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
index fca6f3f..2ae6900 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessInvoicePaymentDao.java
@@ -37,15 +37,14 @@ import com.ning.billing.analytics.model.BusinessInvoicePayment;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoicePayment;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.payment.api.Payment;
-import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
+import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
 import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 
 public class BusinessInvoicePaymentDao {
@@ -54,20 +53,18 @@ public class BusinessInvoicePaymentDao {
 
     private final BusinessInvoicePaymentSqlDao invoicePaymentSqlDao;
     private final AccountInternalApi accountApi;
-    private final InvoicePaymentApi invoicePaymentApi;
     private final InvoiceInternalApi invoiceApi;
-    private final PaymentApi paymentApi;
+    private final PaymentInternalApi paymentApi;
     private final Clock clock;
     private final BusinessInvoiceDao invoiceDao;
     private final BusinessAccountDao accountDao;
 
     @Inject
     public BusinessInvoicePaymentDao(final BusinessInvoicePaymentSqlDao invoicePaymentSqlDao, final AccountInternalApi accountApi,
-                                     final InvoicePaymentApi invoicePaymentApi, final InvoiceInternalApi invoiceApi, final PaymentApi paymentApi,
+                                     final InvoiceInternalApi invoiceApi, final PaymentInternalApi paymentApi,
                                      final Clock clock, final BusinessInvoiceDao invoiceDao, final BusinessAccountDao accountDao) {
         this.invoicePaymentSqlDao = invoicePaymentSqlDao;
         this.accountApi = accountApi;
-        this.invoicePaymentApi = invoicePaymentApi;
         this.invoiceApi = invoiceApi;
         this.paymentApi = paymentApi;
         this.clock = clock;
@@ -92,7 +89,7 @@ public class BusinessInvoicePaymentDao {
 
         final Payment payment;
         try {
-            payment = paymentApi.getPayment(paymentId, context.toCallContext());
+            payment = paymentApi.getPayment(paymentId, context);
         } catch (PaymentApiException e) {
             log.warn("Ignoring payment {}: payment does not exist", paymentId);
             return;
@@ -100,20 +97,22 @@ public class BusinessInvoicePaymentDao {
 
         final PaymentMethod paymentMethod;
         try {
-            paymentMethod = paymentApi.getPaymentMethod(account, payment.getPaymentMethodId(), true, context.toCallContext());
+            paymentMethod = paymentApi.getPaymentMethod(account, payment.getPaymentMethodId(), true, context);
         } catch (PaymentApiException e) {
             log.warn("Ignoring payment {}: payment method {} does not exist", paymentId, payment.getPaymentMethodId());
             return;
         }
 
-        final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePaymentForAttempt(paymentId, context.toCallContext());
         Invoice invoice = null;
-        if (invoicePayment != null) {
-            try {
+        InvoicePayment invoicePayment = null;
+        try {
+            invoicePayment = invoiceApi.getInvoicePaymentForAttempt(paymentId, context);
+            if (invoicePayment != null) {
                 invoice = invoiceApi.getInvoiceById(invoicePayment.getInvoiceId(), context);
-            } catch (InvoiceApiException e) {
-                log.warn("Unable to find invoice {} for payment {}", invoicePayment.getInvoiceId(), paymentId);
             }
+        } catch (InvoiceApiException e) {
+            log.warn("Unable to find invoice {} for payment {}",
+                     invoicePayment != null ? invoicePayment.getInvoiceId() : "unknown", paymentId);
         }
 
         createPayment(account, invoice, invoicePayment, payment, paymentMethod, extFirstPaymentRefId, extSecondPaymentRefId, message, context);
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
index 6012be1..572f6c8 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/user/TestDefaultAnalyticsUserApi.java
@@ -65,6 +65,7 @@ import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.svcapi.entitlement.EntitlementInternalApi;
+import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
 import com.ning.billing.util.svcapi.tag.TagInternalApi;
 
 public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedDB {
@@ -102,7 +103,7 @@ public class TestDefaultAnalyticsUserApi extends AnalyticsTestSuiteWithEmbeddedD
                                                        Mockito.mock(BusinessInvoicePaymentDao.class),
                                                        Mockito.mock(BusinessTagDao.class),
                                                        Mockito.mock(EntitlementInternalApi.class),
-                                                       Mockito.mock(PaymentApi.class),
+                                                       Mockito.mock(PaymentInternalApi.class),
                                                        Mockito.mock(TagInternalApi.class),
                                                        new InternalCallContextFactory(dbi, clock));
     }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index e000af6..cb7f3f3 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -37,31 +37,10 @@ public interface InvoicePaymentApi {
 
     public Invoice getInvoice(UUID invoiceId, TenantContext context) throws InvoiceApiException;
 
-    public Invoice getInvoiceForPaymentId(UUID paymentId, TenantContext context) throws InvoiceApiException;
-
     public List<InvoicePayment> getInvoicePayments(UUID paymentId, TenantContext context);
 
     public InvoicePayment getInvoicePaymentForAttempt(UUID paymentId, TenantContext context);
 
-    public void notifyOfPayment(InvoicePayment invoicePayment, CallContext context) throws InvoiceApiException;
-
-    public void notifyOfPayment(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentId, DateTime paymentDate, CallContext context) throws InvoiceApiException;
-
-    /**
-     * Create a refund.
-     *
-     * @param paymentId                 payment associated with that refund
-     * @param amount                    amount to refund
-     * @param isInvoiceAdjusted         whether the refund should trigger an invoice or invoice item adjustment
-     * @param invoiceItemIdsWithAmounts invoice item ids and associated amounts to adjust
-     * @param paymentCookieId           payment cookie id
-     * @param context                   the call context
-     * @return the created invoice payment object associated with this refund
-     * @throws InvoiceApiException
-     */
-    public InvoicePayment createRefund(UUID paymentId, BigDecimal amount, boolean isInvoiceAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts,
-                                       UUID paymentCookieId, CallContext context) throws InvoiceApiException;
-
     public InvoicePayment createChargeback(UUID invoicePaymentId, BigDecimal amount, CallContext context) throws InvoiceApiException;
 
     public InvoicePayment createChargeback(UUID invoicePaymentId, CallContext context) throws InvoiceApiException;
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index 3db2693..e04fed7 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -87,13 +87,6 @@ public interface InvoiceUserApi {
      */
     public Invoice getInvoiceByNumber(Integer number, TenantContext context) throws InvoiceApiException;
 
-    /**
-     * Record a payment for an invoice.
-     *
-     * @param invoicePayment invoice payment
-     * @param context        call context
-     */
-    public void notifyOfPayment(InvoicePayment invoicePayment, CallContext context) throws InvoiceApiException;
 
     /**
      * Find unpaid invoices for a given account, up to a given day.
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
index 404ac7c..f8ea053 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/alignment/MigrationPlanAligner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010-2011 Ning, Inc.
+ * Copyright 2010-2012 Ning, Inc.
  *
  * Ning licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -47,13 +47,13 @@ public class MigrationPlanAligner {
             throws EntitlementMigrationApiException {
 
         try {
-            TimedMigration[] events = null;
+            TimedMigration[] events;
             final Plan plan0 = catalogService.getFullCatalog().findPlan(input[0].getPlanPhaseSpecifier().getProductName(),
-                                                                  input[0].getPlanPhaseSpecifier().getBillingPeriod(), input[0].getPlanPhaseSpecifier().getPriceListName(), now);
+                                                                        input[0].getPlanPhaseSpecifier().getBillingPeriod(), input[0].getPlanPhaseSpecifier().getPriceListName(), now);
 
             final Plan plan1 = (input.length > 1) ? catalogService.getFullCatalog().findPlan(input[1].getPlanPhaseSpecifier().getProductName(),
-                                                                                       input[1].getPlanPhaseSpecifier().getBillingPeriod(), input[1].getPlanPhaseSpecifier().getPriceListName(), now) :
-                    null;
+                                                                                             input[1].getPlanPhaseSpecifier().getBillingPeriod(), input[1].getPlanPhaseSpecifier().getPriceListName(), now) :
+                               null;
 
             DateTime migrationStartDate = input[0].getEffectiveDate();
 
@@ -194,8 +194,8 @@ public class MigrationPlanAligner {
 
     private boolean isSamePlan(final PlanPhaseSpecifier plan0, final PlanPhaseSpecifier plan1) {
         if (plan0.getPriceListName().equals(plan1.getPriceListName()) &&
-                plan0.getProductName().equals(plan1.getProductName()) &&
-                plan0.getBillingPeriod() == plan1.getBillingPeriod()) {
+            plan0.getProductName().equals(plan1.getProductName()) &&
+            plan0.getBillingPeriod() == plan1.getBillingPeriod()) {
             return true;
         }
         return false;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index 4739213..c51f344 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -57,14 +57,6 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) throws InvoiceApiException {
-        // Retrieve the account id for the internal call context
-        final Invoice invoice = dao.getById(invoicePayment.getInvoiceId(), internalCallContextFactory.createInternalTenantContext(context));
-        final UUID accountId = invoice.getAccountId();
-        dao.notifyOfPayment(invoicePayment, internalCallContextFactory.createInternalCallContext(accountId, context));
-    }
-
-    @Override
     public List<Invoice> getAllInvoicesByAccount(final UUID accountId, final TenantContext context) {
         return dao.getAllInvoicesByAccount(accountId, internalCallContextFactory.createInternalTenantContext(context));
     }
@@ -75,18 +67,10 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public Invoice getInvoiceForPaymentId(final UUID paymentId, final TenantContext context) throws InvoiceApiException {
-        final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
-        final UUID invoiceIdStr = dao.getInvoiceIdByPaymentId(paymentId, internalTenantContext);
-        return invoiceIdStr == null ? null : dao.getById(invoiceIdStr, internalTenantContext);
-    }
-
-    @Override
     public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
         return dao.getInvoicePayments(paymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-
     @Override
     public InvoicePayment getInvoicePaymentForAttempt(final UUID paymentId, final TenantContext context) {
         final List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId, internalCallContextFactory.createInternalTenantContext(context));
@@ -101,16 +85,6 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         }).iterator().next();
     }
 
-    @Override
-    public void notifyOfPayment(final UUID invoiceId, final BigDecimal amount, final Currency currency, final UUID paymentId, final DateTime paymentDate, final CallContext context) throws InvoiceApiException {
-        final InvoicePayment invoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, paymentDate, amount, currency);
-
-        // Retrieve the account id for the internal call context
-        final Invoice invoice = dao.getById(invoiceId, internalCallContextFactory.createInternalTenantContext(context));
-        final UUID accountId = invoice.getAccountId();
-
-        dao.notifyOfPayment(invoicePayment, internalCallContextFactory.createInternalCallContext(accountId, context));
-    }
 
     @Override
     public BigDecimal getRemainingAmountPaid(final UUID invoicePaymentId, final TenantContext context) {
@@ -137,28 +111,6 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         return dao.getAccountIdFromInvoicePaymentId(invoicePaymentId, internalCallContextFactory.createInternalTenantContext(context));
     }
 
-    @Override
-    public InvoicePayment createRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted,
-                                       final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final UUID paymentCookieId,
-                                       final CallContext context) throws InvoiceApiException {
-
-        return invoicePaymentWithException.executeAndThrow(new WithInvoiceApiExceptionCallback<InvoicePayment>() {
-
-            @Override
-            public InvoicePayment doHandle() throws InvoiceApiException {
-                if (amount.compareTo(BigDecimal.ZERO) <= 0) {
-                    throw new InvoiceApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
-                }
-
-                // Retrieve the account id for the internal call context
-                final InternalTenantContext internalCallContextNoAccountId = internalCallContextFactory.createInternalTenantContext(context);
-                final List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId, internalCallContextNoAccountId);
-                final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePayments.get(0).getId(), internalCallContextNoAccountId);
-
-                return dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, paymentCookieId, internalCallContextFactory.createInternalCallContext(accountId, context));
-            }
-        });
-    }
 
     @Override
     public InvoicePayment createChargeback(final UUID invoicePaymentId, final CallContext context) throws InvoiceApiException {
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
index d0aef0f..b18be80 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/svcs/DefaultInvoiceInternalApi.java
@@ -18,20 +18,36 @@ package com.ning.billing.invoice.api.svcs;
 
 import java.math.BigDecimal;
 import java.util.Collection;
+import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 
 import javax.inject.Inject;
 
+import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
+import org.skife.jdbi.v2.exceptions.TransactionFailedException;
 
+import com.ning.billing.ErrorCode;
+import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
 import com.ning.billing.invoice.dao.InvoiceDao;
+import com.ning.billing.invoice.model.DefaultInvoicePayment;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+
 public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
 
+    private static final WithInvoiceApiException<InvoicePayment> invoicePaymentWithException = new WithInvoiceApiException<InvoicePayment>();
+
     private final InvoiceDao dao;
 
     @Inject
@@ -58,4 +74,77 @@ public class DefaultInvoiceInternalApi implements InvoiceInternalApi {
     public BigDecimal getAccountBalance(final UUID accountId, final InternalTenantContext context) {
         return dao.getAccountBalance(accountId, context);
     }
+
+    @Override
+    public void notifyOfPayment(final UUID invoiceId, final BigDecimal amount, final Currency currency, final UUID paymentId, final DateTime paymentDate, final InternalCallContext context) throws InvoiceApiException {
+        final InvoicePayment invoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, paymentDate, amount, currency);
+        dao.notifyOfPayment(invoicePayment, context);
+    }
+
+    @Override
+    public void notifyOfPayment(final InvoicePayment invoicePayment, final InternalCallContext context) throws InvoiceApiException {
+        // Retrieve the account id for the internal call context
+        final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePayment.getId(), context);
+        dao.notifyOfPayment(invoicePayment, context);
+    }
+
+    @Override
+    public InvoicePayment getInvoicePaymentForAttempt(final UUID paymentId, final InternalTenantContext context) throws InvoiceApiException {
+        final List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId, context);
+        if (invoicePayments.size() == 0) {
+            return null;
+        }
+        return Collections2.filter(invoicePayments, new Predicate<InvoicePayment>() {
+            @Override
+            public boolean apply(InvoicePayment input) {
+                return input.getType() == InvoicePaymentType.ATTEMPT;
+            }
+        }).iterator().next();
+    }
+
+    @Override
+    public Invoice getInvoiceForPaymentId(final UUID paymentId, final InternalTenantContext context) throws InvoiceApiException {
+        final UUID invoiceIdStr = dao.getInvoiceIdByPaymentId(paymentId, context);
+        return invoiceIdStr == null ? null : dao.getById(invoiceIdStr, context);
+    }
+
+    @Override
+    public InvoicePayment createRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final UUID paymentCookieId, final InternalCallContext context) throws InvoiceApiException {
+        return invoicePaymentWithException.executeAndThrow(new WithInvoiceApiExceptionCallback<InvoicePayment>() {
+
+            @Override
+            public InvoicePayment doHandle() throws InvoiceApiException {
+                if (amount.compareTo(BigDecimal.ZERO) <= 0) {
+                    throw new InvoiceApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
+                }
+
+                final List<InvoicePayment> invoicePayments = dao.getInvoicePayments(paymentId, context);
+                final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePayments.get(0).getId(), context);
+
+                return dao.createRefund(paymentId, amount, isInvoiceAdjusted, invoiceItemIdsWithAmounts, paymentCookieId, context);
+            }
+        });
+    }
+
+    //
+    // Allow to safely catch TransactionFailedException exceptions and rethrow the correct InvoiceApiException exception
+    //
+    private interface WithInvoiceApiExceptionCallback<T> {
+        public T doHandle() throws InvoiceApiException;
+    }
+
+    private static final class WithInvoiceApiException<T> {
+        public T executeAndThrow(final WithInvoiceApiExceptionCallback<T> callback) throws InvoiceApiException  {
+
+            try {
+                return callback.doHandle();
+            } catch (TransactionFailedException e) {
+                if (e.getCause() instanceof InvoiceApiException) {
+                    throw (InvoiceApiException) e.getCause();
+                } else {
+                    throw e;
+                }
+            }
+        }
+    }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 5349ab0..3ea248f 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -94,13 +94,6 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) throws InvoiceApiException {
-        // Retrieve the account id for the internal call context
-        final UUID accountId = dao.getAccountIdFromInvoicePaymentId(invoicePayment.getId(), internalCallContextFactory.createInternalTenantContext(context));
-        dao.notifyOfPayment(invoicePayment, internalCallContextFactory.createInternalCallContext(accountId, context));
-    }
-
-    @Override
     public BigDecimal getAccountBalance(final UUID accountId, final TenantContext context) {
         final BigDecimal result = dao.getAccountBalance(accountId, internalCallContextFactory.createInternalTenantContext(context));
         return result == null ? BigDecimal.ZERO : result;
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
index 3f14f86..ccd01ae 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/invoice/TestDefaultInvoicePaymentApi.java
@@ -16,9 +16,6 @@
 
 package com.ning.billing.invoice.api.invoice;
 
-import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistInvoice;
-import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistPayment;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
@@ -41,6 +38,7 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePayment.InvoicePaymentType;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
+import com.ning.billing.invoice.api.svcs.DefaultInvoiceInternalApi;
 import com.ning.billing.invoice.dao.AuditedInvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceItemSqlDao;
@@ -50,11 +48,15 @@ import com.ning.billing.invoice.notification.NextBillingDatePoster;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 import com.ning.billing.util.svcsapi.bus.InternalBus;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 
+import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistInvoice;
+import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistPayment;
+
 public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB {
 
     private static final BigDecimal THIRTY = new BigDecimal("30.00");
@@ -65,6 +67,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
     private InvoiceSqlDao invoiceSqlDao;
     private InvoiceItemSqlDao invoiceItemSqlDao;
     private InvoicePaymentApi invoicePaymentApi;
+    private InvoiceInternalApi invoiceInternalApi;
     private InternalCallContextFactory internalCallContextFactory;
 
     @BeforeSuite(groups = "slow")
@@ -82,6 +85,7 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
         internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
         final InvoiceDao invoiceDao = new AuditedInvoiceDao(dbi, nextBillingDatePoster, clock, Mockito.mock(InternalBus.class));
         invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao, internalCallContextFactory);
+        invoiceInternalApi = new DefaultInvoiceInternalApi(invoiceDao);
     }
 
     @Test(groups = "slow")
@@ -150,15 +154,15 @@ public class TestDefaultInvoicePaymentApi extends InvoiceTestSuiteWithEmbeddedDB
 
     private void verifyRefund(final Invoice invoice, final BigDecimal invoiceAmount, final BigDecimal refundAmount, final BigDecimal finalInvoiceAmount,
                               final boolean adjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts) throws InvoiceApiException {
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), invoiceAmount, CURRENCY, callContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceInternalApi, clock, invoice.getId(), invoiceAmount, CURRENCY, internalCallContext);
 
         // Verify the initial invoice balance
         final BigDecimal initialInvoiceBalance = invoicePaymentApi.getInvoice(invoice.getId(), callContext).getBalance();
         Assert.assertEquals(initialInvoiceBalance.compareTo(BigDecimal.ZERO), 0);
 
         // Create a full refund with no adjustment
-        final InvoicePayment refund = invoicePaymentApi.createRefund(payment.getPaymentId(), refundAmount, adjusted, invoiceItemIdsWithAmounts,
-                                                                     UUID.randomUUID(), callContext);
+        final InvoicePayment refund = invoiceInternalApi.createRefund(payment.getPaymentId(), refundAmount, adjusted, invoiceItemIdsWithAmounts,
+                                                                      UUID.randomUUID(), internalCallContext);
         Assert.assertEquals(refund.getAmount().compareTo(refundAmount.negate()), 0);
         Assert.assertEquals(refund.getCurrency(), CURRENCY);
         Assert.assertEquals(refund.getInvoiceId(), invoice.getId());
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
index 66ba437..ecd23bd 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
@@ -20,7 +20,6 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.CopyOnWriteArrayList;
 
@@ -34,6 +33,7 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TenantContext;
 
 public class MockInvoicePaymentApi implements InvoicePaymentApi {
+
     private final CopyOnWriteArrayList<Invoice> invoices = new CopyOnWriteArrayList<Invoice>();
     private final CopyOnWriteArrayList<InvoicePayment> invoicePayments = new CopyOnWriteArrayList<InvoicePayment>();
 
@@ -42,16 +42,6 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public void notifyOfPayment(final InvoicePayment invoicePayment, final CallContext context) {
-        for (final InvoicePayment existingInvoicePayment : invoicePayments) {
-            if (existingInvoicePayment.getInvoiceId().equals(invoicePayment.getInvoiceId()) && existingInvoicePayment.getPaymentId().equals(invoicePayment.getPaymentId())) {
-                invoicePayments.remove(existingInvoicePayment);
-            }
-        }
-        invoicePayments.add(invoicePayment);
-    }
-
-    @Override
     public List<Invoice> getAllInvoicesByAccount(final UUID accountId, final TenantContext context) {
         final ArrayList<Invoice> result = new ArrayList<Invoice>();
 
@@ -73,15 +63,6 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
         return null;
     }
 
-    @Override
-    public Invoice getInvoiceForPaymentId(final UUID paymentId, final TenantContext context) {
-        for (final InvoicePayment invoicePayment : invoicePayments) {
-            if (invoicePayment.getPaymentId().equals(paymentId)) {
-                return getInvoice(invoicePayment.getInvoiceId(), context);
-            }
-        }
-        return null;
-    }
 
     @Override
     public List<InvoicePayment> getInvoicePayments(final UUID paymentId, final TenantContext context) {
@@ -106,12 +87,6 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
 
 
     @Override
-    public void notifyOfPayment(final UUID invoiceId, final BigDecimal amountOutstanding, final Currency currency, final UUID paymentId, final DateTime paymentDate, final CallContext context) {
-        final InvoicePayment invoicePayment = new DefaultInvoicePayment(InvoicePaymentType.ATTEMPT, paymentId, invoiceId, paymentDate, amountOutstanding, currency);
-        notifyOfPayment(invoicePayment, context);
-    }
-
-    @Override
     public InvoicePayment createChargeback(final UUID invoicePaymentId, final BigDecimal amount, final CallContext context) throws InvoiceApiException {
         InvoicePayment existingPayment = null;
         for (final InvoicePayment payment : invoicePayments) {
@@ -123,7 +98,7 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
 
         if (existingPayment != null) {
             invoicePayments.add(new DefaultInvoicePayment(UUID.randomUUID(), InvoicePaymentType.CHARGED_BACK, null, null, DateTime.now(DateTimeZone.UTC), amount,
-                    Currency.USD, null, existingPayment.getId()));
+                                                          Currency.USD, null, existingPayment.getId()));
         }
 
         return existingPayment;
@@ -180,12 +155,4 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi {
     public InvoicePayment getChargebackById(final UUID chargebackId, final TenantContext context) {
         throw new UnsupportedOperationException();
     }
-
-    @Override
-    public InvoicePayment createRefund(final UUID paymentId, final BigDecimal amount, final boolean isInvoiceAdjusted,
-                                       final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final UUID paymentCookieId,
-                                       final CallContext context)
-            throws InvoiceApiException {
-        return null;
-    }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java
index d572117..9a57ab5 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/InvoiceTestUtils.java
@@ -34,8 +34,10 @@ import com.ning.billing.invoice.dao.InvoiceItemSqlDao;
 import com.ning.billing.invoice.dao.InvoiceSqlDao;
 import com.ning.billing.invoice.model.FixedPriceInvoiceItem;
 import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 
 import com.google.common.collect.ImmutableList;
 
@@ -90,12 +92,12 @@ public class InvoiceTestUtils {
                                          "charge back test", "charge back phase", clock.getUTCToday(), amount, currency);
     }
 
-    public static InvoicePayment createAndPersistPayment(final InvoicePaymentApi invoicePaymentApi,
+    public static InvoicePayment createAndPersistPayment(final InvoiceInternalApi invoicePaymentApi,
                                                          final Clock clock,
                                                          final UUID invoiceId,
                                                          final BigDecimal amount,
                                                          final Currency currency,
-                                                         final CallContext callContext) throws InvoiceApiException {
+                                                         final InternalCallContext callContext) throws InvoiceApiException {
         final InvoicePayment payment = Mockito.mock(InvoicePayment.class);
         Mockito.when(payment.getId()).thenReturn(UUID.randomUUID());
         Mockito.when(payment.getType()).thenReturn(InvoicePaymentType.ATTEMPT);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
index 5280304..78904ec 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/tests/TestChargeBacks.java
@@ -16,13 +16,6 @@
 
 package com.ning.billing.invoice.tests;
 
-import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistInvoice;
-import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistPayment;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URL;
@@ -44,6 +37,7 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoicePayment;
 import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.invoice.api.invoice.DefaultInvoicePaymentApi;
+import com.ning.billing.invoice.api.svcs.DefaultInvoiceInternalApi;
 import com.ning.billing.invoice.dao.AuditedInvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceItemSqlDao;
@@ -54,8 +48,16 @@ import com.ning.billing.invoice.notification.NextBillingDatePoster;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.clock.ClockMock;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 import com.ning.billing.util.svcsapi.bus.InternalBus;
 
+import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistInvoice;
+import static com.ning.billing.invoice.tests.InvoiceTestUtils.createAndPersistPayment;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
 public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
 
     private static final BigDecimal FIFTEEN = new BigDecimal("15.00");
@@ -64,6 +66,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     private InvoiceSqlDao invoiceSqlDao;
     private InvoiceItemSqlDao invoiceItemSqlDao;
     private InvoicePaymentApi invoicePaymentApi;
+    private InvoiceInternalApi invoiceApi;
     private InternalCallContextFactory internalCallContextFactory;
 
     private final Clock clock = new ClockMock();
@@ -85,6 +88,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
         internalCallContextFactory = new InternalCallContextFactory(dbi, clock);
         final InvoiceDao invoiceDao = new AuditedInvoiceDao(dbi, nextBillingDatePoster, clock, Mockito.mock(InternalBus.class));
         invoicePaymentApi = new DefaultInvoicePaymentApi(invoiceDao, internalCallContextFactory);
+        invoiceApi = new DefaultInvoiceInternalApi(invoiceDao);
     }
 
     private static void loadSystemPropertiesFromClasspath(final String resource) {
@@ -100,7 +104,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testCompleteChargeBack() throws InvoiceApiException {
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
         // create a full charge back
         invoicePaymentApi.createChargeback(payment.getId(), THIRTY, callContext);
@@ -113,7 +117,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testPartialChargeBack() throws InvoiceApiException {
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
         // create a partial charge back
         invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, callContext);
@@ -127,7 +131,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     public void testChargeBackLargerThanPaymentAmount() throws InvoiceApiException {
         try {
             final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-            final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+            final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
             // create a large charge back
             invoicePaymentApi.createChargeback(payment.getId(), ONE_MILLION, callContext);
@@ -141,7 +145,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     public void testNegativeChargeBackAmount() throws InvoiceApiException {
         try {
             final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-            final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+            final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
             // create a partial charge back
             invoicePaymentApi.createChargeback(payment.getId(), BigDecimal.ONE.negate(), callContext);
@@ -153,7 +157,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testGetAccountIdFromPaymentIdHappyPath() throws InvoiceApiException {
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
         final UUID accountId = invoicePaymentApi.getAccountIdFromInvoicePaymentId(payment.getId(), callContext);
         assertEquals(accountId, invoice.getAccountId());
     }
@@ -173,7 +177,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testGetChargeBacksByAccountIdHappyPath() throws InvoiceApiException {
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
         // create a partial charge back
         invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, callContext);
@@ -194,7 +198,7 @@ public class TestChargeBacks extends InvoiceTestSuiteWithEmbeddedDB {
     @Test(groups = "slow")
     public void testGetChargeBacksByInvoicePaymentIdHappyPath() throws InvoiceApiException {
         final Invoice invoice = createAndPersistInvoice(invoiceSqlDao, invoiceItemSqlDao, clock, THIRTY, CURRENCY, callContext, internalCallContextFactory);
-        final InvoicePayment payment = createAndPersistPayment(invoicePaymentApi, clock, invoice.getId(), THIRTY, CURRENCY, callContext);
+        final InvoicePayment payment = createAndPersistPayment(invoiceApi, clock, invoice.getId(), THIRTY, CURRENCY, internalCallContext);
 
         // create a partial charge back
         invoicePaymentApi.createChargeback(payment.getId(), FIFTEEN, callContext);
diff --git a/payment/src/main/java/com/ning/billing/payment/api/svcs/DefaultPaymentInternalApi.java b/payment/src/main/java/com/ning/billing/payment/api/svcs/DefaultPaymentInternalApi.java
new file mode 100644
index 0000000..035650e
--- /dev/null
+++ b/payment/src/main/java/com/ning/billing/payment/api/svcs/DefaultPaymentInternalApi.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.payment.api.svcs;
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import com.ning.billing.ErrorCode;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.payment.api.Payment;
+import com.ning.billing.payment.api.PaymentApiException;
+import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.payment.core.PaymentMethodProcessor;
+import com.ning.billing.payment.core.PaymentProcessor;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
+
+public class DefaultPaymentInternalApi implements PaymentInternalApi {
+
+    private final PaymentProcessor paymentProcessor;
+    private final PaymentMethodProcessor methodProcessor;
+
+    @Inject
+    public DefaultPaymentInternalApi(final PaymentProcessor paymentProcessor, final PaymentMethodProcessor methodProcessor) {
+        this.paymentProcessor = paymentProcessor;
+        this.methodProcessor = methodProcessor;
+    }
+
+    @Override
+    public Payment getPayment(final UUID paymentId, final InternalTenantContext context) throws PaymentApiException {
+        final Payment payment = paymentProcessor.getPayment(paymentId, context);
+        if (payment == null) {
+            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
+        }
+        return payment;
+    }
+
+    @Override
+    public PaymentMethod getPaymentMethod(final Account account, final UUID paymentMethodId, final boolean withPluginDetail, final InternalTenantContext context) throws PaymentApiException {
+        return methodProcessor.getPaymentMethod(account, paymentMethodId, withPluginDetail, context);
+    }
+
+    @Override
+    public List<Payment> getAccountPayments(final UUID accountId, final InternalTenantContext context) throws PaymentApiException {
+        return paymentProcessor.getAccountPayments(accountId, context);
+    }
+
+    @Override
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginDetail, final InternalTenantContext context) throws PaymentApiException {
+        return methodProcessor.getPaymentMethods(account, withPluginDetail, context);
+    }
+}
diff --git a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
index a3b0a3f..9f30ced 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/PaymentProcessor.java
@@ -39,7 +39,6 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.payment.api.DefaultPayment;
 import com.ning.billing.payment.api.DefaultPaymentErrorEvent;
 import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
@@ -65,6 +64,7 @@ import com.ning.billing.util.events.BusInternalEvent;
 import com.ning.billing.util.events.PaymentErrorInternalEvent;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 import com.ning.billing.util.svcapi.tag.TagInternalApi;
 import com.ning.billing.util.svcsapi.bus.InternalBus;
 
@@ -75,7 +75,7 @@ import com.google.inject.name.Named;
 public class PaymentProcessor extends ProcessorBase {
 
     private final PaymentMethodProcessor paymentMethodProcessor;
-    private final InvoicePaymentApi invoicePaymentApi;
+    private final InvoiceInternalApi invoiceApi;
     private final FailedPaymentRetryServiceScheduler failedPaymentRetryService;
     private final PluginFailureRetryServiceScheduler pluginFailureRetryService;
     private final AutoPayRetryServiceScheduler autoPayoffRetryService;
@@ -93,7 +93,7 @@ public class PaymentProcessor extends ProcessorBase {
     public PaymentProcessor(final PaymentProviderPluginRegistry pluginRegistry,
                             final PaymentMethodProcessor paymentMethodProcessor,
                             final AccountInternalApi accountUserApi,
-                            final InvoicePaymentApi invoicePaymentApi,
+                            final InvoiceInternalApi invoiceApi,
                             final TagInternalApi tagUserApi,
                             final FailedPaymentRetryServiceScheduler failedPaymentRetryService,
                             final PluginFailureRetryServiceScheduler pluginFailureRetryService,
@@ -106,7 +106,7 @@ public class PaymentProcessor extends ProcessorBase {
                             @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
         super(pluginRegistry, accountUserApi, eventBus, paymentDao, tagUserApi, locker, executor);
         this.paymentMethodProcessor = paymentMethodProcessor;
-        this.invoicePaymentApi = invoicePaymentApi;
+        this.invoiceApi = invoiceApi;
         this.failedPaymentRetryService = failedPaymentRetryService;
         this.pluginFailureRetryService = pluginFailureRetryService;
         this.autoPayoffRetryService = autoPayoffRetryService;
@@ -229,7 +229,7 @@ public class PaymentProcessor extends ProcessorBase {
 
 
                     try {
-                        final Invoice invoice = invoicePaymentApi.getInvoice(invoiceId, context.toCallContext());
+                        final Invoice invoice = invoiceApi.getInvoiceById(invoiceId, context);
 
                         if (invoice.isMigrationInvoice()) {
                             log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
@@ -353,7 +353,7 @@ public class PaymentProcessor extends ProcessorBase {
                             return null;
                         }
 
-                        final Invoice invoice = invoicePaymentApi.getInvoice(payment.getInvoiceId(), context.toCallContext());
+                        final Invoice invoice = invoiceApi.getInvoiceById(payment.getInvoiceId(), context);
                         if (invoice.isMigrationInvoice()) {
                             return null;
                         }
@@ -434,12 +434,12 @@ public class PaymentProcessor extends ProcessorBase {
                 allAttempts = paymentDao.getAttemptsForPayment(paymentInput.getId(), context);
 
                 payment = paymentDao.getPayment(paymentInput.getId(), context);
-                invoicePaymentApi.notifyOfPayment(invoice.getId(),
+                invoiceApi.notifyOfPayment(invoice.getId(),
                         payment.getAmount(),
                         paymentStatus == PaymentStatus.SUCCESS ? payment.getCurrency() : null,
                                 payment.getId(),
                                 payment.getEffectiveDate(),
-                                context.toCallContext());
+                                context);
 
                 // Create Bus event
                 event = new DefaultPaymentInfoEvent(account.getId(),
diff --git a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
index dbc2459..8509d69 100644
--- a/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/core/RefundProcessor.java
@@ -38,7 +38,6 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.payment.api.DefaultRefund;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.Refund;
@@ -56,6 +55,7 @@ import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.globallocker.GlobalLocker;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 import com.ning.billing.util.svcapi.tag.TagInternalApi;
 import com.ning.billing.util.svcsapi.bus.InternalBus;
 
@@ -70,13 +70,13 @@ public class RefundProcessor extends ProcessorBase {
 
     private static final Logger log = LoggerFactory.getLogger(RefundProcessor.class);
 
-    private final InvoicePaymentApi invoicePaymentApi;
+    private final InvoiceInternalApi invoiceApi;
     private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
     public RefundProcessor(final PaymentProviderPluginRegistry pluginRegistry,
                            final AccountInternalApi accountApi,
-                           final InvoicePaymentApi invoicePaymentApi,
+                           final InvoiceInternalApi invoiceApi,
                            final InternalBus eventBus,
                            final InternalCallContextFactory internalCallContextFactory,
                            final TagInternalApi tagUserApi,
@@ -84,7 +84,7 @@ public class RefundProcessor extends ProcessorBase {
                            final GlobalLocker locker,
                            @Named(PLUGIN_EXECUTOR_NAMED) final ExecutorService executor) {
         super(pluginRegistry, accountApi, eventBus, paymentDao, tagUserApi, locker, executor);
-        this.invoicePaymentApi = invoicePaymentApi;
+        this.invoiceApi = invoiceApi;
         this.internalCallContextFactory = internalCallContextFactory;
     }
 
@@ -166,7 +166,7 @@ public class RefundProcessor extends ProcessorBase {
                     }
                     paymentDao.updateRefundStatus(refundInfo.getId(), RefundStatus.PLUGIN_COMPLETED, context);
 
-                    invoicePaymentApi.createRefund(paymentId, refundAmount, isAdjusted, invoiceItemIdsWithAmounts, refundInfo.getId(), context.toCallContext());
+                    invoiceApi.createRefund(paymentId, refundAmount, isAdjusted, invoiceItemIdsWithAmounts, refundInfo.getId(), context);
 
                     paymentDao.updateRefundStatus(refundInfo.getId(), RefundStatus.COMPLETED, context);
 
@@ -194,7 +194,7 @@ public class RefundProcessor extends ProcessorBase {
                                            final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final InternalTenantContext context)
             throws PaymentApiException {
         try {
-            final List<InvoiceItem> items = invoicePaymentApi.getInvoiceForPaymentId(paymentId, context.toTenantContext()).getInvoiceItems();
+            final List<InvoiceItem> items = invoiceApi.getInvoiceForPaymentId(paymentId, context).getInvoiceItems();
 
             BigDecimal amountFromItems = BigDecimal.ZERO;
             for (final UUID itemId : invoiceItemIdsWithAmounts.keySet()) {
@@ -304,7 +304,7 @@ public class RefundProcessor extends ProcessorBase {
                     try {
                         for (final RefundModelDao cur : refundsToBeFixed) {
                             // TODO - we currently don't save the items to be adjusted. If we crash, they won't be adjusted...
-                            invoicePaymentApi.createRefund(cur.getPaymentId(), cur.getAmount(), cur.isAdjsuted(), ImmutableMap.<UUID, BigDecimal>of(), cur.getId(), context.toCallContext());
+                            invoiceApi.createRefund(cur.getPaymentId(), cur.getAmount(), cur.isAdjsuted(), ImmutableMap.<UUID, BigDecimal>of(), cur.getId(), context);
                             paymentDao.updateRefundStatus(cur.getId(), RefundStatus.COMPLETED, context);
                         }
                     } catch (InvoiceApiException e) {
diff --git a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
index 9e601aa..f8d0125 100644
--- a/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/glue/PaymentModule.java
@@ -29,6 +29,7 @@ import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.payment.api.DefaultPaymentApi;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentService;
+import com.ning.billing.payment.api.svcs.DefaultPaymentInternalApi;
 import com.ning.billing.payment.bus.InvoiceHandler;
 import com.ning.billing.payment.bus.TagHandler;
 import com.ning.billing.payment.core.PaymentMethodProcessor;
@@ -43,6 +44,7 @@ import com.ning.billing.payment.retry.FailedPaymentRetryService;
 import com.ning.billing.payment.retry.FailedPaymentRetryService.FailedPaymentRetryServiceScheduler;
 import com.ning.billing.payment.retry.PluginFailureRetryService;
 import com.ning.billing.payment.retry.PluginFailureRetryService.PluginFailureRetryServiceScheduler;
+import com.ning.billing.util.svcapi.payment.PaymentInternalApi;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.AbstractModule;
@@ -109,6 +111,7 @@ public class PaymentModule extends AbstractModule {
         bind(PaymentConfig.class).toInstance(paymentConfig);
         bind(PaymentProviderPluginRegistry.class).toProvider(DefaultPaymentProviderPluginRegistryProvider.class).asEagerSingleton();
 
+        bind(PaymentInternalApi.class).to(DefaultPaymentInternalApi.class).asEagerSingleton();
         bind(PaymentApi.class).to(DefaultPaymentApi.class).asEagerSingleton();
         bind(InvoiceHandler.class).asEagerSingleton();
         bind(TagHandler.class).asEagerSingleton();
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index a4ad080..8224949 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -16,11 +16,6 @@
 
 package com.ning.billing.payment.api;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.util.List;
@@ -40,7 +35,6 @@ import com.ning.billing.ErrorCode;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.mock.glue.MockClockModule;
 import com.ning.billing.mock.glue.MockJunctionModule;
 import com.ning.billing.payment.MockRecurringInvoiceItem;
@@ -57,6 +51,11 @@ import com.ning.billing.util.svcsapi.bus.InternalBus.EventBusException;
 
 import com.google.inject.Inject;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
 @Guice(modules = {PaymentTestModuleWithMocks.class, MockClockModule.class, MockJunctionModule.class, CallContextModule.class})
 public class TestPaymentApi extends PaymentTestSuite {
     private static final Logger log = LoggerFactory.getLogger(TestPaymentApi.class);
@@ -70,8 +69,6 @@ public class TestPaymentApi extends PaymentTestSuite {
     @Inject
     protected TestHelper testHelper;
     @Inject
-    protected InvoicePaymentApi invoicePaymentApi;
-    @Inject
     protected Clock clock;
 
     private Account account;
diff --git a/payment/src/test/java/com/ning/billing/payment/TestHelper.java b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
index 001a8ae..17ea477 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestHelper.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestHelper.java
@@ -26,7 +26,6 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceItem;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.mock.api.MockBillCycleDay;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentMethodPlugin;
@@ -37,11 +36,11 @@ import com.ning.billing.util.callcontext.CallContextFactory;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.InternalCallContextFactory;
 import com.ning.billing.util.callcontext.InternalTenantContext;
-import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
 import com.ning.billing.util.events.InvoiceCreationInternalEvent;
 import com.ning.billing.util.svcapi.account.AccountInternalApi;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
 import com.ning.billing.util.svcsapi.bus.InternalBus;
 import com.ning.billing.util.svcsapi.bus.InternalBus.EventBusException;
 
@@ -49,7 +48,7 @@ import com.google.inject.Inject;
 
 public class TestHelper {
     protected final AccountInternalApi AccountApi;
-    protected final InvoicePaymentApi invoicePaymentApi;
+    protected final InvoiceInternalApi invoiceApi;
     protected PaymentApi paymentApi;
     private final CallContext context;
     private final InternalBus eventBus;
@@ -57,11 +56,11 @@ public class TestHelper {
     private final InternalCallContextFactory internalCallContextFactory;
 
     @Inject
-    public TestHelper(final CallContextFactory factory, final AccountInternalApi AccountApi, final InvoicePaymentApi invoicePaymentApi,
+    public TestHelper(final CallContextFactory factory, final AccountInternalApi AccountApi, final InvoiceInternalApi invoiceApi,
                       final PaymentApi paymentApi, final InternalBus eventBus, final Clock clock, final InternalCallContextFactory internalCallContextFactory) {
         this.eventBus = eventBus;
         this.AccountApi = AccountApi;
-        this.invoicePaymentApi = invoicePaymentApi;
+        this.invoiceApi = invoiceApi;
         this.paymentApi = paymentApi;
         this.clock = clock;
         this.internalCallContextFactory = internalCallContextFactory;
@@ -92,7 +91,7 @@ public class TestHelper {
             }
         }
 
-        Mockito.when(invoicePaymentApi.getInvoice(Mockito.eq(invoice.getId()), Mockito.<TenantContext>any())).thenReturn(invoice);
+        Mockito.when(invoiceApi.getInvoiceById(Mockito.eq(invoice.getId()), Mockito.<InternalTenantContext>any())).thenReturn(invoice);
         final InvoiceCreationInternalEvent event = new MockInvoiceCreationEvent(invoice.getId(), invoice.getAccountId(),
                                                                         invoice.getBalance(), invoice.getCurrency(),
                                                                         invoice.getInvoiceDate(),
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index 28cefd5..aed4a79 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -34,7 +34,6 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.config.PaymentConfig;
 import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.api.InvoicePaymentApi;
 import com.ning.billing.mock.glue.MockClockModule;
 import com.ning.billing.mock.glue.MockJunctionModule;
 import com.ning.billing.payment.api.Payment;
@@ -48,9 +47,10 @@ import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
 import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
 import com.ning.billing.payment.retry.FailedPaymentRetryService;
 import com.ning.billing.payment.retry.PluginFailureRetryService;
-import com.ning.billing.util.svcsapi.bus.InternalBus;
 import com.ning.billing.util.clock.ClockMock;
 import com.ning.billing.util.glue.CallContextModule;
+import com.ning.billing.util.svcapi.invoice.InvoiceInternalApi;
+import com.ning.billing.util.svcsapi.bus.InternalBus;
 
 import com.google.inject.Inject;
 
@@ -69,7 +69,7 @@ public class TestRetryService extends PaymentTestSuite {
     @Inject
     private PaymentProcessor paymentProcessor;
     @Inject
-    private InvoicePaymentApi invoicePaymentApi;
+    private InvoiceInternalApi invoiceApi;
     @Inject
     private TestHelper testHelper;
     @Inject
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/invoice/InvoiceInternalApi.java b/util/src/main/java/com/ning/billing/util/svcapi/invoice/InvoiceInternalApi.java
index c54efe0..ffcfaef 100644
--- a/util/src/main/java/com/ning/billing/util/svcapi/invoice/InvoiceInternalApi.java
+++ b/util/src/main/java/com/ning/billing/util/svcapi/invoice/InvoiceInternalApi.java
@@ -18,12 +18,18 @@ package com.ning.billing.util.svcapi.invoice;
 
 import java.math.BigDecimal;
 import java.util.Collection;
+import java.util.Map;
 import java.util.UUID;
 
+import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 
+import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceApiException;
+import com.ning.billing.invoice.api.InvoicePayment;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 
 public interface InvoiceInternalApi {
@@ -35,4 +41,28 @@ public interface InvoiceInternalApi {
     public Collection<Invoice> getInvoicesByAccountId(UUID accountId, InternalTenantContext context);
 
     public BigDecimal getAccountBalance(UUID accountId, InternalTenantContext context);
+
+    public void notifyOfPayment(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentId, DateTime paymentDate, InternalCallContext context) throws InvoiceApiException;
+
+    public void notifyOfPayment(InvoicePayment invoicePayment, InternalCallContext context) throws InvoiceApiException;
+
+    public InvoicePayment getInvoicePaymentForAttempt(UUID paymentId, InternalTenantContext context) throws InvoiceApiException;
+
+    public Invoice getInvoiceForPaymentId(UUID paymentId, InternalTenantContext context) throws InvoiceApiException;
+
+    /**
+     * Create a refund.
+     *
+     * @param paymentId                 payment associated with that refund
+     * @param amount                    amount to refund
+     * @param isInvoiceAdjusted         whether the refund should trigger an invoice or invoice item adjustment
+     * @param invoiceItemIdsWithAmounts invoice item ids and associated amounts to adjust
+     * @param paymentCookieId           payment cookie id
+     * @param context                   the call context
+     * @return the created invoice payment object associated with this refund
+     * @throws InvoiceApiException
+     */
+    public InvoicePayment createRefund(UUID paymentId, BigDecimal amount, boolean isInvoiceAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts,
+                                       UUID paymentCookieId, InternalCallContext context) throws InvoiceApiException;
+
 }
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/payment/PaymentInternalApi.java b/util/src/main/java/com/ning/billing/util/svcapi/payment/PaymentInternalApi.java
new file mode 100644
index 0000000..f0d144a
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/svcapi/payment/PaymentInternalApi.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010-2012 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.ning.billing.util.svcapi.payment;
+
+
+import java.util.List;
+import java.util.UUID;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.payment.api.Payment;
+import com.ning.billing.payment.api.PaymentApiException;
+import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.util.callcontext.InternalTenantContext;
+
+public interface PaymentInternalApi {
+
+    public Payment getPayment(UUID paymentId, InternalTenantContext context)
+            throws PaymentApiException;
+
+    public PaymentMethod getPaymentMethod(Account account, UUID paymentMethodId, boolean withPluginDetail, InternalTenantContext context)
+            throws PaymentApiException;
+
+    public List<Payment> getAccountPayments(UUID accountId, InternalTenantContext context)
+            throws PaymentApiException;
+
+    public List<PaymentMethod> getPaymentMethods(Account account, boolean withPluginDetail, InternalTenantContext context)
+            throws PaymentApiException;
+}