killbill-uncached

payment: update to killbill-api 0.9.1 Signed-off-by: Pierre-Alexandre

4/24/2014 9:29:13 AM

Changes

pom.xml 2(+1 -1)

Details

diff --git a/api/src/main/java/org/killbill/billing/payment/api/PaymentInternalApi.java b/api/src/main/java/org/killbill/billing/payment/api/PaymentInternalApi.java
index a8b0c5d..129972d 100644
--- a/api/src/main/java/org/killbill/billing/payment/api/PaymentInternalApi.java
+++ b/api/src/main/java/org/killbill/billing/payment/api/PaymentInternalApi.java
@@ -1,7 +1,9 @@
 /*
- * Copyright 2010-2012 Ning, Inc.
+ * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -20,22 +22,19 @@ import java.util.List;
 import java.util.UUID;
 
 import org.killbill.billing.account.api.Account;
-import org.killbill.billing.payment.api.Payment;
-import org.killbill.billing.payment.api.PaymentApiException;
-import org.killbill.billing.payment.api.PaymentMethod;
 import org.killbill.billing.callcontext.InternalTenantContext;
 
 public interface PaymentInternalApi {
 
-    public Payment getPayment(UUID paymentId, InternalTenantContext context)
+    public Payment getPayment(UUID paymentId, Iterable<PluginProperty> properties, InternalTenantContext context)
             throws PaymentApiException;
 
-    public PaymentMethod getPaymentMethodById(UUID paymentMethodId, final boolean includedInactive, InternalTenantContext context)
+    public PaymentMethod getPaymentMethodById(UUID paymentMethodId, boolean includedInactive, Iterable<PluginProperty> properties, InternalTenantContext context)
             throws PaymentApiException;
 
     public List<Payment> getAccountPayments(UUID accountId, InternalTenantContext context)
             throws PaymentApiException;
 
-    public List<PaymentMethod> getPaymentMethods(Account account, InternalTenantContext context)
+    public List<PaymentMethod> getPaymentMethods(Account account, Iterable<PluginProperty> properties, InternalTenantContext context)
             throws PaymentApiException;
 }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueBase.java
index ec57bce..2a9764d 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueBase.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -20,9 +22,6 @@ import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.concurrent.Callable;
 
-import org.testng.Assert;
-import org.testng.annotations.BeforeMethod;
-
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.beatrix.integration.BeatrixIntegrationModule;
 import org.killbill.billing.beatrix.integration.TestIntegrationBase;
@@ -34,6 +33,8 @@ import org.killbill.billing.overdue.config.OverdueConfig;
 import org.killbill.billing.payment.api.PaymentMethodPlugin;
 import org.killbill.billing.payment.api.TestPaymentMethodPluginBase;
 import org.killbill.billing.util.config.catalog.XMLLoader;
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
 
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.SECONDS;
@@ -62,7 +63,7 @@ public abstract class TestOverdueBase extends TestIntegrationBase {
         account = createAccountWithNonOsgiPaymentMethod(getAccountData(0));
         assertNotNull(account);
 
-        paymentApi.addPaymentMethod(BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, account, true, paymentMethodPlugin, callContext);
+        paymentApi.addPaymentMethod(BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, account, true, paymentMethodPlugin, PLUGIN_PROPERTIES, callContext);
         productName = "Shotgun";
         term = BillingPeriod.MONTHLY;
         paymentPlugin.clear();
@@ -81,7 +82,7 @@ public abstract class TestOverdueBase extends TestIntegrationBase {
                     return expected.equals(blockingApi.getBlockingStateForService(account.getId(), BlockingStateType.ACCOUNT, OverdueService.OVERDUE_SERVICE_NAME, internalCallContext).getStateName());
                 }
             });
-        } catch (Exception e) {
+        } catch (final Exception e) {
             Assert.assertEquals(blockingApi.getBlockingStateForService(account.getId(), BlockingStateType.ACCOUNT, OverdueService.OVERDUE_SERVICE_NAME, internalCallContext).getStateName(), expected, "Got exception: " + e.toString());
         }
     }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 11e5465..6f6a149 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -25,10 +27,6 @@ import java.util.List;
 
 import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
-import org.killbill.billing.invoice.api.InvoiceItem;
-import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.api.TestApiListener.NextEvent;
 import org.killbill.billing.beatrix.integration.BeatrixIntegrationModule;
@@ -42,10 +40,13 @@ import org.killbill.billing.entitlement.api.DefaultEntitlement;
 import org.killbill.billing.entitlement.api.Entitlement;
 import org.killbill.billing.entitlement.api.EntitlementApiException;
 import org.killbill.billing.invoice.api.Invoice;
+import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.invoice.api.InvoicePayment;
+import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
 import org.killbill.billing.junction.DefaultBlockingState;
 import org.killbill.billing.payment.api.Payment;
+import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
@@ -283,7 +284,6 @@ public class TestOverdueIntegration extends TestOverdueBase {
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 10), new LocalDate(2012, 7, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-169.32")),
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 7, 31), InvoiceItemType.CBA_ADJ, new BigDecimal("169.32")));
 
-
         invoiceChecker.checkInvoice(account.getId(), 4, callContext,
                                     // New invoice for the partial period since we unblocked on the 1st and so are missing the 31 july
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2012, 8, 31), InvoiceItemType.RECURRING, new BigDecimal("249.95")),
@@ -376,7 +376,6 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // 2012, 8, 1 => Nothing should have happened
         addDaysAndCheckForCompletion(1);
 
-
         allowPaymentsAndResetOverdueToClearByPayingAllUnpaidInvoices(true);
 
         invoiceChecker.checkInvoice(account.getId(), 3, callContext,
@@ -494,7 +493,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         assertEquals(invoiceUserApi.getAccountBalance(account.getId(), callContext).compareTo(new BigDecimal("-14.49")), 0);
     }
 
-    @Test(groups = "slow", description = "Test overdue stages and follow with an immediate change of plan and use of credit", enabled=false)
+    @Test(groups = "slow", description = "Test overdue stages and follow with an immediate change of plan and use of credit", enabled = false)
     public void testOverdueStagesFollowedWithImmediateChange2() throws Exception {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
 
@@ -529,10 +528,9 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkODState("OD1");
 
         // 2012, 7, 10 => Retry P0
-        addDaysAndCheckForCompletion(8, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.TAG     );
+        addDaysAndCheckForCompletion(8, NextEvent.BLOCK, NextEvent.PAYMENT_ERROR, NextEvent.TAG);
         checkODState("OD2");
 
-
         // 2012, 7, 18 => Retry P0
         addDaysAndCheckForCompletion(8, NextEvent.PAYMENT_ERROR);
         checkODState("OD2");
@@ -543,7 +541,6 @@ public class TestOverdueIntegration extends TestOverdueBase {
 
         allowPaymentsAndResetOverdueToClearByPayingAllUnpaidInvoices(false);
 
-
         invoiceChecker.checkInvoice(account.getId(), 2, callContext,
                                     // New invoice for the part that was unblocked up to the BCD
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 31), new LocalDate(2013, 5, 31), InvoiceItemType.RECURRING, new BigDecimal("2399.95")),
@@ -551,7 +548,6 @@ public class TestOverdueIntegration extends TestOverdueBase {
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 31), new LocalDate(2013, 5, 31), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-1998.9012")),
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 23), new LocalDate(2012, 7, 23), InvoiceItemType.CBA_ADJ, new BigDecimal("2084.36")));
 
-
         // Move to 2012, 7, 31 and Make a change of plan
         addDaysAndCheckForCompletion(8, NextEvent.INVOICE, NextEvent.PAYMENT);
 
@@ -640,7 +636,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkChangePlanWithOverdueState(baseEntitlement, true, true);
 
         // Add a payment method and set it as default
-        paymentApi.addPaymentMethod(BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, account, true, paymentMethodPlugin, callContext);
+        paymentApi.addPaymentMethod(BeatrixIntegrationModule.NON_OSGI_PLUGIN_NAME, account, true, paymentMethodPlugin, PLUGIN_PROPERTIES, callContext);
 
         allowPaymentsAndResetOverdueToClearByPayingAllUnpaidInvoices(false);
 
@@ -650,8 +646,6 @@ public class TestOverdueIntegration extends TestOverdueBase {
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 15), new LocalDate(2012, 7, 25), InvoiceItemType.REPAIR_ADJ, new BigDecimal("-80.63")),
                                     new ExpectedInvoiceItemCheck(new LocalDate(2012, 7, 25), new LocalDate(2012, 7, 25), InvoiceItemType.CBA_ADJ, new BigDecimal("80.63")));
 
-
-
         invoiceChecker.checkChargedThroughDate(baseEntitlement.getId(), new LocalDate(2012, 7, 31), callContext);
 
         checkChangePlanWithOverdueState(baseEntitlement, false, false);
@@ -686,7 +680,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         // Create an external charge on a new invoice
         addDaysAndCheckForCompletion(5);
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
-        final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(null, account.getId(), bundle.getId(),  "For overdue", new LocalDate(2012, 5, 6), BigDecimal.TEN, Currency.USD);
+        final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(null, account.getId(), bundle.getId(), "For overdue", new LocalDate(2012, 5, 6), BigDecimal.TEN, Currency.USD);
         invoiceUserApi.insertExternalCharges(account.getId(), clock.getUTCToday(), ImmutableList.<InvoiceItem>of(externalCharge), callContext).get(0);
         assertListenerStatus();
         invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2012, 5, 6), null, InvoiceItemType.EXTERNAL_CHARGE, BigDecimal.TEN));
@@ -752,7 +746,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkODState(DefaultBlockingState.CLEAR_STATE_NAME);
 
         // Now, refund the second (first non-zero dollar) invoice
-        final Payment payment = paymentApi.getPayment(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), false, callContext);
+        final Payment payment = paymentApi.getPayment(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), false, PLUGIN_PROPERTIES, callContext);
         refundPaymentAndCheckForCompletion(account, payment, NextEvent.BLOCK, NextEvent.INVOICE_ADJUSTMENT);
         // We should now be in OD1
         checkODState("OD1");
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index d76edaf..f4311da 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -101,6 +101,7 @@ import org.testng.annotations.BeforeMethod;
 
 import com.google.common.base.Function;
 import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.Stage;
@@ -117,6 +118,8 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
     protected static final Logger log = LoggerFactory.getLogger(TestIntegrationBase.class);
     protected static long AT_LEAST_ONE_MONTH_MS = 32L * 24L * 3600L * 1000L;
 
+    protected final Iterable<PluginProperty> PLUGIN_PROPERTIES = ImmutableList.<PluginProperty>of();
+
     @Inject
     protected Lifecycle lifecycle;
 
@@ -298,7 +301,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
 
         final PaymentMethodPlugin info = createPaymentMethodPlugin();
 
-        paymentApi.addPaymentMethod(paymentPluginName, account, true, info, callContext);
+        paymentApi.addPaymentMethod(paymentPluginName, account, true, info, PLUGIN_PROPERTIES, callContext);
         return accountUserApi.getAccountById(account.getId(), callContext);
     }
 
@@ -373,7 +376,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), callContext);
+                    paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), PLUGIN_PROPERTIES, callContext);
                 } catch (final PaymentApiException e) {
                     fail(e.toString());
                 }
@@ -401,7 +404,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createRefund(account, payment.getId(), payment.getPaidAmount(), callContext);
+                    paymentApi.createRefund(account, payment.getId(), payment.getPaidAmount(), PLUGIN_PROPERTIES, callContext);
                 } catch (final PaymentApiException e) {
                     fail(e.toString());
                 }
@@ -415,7 +418,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createRefundWithAdjustment(account, payment.getId(), payment.getPaidAmount(), callContext);
+                    paymentApi.createRefundWithAdjustment(account, payment.getId(), payment.getPaidAmount(), PLUGIN_PROPERTIES, callContext);
                 } catch (final PaymentApiException e) {
                     fail(e.toString());
                 }
@@ -429,7 +432,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB {
             @Override
             public Void apply(@Nullable final Void input) {
                 try {
-                    paymentApi.createRefundWithItemsAdjustments(account, payment.getId(), invoiceItems, callContext);
+                    paymentApi.createRefundWithItemsAdjustments(account, payment.getId(), invoiceItems, PLUGIN_PROPERTIES, callContext);
                 } catch (final PaymentApiException e) {
                     fail(e.toString());
                 }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java
index bc1f0f4..8b6fb85 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -24,10 +26,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.api.TestApiListener.NextEvent;
@@ -45,6 +43,9 @@ import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.payment.api.Payment;
 import org.killbill.billing.payment.api.PaymentStatus;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
@@ -500,7 +501,7 @@ public class TestIntegrationInvoiceWithRepairLogic extends TestIntegrationBase {
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
-        DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
+        final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
         assertNotNull(bpEntitlement);
         assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
 
@@ -542,13 +543,13 @@ public class TestIntegrationInvoiceWithRepairLogic extends TestIntegrationBase {
         final Map<UUID, BigDecimal> iias = new HashMap<UUID, BigDecimal>();
         iias.put(invoice1.getInvoiceItems().get(0).getId(), new BigDecimal("197.26"));
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
-        paymentApi.createRefundWithItemsAdjustments(account, payment1.getId(), iias, callContext);
+        paymentApi.createRefundWithItemsAdjustments(account, payment1.getId(), iias, PLUGIN_PROPERTIES, callContext);
         assertListenerStatus();
 
         try {
             invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(clock.getUTCToday()), false, callContext);
             Assert.fail("Should not gnenerated an new invoice");
-        } catch (InvoiceApiException e) {
+        } catch (final InvoiceApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_NOTHING_TO_DO.getCode());
         }
     }
@@ -576,7 +577,7 @@ public class TestIntegrationInvoiceWithRepairLogic extends TestIntegrationBase {
         //
         // CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE NextEvent.INVOICE
         //
-        DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
+        final DefaultEntitlement bpEntitlement = createBaseEntitlementAndCheckForCompletion(account.getId(), "externalKey", productName, ProductCategory.BASE, term, NextEvent.CREATE, NextEvent.INVOICE);
         assertNotNull(bpEntitlement);
         assertEquals(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).size(), 1);
 
@@ -618,15 +619,14 @@ public class TestIntegrationInvoiceWithRepairLogic extends TestIntegrationBase {
         final Map<UUID, BigDecimal> iias = new HashMap<UUID, BigDecimal>();
         iias.put(invoice1.getInvoiceItems().get(0).getId(), new BigDecimal("100.00"));
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
-        paymentApi.createRefundWithItemsAdjustments(account, payment1.getId(), iias, callContext);
+        paymentApi.createRefundWithItemsAdjustments(account, payment1.getId(), iias, PLUGIN_PROPERTIES, callContext);
         assertListenerStatus();
 
         try {
             invoiceUserApi.triggerInvoiceGeneration(account.getId(), new LocalDate(clock.getUTCToday()), false, callContext);
-            Assert.fail("Should not gnenerated an new invoice");
-        } catch (InvoiceApiException e) {
+            Assert.fail("Should not have generated an new invoice");
+        } catch (final InvoiceApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_NOTHING_TO_DO.getCode());
         }
     }
-
 }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPayment.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPayment.java
index 183dea4..0d0299a 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPayment.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestPayment.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright 2014 Groupon, Inc
  * Copyright 2014 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
@@ -17,9 +18,7 @@
 package org.killbill.billing.beatrix.integration;
 
 import java.math.BigDecimal;
-import java.util.UUID;
 
-import org.joda.time.DateTimeZone;
 import org.joda.time.LocalDate;
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
@@ -50,12 +49,12 @@ public class TestPayment extends TestIntegrationBase {
         clock.setDay(new LocalDate(2012, 4, 1));
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
-        final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(null, account.getId(), null,  "Initial external charge", clock.getUTCToday(), BigDecimal.TEN, Currency.USD);
+        final InvoiceItem externalCharge = new ExternalChargeInvoiceItem(null, account.getId(), null, "Initial external charge", clock.getUTCToday(), BigDecimal.TEN, Currency.USD);
         final InvoiceItem item1 = invoiceUserApi.insertExternalCharges(account.getId(), clock.getUTCToday(), ImmutableList.<InvoiceItem>of(externalCharge), callContext).get(0);
         assertListenerStatus();
 
         busHandler.pushExpectedEvents(NextEvent.PAYMENT);
-        final Payment payment1 = paymentApi.createPayment(account, item1.getInvoiceId(), new BigDecimal("4.00"), callContext);
+        final Payment payment1 = paymentApi.createPayment(account, item1.getInvoiceId(), new BigDecimal("4.00"), PLUGIN_PROPERTIES, callContext);
         assertListenerStatus();
 
         Invoice invoice1 = invoiceUserApi.getInvoice(item1.getInvoiceId(), callContext);
@@ -67,7 +66,7 @@ public class TestPayment extends TestIntegrationBase {
         assertTrue(accountBalance.compareTo(new BigDecimal("6.00")) == 0);
 
         busHandler.pushExpectedEvents(NextEvent.PAYMENT);
-        final Payment payment2 = paymentApi.createPayment(account, item1.getInvoiceId(), new BigDecimal("6.00"), callContext);
+        final Payment payment2 = paymentApi.createPayment(account, item1.getInvoiceId(), new BigDecimal("6.00"), PLUGIN_PROPERTIES, callContext);
         assertListenerStatus();
 
         invoice1 = invoiceUserApi.getInvoice(item1.getInvoiceId(), callContext);
@@ -92,7 +91,7 @@ public class TestPayment extends TestIntegrationBase {
 
 */
         // And then issue refund with item adjustment on first invoice/item
-        paymentApi.createRefund(account, payment2.getId(), new BigDecimal("5.00"), callContext);
+        paymentApi.createRefund(account, payment2.getId(), new BigDecimal("5.00"), PLUGIN_PROPERTIES, callContext);
 
         invoice1 = invoiceUserApi.getInvoice(item1.getInvoiceId(), callContext);
         assertTrue(invoice1.getBalance().compareTo(new BigDecimal("5.00")) == 0);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 46ddf20..6529388 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -25,7 +27,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
@@ -499,7 +500,7 @@ public class AccountResource extends JaxRsResourceBase {
                 if (externalPayment) {
                     paymentApi.createExternalPayment(account, invoice.getId(), amountToPay, callContext);
                 } else {
-                    paymentApi.createPayment(account, invoice.getId(), amountToPay, callContext);
+                    paymentApi.createPayment(account, invoice.getId(), amountToPay, pluginProperties, callContext);
                 }
             }
             remainingRequestPayment = remainingRequestPayment.subtract(amountToPay);
@@ -542,10 +543,10 @@ public class AccountResource extends JaxRsResourceBase {
             return Response.status(Status.BAD_REQUEST).build();
         }
 
-        final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), callContext);
+        final UUID paymentMethodId = paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), pluginProperties, callContext);
         if (payAllUnpaidInvoices && unpaidInvoices.size() > 0) {
             for (final Invoice invoice : unpaidInvoices) {
-                paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), callContext);
+                paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), pluginProperties, callContext);
             }
         }
         return uriBuilder.buildResponse(PaymentMethodResource.class, "getPaymentMethod", paymentMethodId, uriInfo.getBaseUri().toString());
@@ -561,7 +562,7 @@ public class AccountResource extends JaxRsResourceBase {
         final TenantContext tenantContext = context.createContext(request);
 
         final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), tenantContext);
-        final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo, tenantContext);
+        final List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo, pluginProperties, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(account.getId(), auditMode.getLevel(), tenantContext);
         final List<PaymentMethodJson> json = new ArrayList<PaymentMethodJson>(Collections2.transform(methods, new Function<PaymentMethod, PaymentMethodJson>() {
             @Override
@@ -587,12 +588,12 @@ public class AccountResource extends JaxRsResourceBase {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final Account account = accountUserApi.getAccountById(UUID.fromString(accountId), callContext);
-        paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), callContext);
+        paymentApi.setDefaultPaymentMethod(account, UUID.fromString(paymentMethodId), pluginProperties, callContext);
 
         if (payAllUnpaidInvoices) {
             final Collection<Invoice> unpaidInvoices = invoiceApi.getUnpaidInvoicesByAccountId(account.getId(), clock.getUTCToday(), callContext);
             for (final Invoice invoice : unpaidInvoices) {
-                paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), callContext);
+                paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), pluginProperties, callContext);
             }
         }
         return Response.status(Status.OK).build();
@@ -609,7 +610,7 @@ public class AccountResource extends JaxRsResourceBase {
                                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
 
         final UUID accountId = UUID.fromString(accountIdStr);
-        final List<DirectPayment> payments =  directPaymentApi.getAccountPayments(accountId, withPluginInfo, context.createContext(request));
+        final List<DirectPayment> payments = directPaymentApi.getAccountPayments(accountId, withPluginInfo, pluginProperties, context.createContext(request));
         final List<DirectPaymentJson> result = ImmutableList.copyOf(Iterables.transform(payments, new Function<DirectPayment, DirectPaymentJson>() {
             @Override
             public DirectPaymentJson apply(final DirectPayment input) {
@@ -640,10 +641,10 @@ public class AccountResource extends JaxRsResourceBase {
         DirectPayment result;
         switch (transactionType) {
             case AUTHORIZE:
-                result = directPaymentApi.createAuthorization(account, json.getAmount(), json.getExternalKey(), callContext);
+                result = directPaymentApi.createAuthorization(account, json.getAmount(), json.getExternalKey(), pluginProperties, callContext);
                 break;
             case PURCHASE:
-                result = directPaymentApi.createPurchase(account, json.getAmount(), json.getExternalKey(), callContext);
+                result = directPaymentApi.createPurchase(account, json.getAmount(), json.getExternalKey(), pluginProperties, callContext);
                 break;
             default:
                 return Response.status(Status.PRECONDITION_FAILED).entity("TransactionType " + transactionType + " is not allowed for an account").build();
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/DirectPaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/DirectPaymentResource.java
index d463886..137aece 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/DirectPaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/DirectPaymentResource.java
@@ -1,7 +1,8 @@
 /*
  * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Groupon licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -47,7 +48,6 @@ import org.killbill.billing.util.api.AuditUserApi;
 import org.killbill.billing.util.api.CustomFieldUserApi;
 import org.killbill.billing.util.api.TagUserApi;
 import org.killbill.billing.util.callcontext.CallContext;
-import org.killbill.billing.util.callcontext.TenantContext;
 import org.killbill.clock.Clock;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@@ -78,7 +78,7 @@ public class DirectPaymentResource extends JaxRsResourceBase {
                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
 
         final UUID directPaymentIdId = UUID.fromString(directPaymentIdStr);
-        final DirectPayment payment =  directPaymentApi.getPayment(directPaymentIdId, withPluginInfo, context.createContext(request));
+        final DirectPayment payment = directPaymentApi.getPayment(directPaymentIdId, withPluginInfo, pluginProperties, context.createContext(request));
         final DirectPaymentJson result = new DirectPaymentJson(payment, null, null);
         return Response.status(Response.Status.OK).entity(result).build();
     }
@@ -95,19 +95,17 @@ public class DirectPaymentResource extends JaxRsResourceBase {
                                          @javax.ws.rs.core.Context final UriInfo uriInfo,
                                          @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
 
-
         // STEPH_DP error code if no such payment
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final UUID directPaymentId = UUID.fromString(directPaymentIdStr);
-        final DirectPayment initialPayment = directPaymentApi.getPayment(directPaymentId, false, callContext);
+        final DirectPayment initialPayment = directPaymentApi.getPayment(directPaymentId, false, pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
 
-        final DirectPayment payment = directPaymentApi.createCapture(account, directPaymentId, json.getAmount(), callContext);
+        final DirectPayment payment = directPaymentApi.createCapture(account, directPaymentId, json.getAmount(), pluginProperties, callContext);
         return uriBuilder.buildResponse(uriInfo, DirectPaymentResource.class, "getDirectPayment", payment.getId());
     }
 
-
     @DELETE
     @Path("/{directPaymentId:" + UUID_PATTERN + "}/")
     @Consumes(APPLICATION_JSON)
@@ -120,12 +118,11 @@ public class DirectPaymentResource extends JaxRsResourceBase {
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final UUID directPaymentId = UUID.fromString(directPaymentIdStr);
-        final DirectPayment initialPayment = directPaymentApi.getPayment(directPaymentId, false, callContext);
+        final DirectPayment initialPayment = directPaymentApi.getPayment(directPaymentId, false, pluginProperties, callContext);
 
         final Account account = accountUserApi.getAccountById(initialPayment.getAccountId(), callContext);
 
-        final DirectPayment payment = directPaymentApi.createVoid(account, directPaymentId,callContext);
+        final DirectPayment payment = directPaymentApi.createVoid(account, directPaymentId, pluginProperties, callContext);
         return uriBuilder.buildResponse(uriInfo, DirectPaymentResource.class, "getDirectPayment", payment.getId());
     }
-
 }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 6d04d63..7f70135 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -352,7 +354,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                     paidInvoices.add(externalCharge.getInvoiceId());
 
                     final Invoice invoice = invoiceApi.getInvoice(externalCharge.getInvoiceId(), callContext);
-                    paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), callContext);
+                    paymentApi.createPayment(account, invoice.getId(), invoice.getBalance(), pluginProperties, callContext);
                 }
             }
         }
@@ -412,7 +414,7 @@ public class InvoiceResource extends JaxRsResourceBase {
         if (externalPayment) {
             paymentApi.createExternalPayment(account, invoiceId, payment.getAmount(), callContext);
         } else {
-            paymentApi.createPayment(account, invoiceId, payment.getAmount(), callContext);
+            paymentApi.createPayment(account, invoiceId, payment.getAmount(), pluginProperties, callContext);
         }
 
         return uriBuilder.buildResponse(uriInfo, InvoiceResource.class, "getPayments", payment.getInvoiceId());
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
index 44d66cb..9c2ab7e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -39,19 +39,16 @@ import org.joda.time.LocalDate;
 import org.joda.time.format.DateTimeFormat;
 import org.joda.time.format.DateTimeFormatter;
 import org.joda.time.format.ISODateTimeFormat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountUserApi;
-import org.killbill.clock.Clock;
 import org.killbill.billing.jaxrs.json.CustomFieldJson;
 import org.killbill.billing.jaxrs.json.JsonBase;
 import org.killbill.billing.jaxrs.json.TagJson;
 import org.killbill.billing.jaxrs.util.Context;
 import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.util.api.AuditUserApi;
 import org.killbill.billing.util.api.CustomFieldApiException;
 import org.killbill.billing.util.api.CustomFieldUserApi;
@@ -69,6 +66,9 @@ import org.killbill.billing.util.entity.Pagination;
 import org.killbill.billing.util.jackson.ObjectMapper;
 import org.killbill.billing.util.tag.Tag;
 import org.killbill.billing.util.tag.TagDefinition;
+import org.killbill.clock.Clock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.core.JsonGenerator;
 import com.google.common.base.Function;
@@ -81,6 +81,9 @@ public abstract class JaxRsResourceBase implements JaxrsResource {
 
     static final Logger log = LoggerFactory.getLogger(JaxRsResourceBase.class);
 
+    // TODO PIERRE
+    protected final Iterable<PluginProperty> pluginProperties = ImmutableList.<PluginProperty>of();
+
     protected static final ObjectMapper mapper = new ObjectMapper();
 
     protected final JaxrsUriBuilder uriBuilder;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
index e181224..f590203 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -38,7 +40,6 @@ import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
 import org.killbill.billing.account.api.AccountUserApi;
-import org.killbill.clock.Clock;
 import org.killbill.billing.jaxrs.json.PaymentMethodJson;
 import org.killbill.billing.jaxrs.util.Context;
 import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
@@ -52,6 +53,7 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.TenantContext;
 import org.killbill.billing.util.entity.Pagination;
+import org.killbill.clock.Clock;
 
 import com.google.common.base.Function;
 import com.google.common.base.Strings;
@@ -89,7 +91,7 @@ public class PaymentMethodResource extends JaxRsResourceBase {
                                      @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
         final TenantContext tenantContext = context.createContext(request);
 
-        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), false, withPluginInfo, tenantContext);
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), false, withPluginInfo, pluginProperties, tenantContext);
         final Account account = accountUserApi.getAccountById(paymentMethod.getAccountId(), tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(paymentMethod.getAccountId(), auditMode.getLevel(), tenantContext);
         final PaymentMethodJson json = PaymentMethodJson.toPaymentMethodJson(account, paymentMethod, accountAuditLogs);
@@ -109,9 +111,9 @@ public class PaymentMethodResource extends JaxRsResourceBase {
 
         final Pagination<PaymentMethod> paymentMethods;
         if (Strings.isNullOrEmpty(pluginName)) {
-            paymentMethods = paymentApi.getPaymentMethods(offset, limit, tenantContext);
+            paymentMethods = paymentApi.getPaymentMethods(offset, limit, pluginProperties, tenantContext);
         } else {
-            paymentMethods = paymentApi.getPaymentMethods(offset, limit, pluginName, tenantContext);
+            paymentMethods = paymentApi.getPaymentMethods(offset, limit, pluginName, pluginProperties, tenantContext);
         }
 
         final URI nextPageUri = uriBuilder.nextPage(PaymentMethodResource.class, "getPaymentMethods", paymentMethods.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
@@ -143,7 +145,8 @@ public class PaymentMethodResource extends JaxRsResourceBase {
                                                         return PaymentMethodJson.toPaymentMethodJson(accounts.get(paymentMethod.getAccountId()), paymentMethod, accountsAuditLogs.get().get(paymentMethod.getAccountId()));
                                                     }
                                                 },
-                                                nextPageUri);
+                                                nextPageUri
+                                               );
     }
 
     @GET
@@ -160,9 +163,9 @@ public class PaymentMethodResource extends JaxRsResourceBase {
         // Search the plugin(s)
         final Pagination<PaymentMethod> paymentMethods;
         if (Strings.isNullOrEmpty(pluginName)) {
-            paymentMethods = paymentApi.searchPaymentMethods(searchKey, offset, limit, tenantContext);
+            paymentMethods = paymentApi.searchPaymentMethods(searchKey, offset, limit, pluginProperties, tenantContext);
         } else {
-            paymentMethods = paymentApi.searchPaymentMethods(searchKey, offset, limit, pluginName, tenantContext);
+            paymentMethods = paymentApi.searchPaymentMethods(searchKey, offset, limit, pluginName, pluginProperties, tenantContext);
         }
 
         final URI nextPageUri = uriBuilder.nextPage(PaymentMethodResource.class, "searchPaymentMethods", paymentMethods.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
@@ -195,7 +198,8 @@ public class PaymentMethodResource extends JaxRsResourceBase {
                                                         return PaymentMethodJson.toPaymentMethodJson(accounts.get(paymentMethod.getAccountId()), paymentMethod, accountsAuditLogs.get().get(paymentMethod.getAccountId()));
                                                     }
                                                 },
-                                                nextPageUri);
+                                                nextPageUri
+                                               );
     }
 
     @DELETE
@@ -209,10 +213,10 @@ public class PaymentMethodResource extends JaxRsResourceBase {
                                         @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, AccountApiException {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
-        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), false, false, callContext);
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodById(UUID.fromString(paymentMethodId), false, false, pluginProperties, callContext);
         final Account account = accountUserApi.getAccountById(paymentMethod.getAccountId(), callContext);
 
-        paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), deleteDefaultPaymentMethodWithAutoPayOff, callContext);
+        paymentApi.deletedPaymentMethod(account, UUID.fromString(paymentMethodId), deleteDefaultPaymentMethodWithAutoPayOff, pluginProperties, callContext);
 
         return Response.status(Status.OK).build();
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index 9925e0f..507bc61 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -115,7 +117,7 @@ public class PaymentResource extends JaxRsResourceBase {
         final TenantContext tenantContext = context.createContext(request);
 
         final UUID paymentId = UUID.fromString(paymentIdString);
-        final Payment payment = paymentApi.getPayment(paymentId, false, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, pluginProperties, tenantContext);
 
         final PaymentJson paymentJson;
         if (withRefundsAndChargebacks) {
@@ -152,9 +154,9 @@ public class PaymentResource extends JaxRsResourceBase {
 
         final Pagination<Payment> payments;
         if (Strings.isNullOrEmpty(pluginName)) {
-            payments = paymentApi.getPayments(offset, limit, tenantContext);
+            payments = paymentApi.getPayments(offset, limit, pluginProperties, tenantContext);
         } else {
-            payments = paymentApi.getPayments(offset, limit, pluginName, tenantContext);
+            payments = paymentApi.getPayments(offset, limit, pluginName, pluginProperties, tenantContext);
         }
 
         final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class, "getPayments", payments.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
@@ -190,9 +192,9 @@ public class PaymentResource extends JaxRsResourceBase {
         // Search the plugin(s)
         final Pagination<Payment> payments;
         if (Strings.isNullOrEmpty(pluginName)) {
-            payments = paymentApi.searchPayments(searchKey, offset, limit, tenantContext);
+            payments = paymentApi.searchPayments(searchKey, offset, limit, pluginProperties, tenantContext);
         } else {
-            payments = paymentApi.searchPayments(searchKey, offset, limit, pluginName, tenantContext);
+            payments = paymentApi.searchPayments(searchKey, offset, limit, pluginName, pluginProperties, tenantContext);
         }
 
         final URI nextPageUri = uriBuilder.nextPage(PaymentResource.class, "searchPayments", payments.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
@@ -228,9 +230,9 @@ public class PaymentResource extends JaxRsResourceBase {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final UUID paymentId = UUID.fromString(paymentIdString);
-        final Payment payment = paymentApi.getPayment(paymentId, false, callContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, pluginProperties, callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
-        final Payment newPayment = paymentApi.retryPayment(account, paymentId, callContext);
+        final Payment newPayment = paymentApi.retryPayment(account, paymentId, pluginProperties, callContext);
 
         return Response.status(Status.OK).entity(new PaymentJson(newPayment, null)).build();
     }
@@ -287,7 +289,7 @@ public class PaymentResource extends JaxRsResourceBase {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid, false, callContext);
+        final Payment payment = paymentApi.getPayment(paymentUuid, false, pluginProperties, callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
 
         final Refund result;
@@ -297,14 +299,14 @@ public class PaymentResource extends JaxRsResourceBase {
                 for (final InvoiceItemJson item : json.getAdjustments()) {
                     adjustments.put(UUID.fromString(item.getInvoiceItemId()), item.getAmount());
                 }
-                result = paymentApi.createRefundWithItemsAdjustments(account, paymentUuid, adjustments, callContext);
+                result = paymentApi.createRefundWithItemsAdjustments(account, paymentUuid, adjustments, pluginProperties, callContext);
             } else {
                 // Invoice adjustment
-                result = paymentApi.createRefundWithAdjustment(account, paymentUuid, json.getAmount(), callContext);
+                result = paymentApi.createRefundWithAdjustment(account, paymentUuid, json.getAmount(), pluginProperties, callContext);
             }
         } else {
             // Refund without adjustment
-            result = paymentApi.createRefund(account, paymentUuid, json.getAmount(), callContext);
+            result = paymentApi.createRefund(account, paymentUuid, json.getAmount(), pluginProperties, callContext);
         }
 
         return uriBuilder.buildResponse(RefundResource.class, "getRefund", result.getId(), uriInfo.getBaseUri().toString());
@@ -387,7 +389,7 @@ public class PaymentResource extends JaxRsResourceBase {
                             @javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException, PaymentApiException {
         final UUID paymentId = UUID.fromString(paymentIdString);
         final TenantContext tenantContext = context.createContext(request);
-        final Payment payment = paymentApi.getPayment(paymentId, false, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, pluginProperties, tenantContext);
         return super.getTags(payment.getAccountId(), paymentId, auditMode, includedDeleted, tenantContext);
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/RefundResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/RefundResource.java
index 9c807e0..e04ff7b 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/RefundResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/RefundResource.java
@@ -35,7 +35,6 @@ import javax.ws.rs.core.Response.Status;
 
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.AccountUserApi;
-import org.killbill.clock.Clock;
 import org.killbill.billing.jaxrs.json.RefundJson;
 import org.killbill.billing.jaxrs.util.Context;
 import org.killbill.billing.jaxrs.util.JaxrsUriBuilder;
@@ -50,6 +49,7 @@ import org.killbill.billing.util.audit.AccountAuditLogs;
 import org.killbill.billing.util.audit.AuditLog;
 import org.killbill.billing.util.callcontext.TenantContext;
 import org.killbill.billing.util.entity.Pagination;
+import org.killbill.clock.Clock;
 
 import com.google.common.base.Function;
 import com.google.common.base.Strings;
@@ -83,7 +83,7 @@ public class RefundResource extends JaxRsResourceBase {
                               @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                               @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException {
         final TenantContext tenantContext = context.createContext(request);
-        final Refund refund = paymentApi.getRefund(UUID.fromString(refundId), false, tenantContext);
+        final Refund refund = paymentApi.getRefund(UUID.fromString(refundId), false, pluginProperties, tenantContext);
         final List<AuditLog> auditLogs = auditUserApi.getAuditLogs(refund.getId(), ObjectType.REFUND, auditMode.getLevel(), tenantContext);
         // TODO Return adjusted items
         return Response.status(Status.OK).entity(new RefundJson(refund, null, auditLogs)).build();
@@ -101,9 +101,9 @@ public class RefundResource extends JaxRsResourceBase {
 
         final Pagination<Refund> refunds;
         if (Strings.isNullOrEmpty(pluginName)) {
-            refunds = paymentApi.getRefunds(offset, limit, tenantContext);
+            refunds = paymentApi.getRefunds(offset, limit, pluginProperties, tenantContext);
         } else {
-            refunds = paymentApi.getRefunds(offset, limit, pluginName, tenantContext);
+            refunds = paymentApi.getRefunds(offset, limit, pluginName, pluginProperties, tenantContext);
         }
 
         final URI nextPageUri = uriBuilder.nextPage(RefundResource.class, "getRefunds", refunds.getNextOffset(), limit, ImmutableMap.<String, String>of(QUERY_PAYMENT_METHOD_PLUGIN_NAME, Strings.nullToEmpty(pluginName),
@@ -118,7 +118,7 @@ public class RefundResource extends JaxRsResourceBase {
                                                         UUID kbAccountId = null;
                                                         if (!AuditLevel.NONE.equals(auditMode.getLevel()) && paymentIdAccountIdMappings.get(refund.getPaymentId()) == null) {
                                                             try {
-                                                                kbAccountId = paymentApi.getPayment(refund.getPaymentId(), false, tenantContext).getAccountId();
+                                                                kbAccountId = paymentApi.getPayment(refund.getPaymentId(), false, pluginProperties, tenantContext).getAccountId();
                                                                 paymentIdAccountIdMappings.put(refund.getPaymentId(), kbAccountId);
                                                             } catch (final PaymentApiException e) {
                                                                 log.warn("Unable to retrieve payment for id " + refund.getPaymentId());
@@ -134,7 +134,8 @@ public class RefundResource extends JaxRsResourceBase {
                                                         return new RefundJson(refund, null, auditLogs);
                                                     }
                                                 },
-                                                nextPageUri);
+                                                nextPageUri
+                                               );
     }
 
     @GET
@@ -151,9 +152,9 @@ public class RefundResource extends JaxRsResourceBase {
         // Search the plugin(s)
         final Pagination<Refund> refunds;
         if (Strings.isNullOrEmpty(pluginName)) {
-            refunds = paymentApi.searchRefunds(searchKey, offset, limit, tenantContext);
+            refunds = paymentApi.searchRefunds(searchKey, offset, limit, pluginProperties, tenantContext);
         } else {
-            refunds = paymentApi.searchRefunds(searchKey, offset, limit, pluginName, tenantContext);
+            refunds = paymentApi.searchRefunds(searchKey, offset, limit, pluginName, pluginProperties, tenantContext);
         }
 
         final URI nextPageUri = uriBuilder.nextPage(RefundResource.class, "searchRefunds", refunds.getNextOffset(), limit, ImmutableMap.<String, String>of("searchKey", searchKey,
@@ -169,7 +170,7 @@ public class RefundResource extends JaxRsResourceBase {
                                                         UUID kbAccountId = null;
                                                         if (!AuditLevel.NONE.equals(auditMode.getLevel()) && paymentIdAccountIdMappings.get(refund.getPaymentId()) == null) {
                                                             try {
-                                                                kbAccountId = paymentApi.getPayment(refund.getPaymentId(), false, tenantContext).getAccountId();
+                                                                kbAccountId = paymentApi.getPayment(refund.getPaymentId(), false, pluginProperties, tenantContext).getAccountId();
                                                                 paymentIdAccountIdMappings.put(refund.getPaymentId(), kbAccountId);
                                                             } catch (final PaymentApiException e) {
                                                                 log.warn("Unable to retrieve payment for id " + refund.getPaymentId());
@@ -185,7 +186,8 @@ public class RefundResource extends JaxRsResourceBase {
                                                         return new RefundJson(refund, null, auditLogs);
                                                     }
                                                 },
-                                                nextPageUri);
+                                                nextPageUri
+                                               );
     }
 
     @Override
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index ef74dbf..f589788 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -27,7 +27,6 @@ import java.util.UUID;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.callcontext.InternalCallContext;
-import org.killbill.clock.Clock;
 import org.killbill.billing.payment.core.PaymentMethodProcessor;
 import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.payment.core.RefundProcessor;
@@ -35,7 +34,9 @@ import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.callcontext.TenantContext;
 import org.killbill.billing.util.entity.Pagination;
+import org.killbill.clock.Clock;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.inject.Inject;
 
@@ -62,15 +63,17 @@ public class DefaultPaymentApi implements PaymentApi {
 
     @Override
     public Payment createPayment(final Account account, final UUID invoiceId,
-                                 final BigDecimal amount, final CallContext context) throws PaymentApiException {
+                                 final BigDecimal amount, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentApiException {
         return paymentProcessor.createPayment(account, invoiceId, amount,
-                                              internalCallContextFactory.createInternalCallContext(account.getId(), context), true, false);
+                                              internalCallContextFactory.createInternalCallContext(account.getId(), context),
+                                              true, false, properties);
     }
 
     @Override
     public Payment createExternalPayment(final Account account, final UUID invoiceId, final BigDecimal amount, final CallContext context) throws PaymentApiException {
         return paymentProcessor.createPayment(account, invoiceId, amount,
-                                              internalCallContextFactory.createInternalCallContext(account.getId(), context), true, true);
+                                              internalCallContextFactory.createInternalCallContext(account.getId(), context),
+                                              true, true, ImmutableList.<PluginProperty>of());
     }
 
     @Override
@@ -80,25 +83,25 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Payment retryPayment(final Account account, final UUID paymentId, final CallContext context) throws PaymentApiException {
+    public Payment retryPayment(final Account account, final UUID paymentId, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentApiException {
         final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(account.getId(), context);
-        paymentProcessor.retryPaymentFromApi(paymentId, internalCallContext);
-        return getPayment(paymentId, false, context);
+        paymentProcessor.retryPaymentFromApi(paymentId, properties, internalCallContext);
+        return getPayment(paymentId, false, properties, context);
     }
 
     @Override
-    public Pagination<Payment> getPayments(final Long offset, final Long limit, final TenantContext context) {
-        return paymentProcessor.getPayments(offset, limit, context, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<Payment> getPayments(final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+        return paymentProcessor.getPayments(offset, limit, properties, context, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<Payment> getPayments(final Long offset, final Long limit, final String pluginName, final TenantContext tenantContext) throws PaymentApiException {
-        return paymentProcessor.getPayments(offset, limit, pluginName, tenantContext, internalCallContextFactory.createInternalTenantContext(tenantContext));
+    public Pagination<Payment> getPayments(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
+        return paymentProcessor.getPayments(offset, limit, pluginName, properties, tenantContext, internalCallContextFactory.createInternalTenantContext(tenantContext));
     }
 
     @Override
-    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final TenantContext context) throws PaymentApiException {
-        final Payment payment = paymentProcessor.getPayment(paymentId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(context));
+    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        final Payment payment = paymentProcessor.getPayment(paymentId, withPluginInfo, properties, internalCallContextFactory.createInternalTenantContext(context));
         if (payment == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
         }
@@ -106,33 +109,33 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final TenantContext context) {
-        return paymentProcessor.searchPayments(searchKey, offset, limit, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+        return paymentProcessor.searchPayments(searchKey, offset, limit, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final String pluginName, final TenantContext context) throws PaymentApiException {
-        return paymentProcessor.searchPayments(searchKey, offset, limit, pluginName, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        return paymentProcessor.searchPayments(searchKey, offset, limit, pluginName, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final TenantContext context) {
-        return refundProcessor.getRefunds(offset, limit, context, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+        return refundProcessor.getRefunds(offset, limit, properties, context, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final String pluginName, final TenantContext tenantContext) throws PaymentApiException {
-        return refundProcessor.getRefunds(offset, limit, pluginName, tenantContext, internalCallContextFactory.createInternalTenantContext(tenantContext));
+    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
+        return refundProcessor.getRefunds(offset, limit, pluginName, properties, tenantContext, internalCallContextFactory.createInternalTenantContext(tenantContext));
     }
 
     @Override
-    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final TenantContext context) {
-        return refundProcessor.searchRefunds(searchKey, offset, limit, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+        return refundProcessor.searchRefunds(searchKey, offset, limit, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final String pluginName, final TenantContext context) throws PaymentApiException {
-        return refundProcessor.searchRefunds(searchKey, offset, limit, pluginName, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        return refundProcessor.searchRefunds(searchKey, offset, limit, pluginName, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
@@ -147,16 +150,16 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Refund getRefund(final UUID refundId, final boolean withPluginInfo, final TenantContext context) throws PaymentApiException {
-        return refundProcessor.getRefund(refundId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(context));
+    public Refund getRefund(final UUID refundId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        return refundProcessor.getRefund(refundId, withPluginInfo, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Refund createRefund(final Account account, final UUID paymentId, final BigDecimal refundAmount, final CallContext context) throws PaymentApiException {
+    public Refund createRefund(final Account account, final UUID paymentId, final BigDecimal refundAmount, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentApiException {
         if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
             throw new PaymentApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
         }
-        return refundProcessor.createRefund(account, paymentId, refundAmount, false, ImmutableMap.<UUID, BigDecimal>of(),
+        return refundProcessor.createRefund(account, paymentId, refundAmount, false, ImmutableMap.<UUID, BigDecimal>of(), properties,
                                             internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
@@ -167,28 +170,28 @@ public class DefaultPaymentApi implements PaymentApi {
     }
 
     @Override
-    public Refund createRefundWithAdjustment(final Account account, final UUID paymentId, final BigDecimal refundAmount, final CallContext context) throws PaymentApiException {
+    public Refund createRefundWithAdjustment(final Account account, final UUID paymentId, final BigDecimal refundAmount, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentApiException {
         if (refundAmount == null || refundAmount.compareTo(BigDecimal.ZERO) <= 0) {
             throw new PaymentApiException(ErrorCode.PAYMENT_REFUND_AMOUNT_NEGATIVE_OR_NULL);
         }
-        return refundProcessor.createRefund(account, paymentId, refundAmount, true, ImmutableMap.<UUID, BigDecimal>of(),
+        return refundProcessor.createRefund(account, paymentId, refundAmount, true, ImmutableMap.<UUID, BigDecimal>of(), properties,
                                             internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Set<UUID> invoiceItemIds, final CallContext context) throws PaymentApiException {
+    public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Set<UUID> invoiceItemIds, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentApiException {
         final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts = new HashMap<UUID, BigDecimal>();
         for (final UUID invoiceItemId : invoiceItemIds) {
             invoiceItemIdsWithAmounts.put(invoiceItemId, null);
         }
 
-        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts,
+        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts, properties,
                                             internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final CallContext context) throws PaymentApiException {
-        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts,
+    public Refund createRefundWithItemsAdjustments(final Account account, final UUID paymentId, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final Iterable<PluginProperty> properties, final CallContext context) throws PaymentApiException {
+        return refundProcessor.createRefund(account, paymentId, null, true, invoiceItemIdsWithAmounts, properties,
                                             internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
@@ -211,70 +214,71 @@ public class DefaultPaymentApi implements PaymentApi {
 
     @Override
     public UUID addPaymentMethod(final String pluginName, final Account account,
-                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodInfo, final CallContext context)
+                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodInfo,
+                                 final Iterable<PluginProperty> properties, final CallContext context)
             throws PaymentApiException {
-        return methodProcessor.addPaymentMethod(pluginName, account, setDefault, paymentMethodInfo,
+        return methodProcessor.addPaymentMethod(pluginName, account, setDefault, paymentMethodInfo, properties,
                                                 internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginInfo, final TenantContext context)
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context)
             throws PaymentApiException {
-        return methodProcessor.getPaymentMethods(account, withPluginInfo, internalCallContextFactory.createInternalTenantContext(context));
+        return methodProcessor.getPaymentMethods(account, withPluginInfo, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final boolean includedDeleted, final boolean withPluginInfo, final TenantContext context)
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final boolean includedDeleted, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context)
             throws PaymentApiException {
-        return methodProcessor.getPaymentMethodById(paymentMethodId, includedDeleted, withPluginInfo, internalCallContextFactory.createInternalTenantContext(context));
+        return methodProcessor.getPaymentMethodById(paymentMethodId, includedDeleted, withPluginInfo, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final TenantContext context) {
-        return methodProcessor.getPaymentMethods(offset, limit, context, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+        return methodProcessor.getPaymentMethods(offset, limit, properties, context, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final String pluginName, final TenantContext context) throws PaymentApiException {
-        return methodProcessor.getPaymentMethods(offset, limit, pluginName, context, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        return methodProcessor.getPaymentMethods(offset, limit, pluginName, properties, context, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final TenantContext context) {
-        return methodProcessor.searchPaymentMethods(searchKey, offset, limit, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext context) {
+        return methodProcessor.searchPaymentMethods(searchKey, offset, limit, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final String pluginName, final TenantContext context) throws PaymentApiException {
-        return methodProcessor.searchPaymentMethods(searchKey, offset, limit, pluginName, internalCallContextFactory.createInternalTenantContext(context));
+    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        return methodProcessor.searchPaymentMethods(searchKey, offset, limit, pluginName, properties, internalCallContextFactory.createInternalTenantContext(context));
     }
 
     @Override
-    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final boolean deleteDefaultPaymentMethodWithAutoPayOff, final CallContext context)
+    public void deletedPaymentMethod(final Account account, final UUID paymentMethodId, final boolean deleteDefaultPaymentMethodWithAutoPayOff, final Iterable<PluginProperty> properties, final CallContext context)
             throws PaymentApiException {
-        methodProcessor.deletedPaymentMethod(account, paymentMethodId, deleteDefaultPaymentMethodWithAutoPayOff, internalCallContextFactory.createInternalCallContext(account.getId(), context));
+        methodProcessor.deletedPaymentMethod(account, paymentMethodId, deleteDefaultPaymentMethodWithAutoPayOff, properties, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final CallContext context)
+    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final Iterable<PluginProperty> properties, final CallContext context)
             throws PaymentApiException {
-        methodProcessor.setDefaultPaymentMethod(account, paymentMethodId, internalCallContextFactory.createInternalCallContext(account.getId(), context));
+        methodProcessor.setDefaultPaymentMethod(account, paymentMethodId, properties, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final CallContext context)
+    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final Iterable<PluginProperty> properties, final CallContext context)
             throws PaymentApiException {
-        return methodProcessor.refreshPaymentMethods(pluginName, account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
+        return methodProcessor.refreshPaymentMethods(pluginName, account, properties, internalCallContextFactory.createInternalCallContext(account.getId(), context));
     }
 
     @Override
-    public List<PaymentMethod> refreshPaymentMethods(final Account account, final CallContext context)
+    public List<PaymentMethod> refreshPaymentMethods(final Account account, final Iterable<PluginProperty> properties, final CallContext context)
             throws PaymentApiException {
         final InternalCallContext callContext = internalCallContextFactory.createInternalCallContext(account.getId(), context);
 
         final List<PaymentMethod> paymentMethods = new LinkedList<PaymentMethod>();
         for (final String pluginName : methodProcessor.getAvailablePlugins()) {
-            paymentMethods.addAll(methodProcessor.refreshPaymentMethods(pluginName, account, callContext));
+            paymentMethods.addAll(methodProcessor.refreshPaymentMethods(pluginName, account, properties, callContext));
         }
 
         return paymentMethods;
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
index 9916fe4..8783076 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultDirectPaymentApi.java
@@ -22,18 +22,15 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
-import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.payment.api.DirectPayment;
 import org.killbill.billing.payment.api.DirectPaymentApi;
 import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.core.DirectPaymentProcessor;
-import org.killbill.billing.util.cache.CacheController;
-import org.killbill.billing.util.cache.CacheControllerDispatcher;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.callcontext.TenantContext;
-import org.killbill.billing.util.dao.NonEntityDao;
 import org.killbill.clock.Clock;
 
 public class DefaultDirectPaymentApi implements DirectPaymentApi {
@@ -50,37 +47,37 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
     }
 
     @Override
-    public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final CallContext callContext) throws PaymentApiException {
-        return directPaymentProcessor.createAuthorization(account, amount, externalKey, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
+    public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+        return directPaymentProcessor.createAuthorization(account, amount, externalKey, properties, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
     }
 
     @Override
-    public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final CallContext callContext) throws PaymentApiException {
-        return directPaymentProcessor.createCapture(account, directPaymentId, amount, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
+    public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+        return directPaymentProcessor.createCapture(account, directPaymentId, amount, properties, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
     }
 
     @Override
-    public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final CallContext callContext) throws PaymentApiException {
-        return directPaymentProcessor.createPurchase(account, amount, externalKey, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
+    public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
+        return directPaymentProcessor.createPurchase(account, amount, externalKey, properties, internalCallContextFactory.createInternalCallContext(account.getId(), callContext));
     }
 
     @Override
-    public DirectPayment createVoid(final Account account, final UUID directPaymentId, final CallContext callContext) throws PaymentApiException {
+    public DirectPayment createVoid(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
         return null;
     }
 
     @Override
-    public DirectPayment createCredit(final Account account, final UUID directPaymentId, final CallContext callContext) throws PaymentApiException {
+    public DirectPayment createCredit(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final CallContext callContext) throws PaymentApiException {
         return null;
     }
 
     @Override
-    public List<DirectPayment> getAccountPayments(final UUID accountId, final boolean withPluginInfo, final TenantContext tenantContext) throws PaymentApiException {
+    public List<DirectPayment> getAccountPayments(final UUID accountId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
         return directPaymentProcessor.getAccountPayments(accountId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(accountId, tenantContext));
     }
 
     @Override
-    public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final TenantContext tenantContext) throws PaymentApiException {
+    public DirectPayment getPayment(final UUID directPaymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext) throws PaymentApiException {
         return directPaymentProcessor.getPayment(directPaymentId, withPluginInfo, internalCallContextFactory.createInternalTenantContext(tenantContext));
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentInternalApi.java b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentInternalApi.java
index 3ac67f9..2ef6b33 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentInternalApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/svcs/DefaultPaymentInternalApi.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -23,13 +25,14 @@ import javax.inject.Inject;
 
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
+import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.payment.api.Payment;
 import org.killbill.billing.payment.api.PaymentApiException;
 import org.killbill.billing.payment.api.PaymentInternalApi;
 import org.killbill.billing.payment.api.PaymentMethod;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.core.PaymentMethodProcessor;
 import org.killbill.billing.payment.core.PaymentProcessor;
-import org.killbill.billing.callcontext.InternalTenantContext;
 
 public class DefaultPaymentInternalApi implements PaymentInternalApi {
 
@@ -43,8 +46,8 @@ public class DefaultPaymentInternalApi implements PaymentInternalApi {
     }
 
     @Override
-    public Payment getPayment(final UUID paymentId, final InternalTenantContext context) throws PaymentApiException {
-        final Payment payment = paymentProcessor.getPayment(paymentId, false, context);
+    public Payment getPayment(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
+        final Payment payment = paymentProcessor.getPayment(paymentId, false, properties, context);
         if (payment == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
         }
@@ -52,8 +55,8 @@ public class DefaultPaymentInternalApi implements PaymentInternalApi {
     }
 
     @Override
-    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final boolean includedInactive, final InternalTenantContext context) throws PaymentApiException {
-        return methodProcessor.getPaymentMethodById(paymentMethodId, includedInactive, false, context);
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final boolean includedInactive, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
+        return methodProcessor.getPaymentMethodById(paymentMethodId, includedInactive, false, properties, context);
     }
 
     @Override
@@ -62,7 +65,7 @@ public class DefaultPaymentInternalApi implements PaymentInternalApi {
     }
 
     @Override
-    public List<PaymentMethod> getPaymentMethods(final Account account, final InternalTenantContext context) throws PaymentApiException {
-        return methodProcessor.getPaymentMethods(account, false, context);
+    public List<PaymentMethod> getPaymentMethods(final Account account, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
+        return methodProcessor.getPaymentMethods(account, false, properties, context);
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java b/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java
index 545dd5a..a4d0fe0 100644
--- a/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java
+++ b/payment/src/main/java/org/killbill/billing/payment/bus/InvoiceHandler.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -16,21 +18,22 @@
 
 package org.killbill.billing.payment.bus;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.account.api.AccountApiException;
+import org.killbill.billing.account.api.AccountInternalApi;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.events.InvoiceCreationInternalEvent;
 import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.util.callcontext.CallOrigin;
-import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.callcontext.UserType;
-import org.killbill.billing.events.InvoiceCreationInternalEvent;
-import org.killbill.billing.account.api.AccountInternalApi;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
 import com.google.common.eventbus.Subscribe;
 import com.google.inject.Inject;
 
@@ -61,13 +64,13 @@ public class InvoiceHandler {
         try {
             final InternalCallContext internalContext = internalCallContextFactory.createInternalCallContext(event.getSearchKey2(), event.getSearchKey1(), "PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken());
             account = accountApi.getAccountById(event.getAccountId(), internalContext);
-            paymentProcessor.createPayment(account, event.getInvoiceId(), null, internalContext, false, false);
-        } catch (AccountApiException e) {
+            paymentProcessor.createPayment(account, event.getInvoiceId(), null, internalContext, false, false, ImmutableList.<PluginProperty>of());
+        } catch (final AccountApiException e) {
             log.error("Failed to process invoice payment", e);
-        } catch (PaymentApiException e) {
+        } catch (final PaymentApiException e) {
             // Log as error unless:
             if (e.getCode() != ErrorCode.PAYMENT_NULL_INVOICE.getCode() /* Nothing left to be paid */ &&
-                    e.getCode() != ErrorCode.PAYMENT_CREATE_PAYMENT.getCode() /* User payment error */) {
+                e.getCode() != ErrorCode.PAYMENT_CREATE_PAYMENT.getCode() /* User payment error */) {
                 log.error("Failed to process invoice payment {}", e.toString());
             }
         }
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
index 0d38183..685a244 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/DirectPaymentProcessor.java
@@ -106,7 +106,7 @@ public class DirectPaymentProcessor extends ProcessorBase {
         this.voidPluginDispatcher = new PluginDispatcher<Void>(paymentPluginTimeoutSec, executor);
     }
 
-    public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final InternalCallContext callContext) throws PaymentApiException {
+    public DirectPayment createAuthorization(final Account account, final BigDecimal amount, final String externalKey, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
 
         final PaymentPluginApi plugin = getPaymentProviderPlugin(account, callContext);
 
@@ -124,7 +124,7 @@ public class DirectPaymentProcessor extends ProcessorBase {
         try {
 
             try {
-                infoPlugin = plugin.authorizePayment(account.getId(), pmd.getId(), ptmd.getId(), amount, account.getCurrency(), ImmutableList.<PluginProperty>of(), callContext.toCallContext(tenantId));
+                infoPlugin = plugin.authorizePayment(account.getId(), pmd.getId(), ptmd.getId(), amount, account.getCurrency(), properties, callContext.toCallContext(tenantId));
             } catch (final RuntimeException e) {
                 // Handle case of plugin RuntimeException to be handled the same as a Plugin failure (PaymentPluginApiException)
                 final String formatError = String.format("Plugin threw RuntimeException for payment %s", pmd.getId());
@@ -170,19 +170,19 @@ public class DirectPaymentProcessor extends ProcessorBase {
         return result;
     }
 
-    public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final InternalCallContext callContext) throws PaymentApiException {
+    public DirectPayment createCapture(final Account account, final UUID directPaymentId, final BigDecimal amount, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
         return null;
     }
 
-    public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final InternalCallContext callContext) throws PaymentApiException {
+    public DirectPayment createPurchase(final Account account, final BigDecimal amount, final String externalKey, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
         return null;
     }
 
-    public DirectPayment createVoid(final Account account, final UUID directPaymentId, final InternalCallContext callContext) throws PaymentApiException {
+    public DirectPayment createVoid(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
         return null;
     }
 
-    public DirectPayment createCredit(final Account account, final UUID directPaymentId, final InternalCallContext callContext) throws PaymentApiException {
+    public DirectPayment createCredit(final Account account, final UUID directPaymentId, final Iterable<PluginProperty> properties, final InternalCallContext callContext) throws PaymentApiException {
         return null;
     }
 
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
index 687982a..705af4a 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentMethodProcessor.java
@@ -87,7 +87,8 @@ public class PaymentMethodProcessor extends ProcessorBase {
     }
 
     public UUID addPaymentMethod(final String paymentPluginServiceName, final Account account,
-                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodProps, final InternalCallContext context)
+                                 final boolean setDefault, final PaymentMethodPlugin paymentMethodProps,
+                                 final Iterable<PluginProperty> properties, final InternalCallContext context)
             throws PaymentApiException {
         final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
 
@@ -100,7 +101,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                 try {
                     pluginApi = getPaymentPluginApi(paymentPluginServiceName);
                     pm = new DefaultPaymentMethod(account.getId(), paymentPluginServiceName, paymentMethodProps);
-                    pluginApi.addPaymentMethod(account.getId(), pm.getId(), paymentMethodProps, setDefault, ImmutableList.<PluginProperty>of(), context.toCallContext(tenantId));
+                    pluginApi.addPaymentMethod(account.getId(), pm.getId(), paymentMethodProps, setDefault, properties, context.toCallContext(tenantId));
                     final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getCreatedDate(), pm.getUpdatedDate(),
                                                                                     pm.getAccountId(), pm.getPluginName(), pm.isActive());
                     paymentDao.insertPaymentMethod(pmModel, context);
@@ -120,31 +121,31 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginInfo, final InternalTenantContext context) throws PaymentApiException {
+    public List<PaymentMethod> getPaymentMethods(final Account account, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
 
         final List<PaymentMethodModelDao> paymentMethodModels = paymentDao.getPaymentMethods(account.getId(), context);
         if (paymentMethodModels.size() == 0) {
             return Collections.emptyList();
         }
-        return getPaymentMethodInternal(paymentMethodModels, withPluginInfo, context);
+        return getPaymentMethodInternal(paymentMethodModels, withPluginInfo, properties, context);
     }
 
-    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final boolean includedDeleted, final boolean withPluginInfo, final InternalTenantContext context)
+    public PaymentMethod getPaymentMethodById(final UUID paymentMethodId, final boolean includedDeleted, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context)
             throws PaymentApiException {
         final PaymentMethodModelDao paymentMethodModel = includedDeleted ? paymentDao.getPaymentMethodIncludedDeleted(paymentMethodId, context) : paymentDao.getPaymentMethod(paymentMethodId, context);
         if (paymentMethodModel == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodId);
         }
 
-        return buildDefaultPaymentMethod(paymentMethodModel, withPluginInfo, context);
+        return buildDefaultPaymentMethod(paymentMethodModel, withPluginInfo, properties, context);
     }
 
-    private PaymentMethod buildDefaultPaymentMethod(final PaymentMethodModelDao paymentMethodModelDao, final boolean withPluginInfo, final InternalTenantContext context) throws PaymentApiException {
+    private PaymentMethod buildDefaultPaymentMethod(final PaymentMethodModelDao paymentMethodModelDao, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
         final PaymentMethodPlugin paymentMethodPlugin;
         if (withPluginInfo) {
             try {
                 final PaymentPluginApi pluginApi = getPaymentPluginApi(paymentMethodModelDao.getPluginName());
-                paymentMethodPlugin = pluginApi.getPaymentMethodDetail(paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId(), ImmutableList.<PluginProperty>of(), buildTenantContext(context));
+                paymentMethodPlugin = pluginApi.getPaymentMethodDetail(paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId(), properties, buildTenantContext(context));
             } catch (final PaymentPluginApiException e) {
                 log.warn("Error retrieving payment method " + paymentMethodModelDao.getId() + " from plugin " + paymentMethodModelDao.getPluginName(), e);
                 throw new PaymentApiException(ErrorCode.PAYMENT_GET_PAYMENT_METHODS, paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId());
@@ -156,20 +157,20 @@ public class PaymentMethodProcessor extends ProcessorBase {
         return new DefaultPaymentMethod(paymentMethodModelDao, paymentMethodPlugin);
     }
 
-    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
+    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
         return getEntityPaginationFromPlugins(getAvailablePlugins(),
                                               offset,
                                               limit,
                                               new EntityPaginationBuilder<PaymentMethod, PaymentApiException>() {
                                                   @Override
                                                   public Pagination<PaymentMethod> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
-                                                      return getPaymentMethods(offset, limit, pluginName, tenantContext, internalTenantContext);
+                                                      return getPaymentMethods(offset, limit, pluginName, properties, tenantContext, internalTenantContext);
                                                   }
                                               }
                                              );
     }
 
-    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final String pluginName, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
 
         return getEntityPagination(limit,
@@ -185,7 +186,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                                        public PaymentMethod apply(final PaymentMethodModelDao paymentMethodModelDao) {
                                            PaymentMethodPlugin paymentMethodPlugin = null;
                                            try {
-                                               paymentMethodPlugin = pluginApi.getPaymentMethodDetail(paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId(), ImmutableList.<PluginProperty>of(), tenantContext);
+                                               paymentMethodPlugin = pluginApi.getPaymentMethodDetail(paymentMethodModelDao.getAccountId(), paymentMethodModelDao.getId(), properties, tenantContext);
                                            } catch (final PaymentPluginApiException e) {
                                                log.warn("Unable to find payment method id " + paymentMethodModelDao.getId() + " in plugin " + pluginName);
                                                // We still want to return a payment method object, even though the plugin details are missing
@@ -197,20 +198,21 @@ public class PaymentMethodProcessor extends ProcessorBase {
                                   );
     }
 
-    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final InternalTenantContext internalTenantContext) {
+    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) {
         return getEntityPaginationFromPlugins(getAvailablePlugins(),
                                               offset,
                                               limit,
                                               new EntityPaginationBuilder<PaymentMethod, PaymentApiException>() {
                                                   @Override
                                                   public Pagination<PaymentMethod> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
-                                                      return searchPaymentMethods(searchKey, offset, limit, pluginName, internalTenantContext);
+                                                      return searchPaymentMethods(searchKey, offset, limit, pluginName, properties, internalTenantContext);
                                                   }
                                               }
                                              );
     }
 
-    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final String pluginName, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Pagination<PaymentMethod> searchPaymentMethods(final String searchKey, final Long offset, final Long limit, final String pluginName,
+                                                          final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
 
         return getEntityPagination(limit,
@@ -218,7 +220,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                                        @Override
                                        public Pagination<PaymentMethodPlugin> build() throws PaymentApiException {
                                            try {
-                                               return pluginApi.searchPaymentMethods(searchKey, offset, limit, ImmutableList.<PluginProperty>of(), buildTenantContext(internalTenantContext));
+                                               return pluginApi.searchPaymentMethods(searchKey, offset, limit, properties, buildTenantContext(internalTenantContext));
                                            } catch (final PaymentPluginApiException e) {
                                                throw new PaymentApiException(e, ErrorCode.PAYMENT_PLUGIN_SEARCH_PAYMENT_METHODS, pluginName, searchKey);
                                            }
@@ -245,8 +247,8 @@ public class PaymentMethodProcessor extends ProcessorBase {
                                   );
     }
 
-    public PaymentMethod getExternalPaymentMethod(final Account account, final InternalTenantContext context) throws PaymentApiException {
-        final List<PaymentMethod> paymentMethods = getPaymentMethods(account, false, context);
+    public PaymentMethod getExternalPaymentMethod(final Account account, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
+        final List<PaymentMethod> paymentMethods = getPaymentMethods(account, false, properties, context);
         for (final PaymentMethod paymentMethod : paymentMethods) {
             if (ExternalPaymentProviderPlugin.PLUGIN_NAME.equals(paymentMethod.getPluginName())) {
                 return paymentMethod;
@@ -256,30 +258,31 @@ public class PaymentMethodProcessor extends ProcessorBase {
         return null;
     }
 
-    public ExternalPaymentProviderPlugin getExternalPaymentProviderPlugin(final Account account, final InternalCallContext context) throws PaymentApiException {
+    public ExternalPaymentProviderPlugin getExternalPaymentProviderPlugin(final Account account, final Iterable<PluginProperty> properties, final InternalCallContext context) throws PaymentApiException {
         // Check if this account has already used the external payment plugin
         // If not, it's the first time - add a payment method for it
-        if (getExternalPaymentMethod(account, context) == null) {
-            final DefaultNoOpPaymentMethodPlugin props = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, ImmutableList.<PluginProperty>of());
-            addPaymentMethod(ExternalPaymentProviderPlugin.PLUGIN_NAME, account, false, props, context);
+        if (getExternalPaymentMethod(account, properties, context) == null) {
+            final DefaultNoOpPaymentMethodPlugin props = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, properties);
+            addPaymentMethod(ExternalPaymentProviderPlugin.PLUGIN_NAME, account, false, props, properties, context);
         }
 
         return (ExternalPaymentProviderPlugin) getPaymentPluginApi(ExternalPaymentProviderPlugin.PLUGIN_NAME);
     }
 
-    private List<PaymentMethod> getPaymentMethodInternal(final List<PaymentMethodModelDao> paymentMethodModels, final boolean withPluginInfo, final InternalTenantContext context)
+    private List<PaymentMethod> getPaymentMethodInternal(final List<PaymentMethodModelDao> paymentMethodModels, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context)
             throws PaymentApiException {
 
         final List<PaymentMethod> result = new ArrayList<PaymentMethod>(paymentMethodModels.size());
         for (final PaymentMethodModelDao paymentMethodModel : paymentMethodModels) {
-            final PaymentMethod pm = buildDefaultPaymentMethod(paymentMethodModel, withPluginInfo, context);
+            final PaymentMethod pm = buildDefaultPaymentMethod(paymentMethodModel, withPluginInfo, properties, context);
             result.add(pm);
         }
         return result;
     }
 
     public void deletedPaymentMethod(final Account account, final UUID paymentMethodId,
-                                     final boolean deleteDefaultPaymentMethodWithAutoPayOff, final InternalCallContext context)
+                                     final boolean deleteDefaultPaymentMethodWithAutoPayOff,
+                                     final Iterable<PluginProperty> properties, final InternalCallContext context)
             throws PaymentApiException {
         final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
 
@@ -307,7 +310,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                         }
                     }
                     final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, context);
-                    pluginApi.deletePaymentMethod(account.getId(), paymentMethodId, ImmutableList.<PluginProperty>of(), context.toCallContext(tenantId));
+                    pluginApi.deletePaymentMethod(account.getId(), paymentMethodId, properties, context.toCallContext(tenantId));
                     paymentDao.deletedPaymentMethod(paymentMethodId, context);
                     return null;
                 } catch (final PaymentPluginApiException e) {
@@ -320,7 +323,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
         });
     }
 
-    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final InternalCallContext context)
+    public void setDefaultPaymentMethod(final Account account, final UUID paymentMethodId, final Iterable<PluginProperty> properties, final InternalCallContext context)
             throws PaymentApiException {
         final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
 
@@ -336,7 +339,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                 try {
                     final PaymentPluginApi pluginApi = getPluginApi(paymentMethodId, context);
 
-                    pluginApi.setDefaultPaymentMethod(account.getId(), paymentMethodId, ImmutableList.<PluginProperty>of(), context.toCallContext(tenantId));
+                    pluginApi.setDefaultPaymentMethod(account.getId(), paymentMethodId, properties, context.toCallContext(tenantId));
                     accountInternalApi.updatePaymentMethod(account.getId(), paymentMethodId, context);
                     return null;
                 } catch (final PaymentPluginApiException e) {
@@ -368,14 +371,14 @@ public class PaymentMethodProcessor extends ProcessorBase {
      * @return the list of payment methods -- should be identical between KB, the plugin view-- if it keeps a state-- and the gateway.
      * @throws PaymentApiException
      */
-    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final InternalCallContext context) throws PaymentApiException {
+    public List<PaymentMethod> refreshPaymentMethods(final String pluginName, final Account account, final Iterable<PluginProperty> properties, final InternalCallContext context) throws PaymentApiException {
         final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
 
         // Don't hold the account lock while fetching the payment methods from the gateway as those could change anyway
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
         final List<PaymentMethodInfoPlugin> pluginPms;
         try {
-            pluginPms = pluginApi.getPaymentMethods(account.getId(), true, ImmutableList.<PluginProperty>of(), context.toCallContext(tenantId));
+            pluginPms = pluginApi.getPaymentMethods(account.getId(), true, properties, context.toCallContext(tenantId));
             // The method should never return null by convention, but let's not trust the plugin...
             if (pluginPms == null) {
                 log.debug("No payment methods defined on the account {} for plugin {}", account.getId(), pluginName);
@@ -418,7 +421,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                                                                                                              finalPaymentMethods,
                                                                                                              context);
                 try {
-                    pluginApi.resetPaymentMethods(account.getId(), pluginPmsWithId, ImmutableList.<PluginProperty>of());
+                    pluginApi.resetPaymentMethods(account.getId(), pluginPmsWithId, properties);
                 } catch (final PaymentPluginApiException e) {
                     log.warn("Error resetting payment methods for account " + account.getId() + " and plugin " + pluginName, e);
                     throw new PaymentApiException(ErrorCode.PAYMENT_REFRESH_PAYMENT_METHOD, account.getId(), e.getErrorMessage());
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index 504a59d..0eb2783 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -80,7 +80,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
 import com.google.common.collect.Collections2;
-import com.google.common.collect.ImmutableList;
 import com.google.inject.name.Named;
 
 import static org.killbill.billing.payment.glue.PaymentModule.PLUGIN_EXECUTOR_NAMED;
@@ -133,7 +132,7 @@ public class PaymentProcessor extends ProcessorBase {
         this.voidPluginDispatcher = new PluginDispatcher<Void>(paymentPluginTimeoutSec, executor);
     }
 
-    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final InternalTenantContext context) throws PaymentApiException {
+    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
         final PaymentModelDao model = paymentDao.getPayment(paymentId, context);
         if (model == null) {
             return null;
@@ -142,7 +141,7 @@ public class PaymentProcessor extends ProcessorBase {
         PaymentInfoPlugin pluginInfo = null;
         if (plugin != null) {
             try {
-                pluginInfo = plugin.getPaymentInfo(model.getAccountId(), paymentId, ImmutableList.<PluginProperty>of(), buildTenantContext(context));
+                pluginInfo = plugin.getPaymentInfo(model.getAccountId(), paymentId, properties, buildTenantContext(context));
             } catch (final PaymentPluginApiException e) {
                 throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_GET_PAYMENT_INFO, paymentId, e.toString());
             }
@@ -150,20 +149,21 @@ public class PaymentProcessor extends ProcessorBase {
         return fromPaymentModelDao(model, pluginInfo, context);
     }
 
-    public Pagination<Payment> getPayments(final Long offset, final Long limit, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
+    public Pagination<Payment> getPayments(final Long offset, final Long limit, final Iterable<PluginProperty> properties,
+                                           final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
         return getEntityPaginationFromPlugins(getAvailablePlugins(),
                                               offset,
                                               limit,
                                               new EntityPaginationBuilder<Payment, PaymentApiException>() {
                                                   @Override
                                                   public Pagination<Payment> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
-                                                      return getPayments(offset, limit, pluginName, tenantContext, internalTenantContext);
+                                                      return getPayments(offset, limit, pluginName, properties, tenantContext, internalTenantContext);
                                                   }
                                               }
                                              );
     }
 
-    public Pagination<Payment> getPayments(final Long offset, final Long limit, final String pluginName, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Pagination<Payment> getPayments(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
 
         return getEntityPagination(limit,
@@ -179,7 +179,7 @@ public class PaymentProcessor extends ProcessorBase {
                                        public Payment apply(final PaymentModelDao paymentModelDao) {
                                            PaymentInfoPlugin pluginInfo = null;
                                            try {
-                                               pluginInfo = pluginApi.getPaymentInfo(paymentModelDao.getAccountId(), paymentModelDao.getId(), ImmutableList.<PluginProperty>of(), tenantContext);
+                                               pluginInfo = pluginApi.getPaymentInfo(paymentModelDao.getAccountId(), paymentModelDao.getId(), properties, tenantContext);
                                            } catch (final PaymentPluginApiException e) {
                                                log.warn("Unable to find payment id " + paymentModelDao.getId() + " in plugin " + pluginName);
                                                // We still want to return a payment object, even though the plugin details are missing
@@ -191,20 +191,20 @@ public class PaymentProcessor extends ProcessorBase {
                                   );
     }
 
-    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final InternalTenantContext internalTenantContext) {
+    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) {
         return getEntityPaginationFromPlugins(getAvailablePlugins(),
                                               offset,
                                               limit,
                                               new EntityPaginationBuilder<Payment, PaymentApiException>() {
                                                   @Override
                                                   public Pagination<Payment> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
-                                                      return searchPayments(searchKey, offset, limit, pluginName, internalTenantContext);
+                                                      return searchPayments(searchKey, offset, limit, pluginName, properties, internalTenantContext);
                                                   }
                                               }
                                              );
     }
 
-    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final String pluginName, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Pagination<Payment> searchPayments(final String searchKey, final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
 
         return getEntityPagination(limit,
@@ -212,7 +212,7 @@ public class PaymentProcessor extends ProcessorBase {
                                        @Override
                                        public Pagination<PaymentInfoPlugin> build() throws PaymentApiException {
                                            try {
-                                               return pluginApi.searchPayments(searchKey, offset, limit, ImmutableList.<PluginProperty>of(), buildTenantContext(internalTenantContext));
+                                               return pluginApi.searchPayments(searchKey, offset, limit, properties, buildTenantContext(internalTenantContext));
                                            } catch (final PaymentPluginApiException e) {
                                                throw new PaymentApiException(e, ErrorCode.PAYMENT_PLUGIN_SEARCH_PAYMENTS, pluginName, searchKey);
                                            }
@@ -316,7 +316,8 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     public Payment createPayment(final Account account, final UUID invoiceId, @Nullable final BigDecimal inputAmount,
-                                 final InternalCallContext context, final boolean isInstantPayment, final boolean isExternalPayment)
+                                 final InternalCallContext context, final boolean isInstantPayment,
+                                 final boolean isExternalPayment, final Iterable<PluginProperty> properties)
             throws PaymentApiException {
         // If this is an external payment, retrieve the external payment method first.
         // We need to do this without the lock, because getExternalPaymentProviderPlugin will acquire the lock
@@ -325,7 +326,7 @@ public class PaymentProcessor extends ProcessorBase {
         // (to avoid throwing an exception if there is nothing to pay).
         final PaymentPluginApi externalPaymentPlugin;
         if (isExternalPayment) {
-            externalPaymentPlugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, context);
+            externalPaymentPlugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, properties, context);
         } else {
             externalPaymentPlugin = null;
         }
@@ -356,7 +357,7 @@ public class PaymentProcessor extends ProcessorBase {
                                                                                                                         // Use the special external payment plugin to handle external payments
                                                                                                                         if (isExternalPayment) {
                                                                                                                             plugin = externalPaymentPlugin;
-                                                                                                                            paymentMethodId = paymentMethodProcessor.getExternalPaymentMethod(account, context).getId();
+                                                                                                                            paymentMethodId = paymentMethodProcessor.getExternalPaymentMethod(account, properties, context).getId();
                                                                                                                         } else {
                                                                                                                             plugin = getPaymentProviderPlugin(account, context);
                                                                                                                             paymentMethodId = account.getPaymentMethodId();
@@ -383,7 +384,7 @@ public class PaymentProcessor extends ProcessorBase {
                                                                                                                     if (!isInstantPayment && isAccountAutoPayOff) {
                                                                                                                         return processNewPaymentForAutoPayOffWithAccountLocked(paymentMethodId, account, invoice, requestedAmount, context);
                                                                                                                     } else {
-                                                                                                                        return processNewPaymentWithAccountLocked(paymentMethodId, plugin, account, invoice, requestedAmount, isInstantPayment, context);
+                                                                                                                        return processNewPaymentWithAccountLocked(paymentMethodId, plugin, account, invoice, requestedAmount, isInstantPayment, properties, context);
                                                                                                                     }
                                                                                                                 } catch (final InvoiceApiException e) {
                                                                                                                     throw new PaymentApiException(e);
@@ -468,29 +469,30 @@ public class PaymentProcessor extends ProcessorBase {
         return inputAmount != null ? inputAmount : invoice.getBalance();
     }
 
-    public void retryAutoPayOff(final UUID paymentId, final InternalCallContext context) {
-        retryFailedPaymentInternal(paymentId, context, PaymentStatus.AUTO_PAY_OFF);
+    public void retryAutoPayOff(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
+        retryFailedPaymentInternal(paymentId, properties, context, PaymentStatus.AUTO_PAY_OFF);
     }
 
-    public void retryPluginFailure(final UUID paymentId, final InternalCallContext context) {
+    public void retryPluginFailure(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
 
-        retryFailedPaymentInternal(paymentId, context, PaymentStatus.PLUGIN_FAILURE);
+        retryFailedPaymentInternal(paymentId, properties, context, PaymentStatus.PLUGIN_FAILURE);
     }
 
-    public void retryFailedPayment(final UUID paymentId, final InternalCallContext context) {
+    public void retryFailedPayment(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
         log.info("Retrying failed payment " + paymentId + " time = " + clock.getUTCNow());
-        retryFailedPaymentInternal(paymentId, context, PaymentStatus.PAYMENT_FAILURE);
+        retryFailedPaymentInternal(paymentId, properties, context, PaymentStatus.PAYMENT_FAILURE);
     }
 
-    public void retryPaymentFromApi(final UUID paymentId, final InternalCallContext context) {
+    public void retryPaymentFromApi(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
         log.info("Retrying payment " + paymentId + " time = " + clock.getUTCNow());
-        retryFailedPaymentInternal(paymentId, context, PaymentStatus.UNKNOWN,
+        retryFailedPaymentInternal(paymentId, properties, context,
+                                   PaymentStatus.UNKNOWN,
                                    PaymentStatus.AUTO_PAY_OFF,
                                    PaymentStatus.PAYMENT_FAILURE,
                                    PaymentStatus.PLUGIN_FAILURE);
     }
 
-    private void retryFailedPaymentInternal(final UUID paymentId, final InternalCallContext context, final PaymentStatus... expectedPaymentStates) {
+    private void retryFailedPaymentInternal(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context, final PaymentStatus... expectedPaymentStates) {
 
         try {
 
@@ -538,7 +540,7 @@ public class PaymentProcessor extends ProcessorBase {
                                                                                                            setTerminalStateOnRetryWithAccountLocked(account, invoice, payment, invoice.getBalance(), "Paid invoice", context);
                                                                                                            return null;
                                                                                                        }
-                                                                                                       processRetryPaymentWithAccountLocked(plugin, account, invoice, payment, invoice.getBalance(), context);
+                                                                                                       processRetryPaymentWithAccountLocked(plugin, account, invoice, payment, invoice.getBalance(), properties, context);
                                                                                                        return null;
                                                                                                    } catch (final InvoiceApiException e) {
                                                                                                        throw new PaymentApiException(e);
@@ -583,13 +585,13 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     private Payment processNewPaymentWithAccountLocked(final UUID paymentMethodId, final PaymentPluginApi plugin, final Account account, final Invoice invoice,
-                                                       final BigDecimal requestedAmount, final boolean isInstantPayment, final InternalCallContext context) throws PaymentApiException {
+                                                       final BigDecimal requestedAmount, final boolean isInstantPayment, final Iterable<PluginProperty> properties, final InternalCallContext context) throws PaymentApiException {
         final PaymentModelDao payment = new PaymentModelDao(account.getId(), invoice.getId(), paymentMethodId, requestedAmount, invoice.getCurrency(), clock.getUTCNow());
         final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), paymentMethodId, clock.getUTCNow(),
                                                                           requestedAmount, invoice.getCurrency());
 
         final PaymentModelDao savedPayment = paymentDao.insertPaymentWithFirstAttempt(payment, attempt, context);
-        return processPaymentWithAccountLocked(plugin, account, invoice, savedPayment, attempt, isInstantPayment, context);
+        return processPaymentWithAccountLocked(plugin, account, invoice, savedPayment, attempt, isInstantPayment, properties, context);
     }
 
     private Payment setTerminalStateOnRetryWithAccountLocked(final Account account, final Invoice invoice, final PaymentModelDao payment, final BigDecimal requestedAmount, final String terminalStateReason, final InternalCallContext context) {
@@ -620,15 +622,16 @@ public class PaymentProcessor extends ProcessorBase {
     }
 
     private Payment processRetryPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice, final PaymentModelDao payment,
-                                                         final BigDecimal requestedAmount, final InternalCallContext context) throws PaymentApiException {
+                                                         final BigDecimal requestedAmount, final Iterable<PluginProperty> properties, final InternalCallContext context) throws PaymentApiException {
         final PaymentAttemptModelDao attempt = new PaymentAttemptModelDao(account.getId(), invoice.getId(), payment.getId(), account.getPaymentMethodId(), clock.getUTCNow(),
                                                                           requestedAmount, invoice.getCurrency());
         paymentDao.updatePaymentWithNewAttempt(payment.getId(), attempt, context);
-        return processPaymentWithAccountLocked(plugin, account, invoice, payment, attempt, false, context);
+        return processPaymentWithAccountLocked(plugin, account, invoice, payment, attempt, false, properties, context);
     }
 
     private Payment processPaymentWithAccountLocked(final PaymentPluginApi plugin, final Account account, final Invoice invoice,
-                                                    final PaymentModelDao paymentInput, final PaymentAttemptModelDao attemptInput, final boolean isInstantPayment, final InternalCallContext context)
+                                                    final PaymentModelDao paymentInput, final PaymentAttemptModelDao attemptInput,
+                                                    final boolean isInstantPayment, final Iterable<PluginProperty> properties, final InternalCallContext context)
             throws PaymentApiException {
         final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
 
@@ -647,7 +650,7 @@ public class PaymentProcessor extends ProcessorBase {
         try {
             try {
                 paymentPluginInfo = plugin.processPayment(account.getId(), paymentInput.getId(), attemptInput.getPaymentMethodId(),
-                                                          attemptInput.getRequestedAmount(), account.getCurrency(), ImmutableList.<PluginProperty>of(), context.toCallContext(tenantId));
+                                                          attemptInput.getRequestedAmount(), account.getCurrency(), properties, context.toCallContext(tenantId));
             } catch (final RuntimeException e) {
                 // Handle case of plugin RuntimeException to be handled the same as a Plugin failure (PaymentPluginApiException)
                 final String formatError = String.format("Plugin threw RuntimeException for payment %s", paymentInput.getId());
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/RefundProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/RefundProcessor.java
index d509840..5bb884c 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/RefundProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/RefundProcessor.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -114,7 +116,8 @@ public class RefundProcessor extends ProcessorBase {
      * @throws PaymentApiException
      */
     public Refund createRefund(final Account account, final UUID paymentId, @Nullable final BigDecimal specifiedRefundAmount,
-                               final boolean isAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts, final InternalCallContext context)
+                               final boolean isAdjusted, final Map<UUID, BigDecimal> invoiceItemIdsWithAmounts,
+                               final Iterable<PluginProperty> properties, final InternalCallContext context)
             throws PaymentApiException {
         final UUID tenantId = nonEntityDao.retrieveIdFromObject(context.getTenantRecordId(), ObjectType.TENANT);
 
@@ -135,7 +138,7 @@ public class RefundProcessor extends ProcessorBase {
                     paymentDao.insertRefund(refundInfo, context);
 
                     final PaymentPluginApi plugin = getPaymentProviderPlugin(payment.getPaymentMethodId(), context);
-                    final RefundInfoPlugin refundInfoPlugin = plugin.processRefund(account.getId(), paymentId, refundAmount, account.getCurrency(), ImmutableList.<PluginProperty>of(), context.toCallContext(tenantId));
+                    final RefundInfoPlugin refundInfoPlugin = plugin.processRefund(account.getId(), paymentId, refundAmount, account.getCurrency(), properties, context.toCallContext(tenantId));
 
                     switch (refundInfoPlugin.getStatus()) {
                         case PROCESSED:
@@ -165,9 +168,9 @@ public class RefundProcessor extends ProcessorBase {
                                                                               refundInfoPlugin.getSecondRefundReferenceId())
                             );
                     }
-                } catch (PaymentPluginApiException e) {
+                } catch (final PaymentPluginApiException e) {
                     throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_REFUND, account.getId(), e.getErrorMessage());
-                } catch (InvoiceApiException e) {
+                } catch (final InvoiceApiException e) {
                     throw new PaymentApiException(e);
                 }
             }
@@ -193,7 +196,7 @@ public class RefundProcessor extends ProcessorBase {
                     // TODO STEPH : Model is broken if we had an invoice item adjustements as we lost track of them
                     invoiceApi.createRefund(refund.getPaymentId(), refund.getAmount(), refund.isAdjusted(), Collections.<UUID, BigDecimal>emptyMap(), refund.getId(), context);
                     paymentDao.updateRefundStatus(refund.getId(), RefundStatus.COMPLETED, refund.getAmount(), refund.getCurrency(), context);
-                } catch (InvoiceApiException e) {
+                } catch (final InvoiceApiException e) {
                 }
                 return null;
             }
@@ -227,7 +230,7 @@ public class RefundProcessor extends ProcessorBase {
             }
 
             return Objects.firstNonNull(specifiedRefundAmount, amountFromItems);
-        } catch (InvoiceApiException e) {
+        } catch (final InvoiceApiException e) {
             throw new PaymentApiException(e);
         }
     }
@@ -242,7 +245,7 @@ public class RefundProcessor extends ProcessorBase {
         throw new IllegalArgumentException("Unable to find invoice item for id " + itemId);
     }
 
-    public Refund getRefund(final UUID refundId, final boolean withPluginInfo, final InternalTenantContext context) throws PaymentApiException {
+    public Refund getRefund(final UUID refundId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final InternalTenantContext context) throws PaymentApiException {
         RefundModelDao result = paymentDao.getRefund(refundId, context);
         if (result == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_REFUND, refundId);
@@ -266,7 +269,7 @@ public class RefundProcessor extends ProcessorBase {
         List<RefundInfoPlugin> refundInfoPlugins = ImmutableList.<RefundInfoPlugin>of();
         if (plugin != null) {
             try {
-                refundInfoPlugins = plugin.getRefundInfo(result.getAccountId(), result.getPaymentId(), ImmutableList.<PluginProperty>of(), buildTenantContext(context));
+                refundInfoPlugins = plugin.getRefundInfo(result.getAccountId(), result.getPaymentId(), properties, buildTenantContext(context));
             } catch (final PaymentPluginApiException e) {
                 throw new PaymentApiException(ErrorCode.PAYMENT_PLUGIN_GET_REFUND_INFO, refundId, e.toString());
             }
@@ -300,20 +303,21 @@ public class RefundProcessor extends ProcessorBase {
                );
     }
 
-    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
+    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) {
         return getEntityPaginationFromPlugins(getAvailablePlugins(),
                                               offset,
                                               limit,
                                               new EntityPaginationBuilder<Refund, PaymentApiException>() {
                                                   @Override
                                                   public Pagination<Refund> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
-                                                      return getRefunds(offset, limit, pluginName, tenantContext, internalTenantContext);
+                                                      return getRefunds(offset, limit, pluginName, properties, tenantContext, internalTenantContext);
                                                   }
                                               }
                                              );
     }
 
-    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final String pluginName, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Pagination<Refund> getRefunds(final Long offset, final Long limit, final String pluginName, final Iterable<PluginProperty> properties,
+                                         final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
 
         return getEntityPagination(limit,
@@ -329,7 +333,7 @@ public class RefundProcessor extends ProcessorBase {
                                        public Refund apply(final RefundModelDao refundModelDao) {
                                            List<RefundInfoPlugin> refundInfoPlugins = null;
                                            try {
-                                               refundInfoPlugins = pluginApi.getRefundInfo(refundModelDao.getAccountId(), refundModelDao.getId(), ImmutableList.<PluginProperty>of(), tenantContext);
+                                               refundInfoPlugins = pluginApi.getRefundInfo(refundModelDao.getAccountId(), refundModelDao.getId(), properties, tenantContext);
                                            } catch (final PaymentPluginApiException e) {
                                                log.warn("Unable to find refund id " + refundModelDao.getId() + " in plugin " + pluginName);
                                                // We still want to return a refund object, even though the plugin details are missing
@@ -342,20 +346,21 @@ public class RefundProcessor extends ProcessorBase {
                                   );
     }
 
-    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final InternalTenantContext internalTenantContext) {
+    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) {
         return getEntityPaginationFromPlugins(getAvailablePlugins(),
                                               offset,
                                               limit,
                                               new EntityPaginationBuilder<Refund, PaymentApiException>() {
                                                   @Override
                                                   public Pagination<Refund> build(final Long offset, final Long limit, final String pluginName) throws PaymentApiException {
-                                                      return searchRefunds(searchKey, offset, limit, pluginName, internalTenantContext);
+                                                      return searchRefunds(searchKey, offset, limit, pluginName, properties, internalTenantContext);
                                                   }
                                               }
                                              );
     }
 
-    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final String pluginName, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Pagination<Refund> searchRefunds(final String searchKey, final Long offset, final Long limit, final String pluginName,
+                                            final Iterable<PluginProperty> properties, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentPluginApi pluginApi = getPaymentPluginApi(pluginName);
 
         final Map<UUID, List<RefundInfoPlugin>> refundsByPaymentId = new HashMap<UUID, List<RefundInfoPlugin>>();
@@ -367,7 +372,7 @@ public class RefundProcessor extends ProcessorBase {
                                        public Pagination<RefundInfoPlugin> build() throws PaymentApiException {
                                            final Pagination<RefundInfoPlugin> refunds;
                                            try {
-                                               refunds = pluginApi.searchRefunds(searchKey, offset, limit, ImmutableList.<PluginProperty>of(), buildTenantContext(internalTenantContext));
+                                               refunds = pluginApi.searchRefunds(searchKey, offset, limit, properties, buildTenantContext(internalTenantContext));
                                            } catch (final PaymentPluginApiException e) {
                                                throw new PaymentApiException(e, ErrorCode.PAYMENT_PLUGIN_SEARCH_REFUNDS, pluginName, searchKey);
                                            }
@@ -495,14 +500,14 @@ public class RefundProcessor extends ProcessorBase {
                             invoiceApi.createRefund(cur.getPaymentId(), cur.getAmount(), cur.isAdjusted(), ImmutableMap.<UUID, BigDecimal>of(), cur.getId(), context);
                             paymentDao.updateRefundStatus(cur.getId(), RefundStatus.COMPLETED, cur.getProcessedAmount(), cur.getProcessedCurrency(), context);
                         }
-                    } catch (InvoiceApiException e) {
+                    } catch (final InvoiceApiException e) {
                         throw new PaymentApiException(e);
                     }
                     return null;
                 }
             });
             return true;
-        } catch (AccountApiException e) {
+        } catch (final AccountApiException e) {
             throw new PaymentApiException(e);
         }
     }
diff --git a/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java b/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
index 266e303..27ae2d2 100644
--- a/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
+++ b/payment/src/main/java/org/killbill/billing/payment/provider/DefaultNoOpPaymentMethodPlugin.java
@@ -26,6 +26,8 @@ import javax.annotation.Nullable;
 import org.killbill.billing.payment.api.PaymentMethodPlugin;
 import org.killbill.billing.payment.api.PluginProperty;
 
+import com.google.common.collect.ImmutableList;
+
 public class DefaultNoOpPaymentMethodPlugin implements PaymentMethodPlugin {
 
     private final UUID kbPaymentMethodId;
@@ -42,18 +44,18 @@ public class DefaultNoOpPaymentMethodPlugin implements PaymentMethodPlugin {
 
     public DefaultNoOpPaymentMethodPlugin(final String externalId,
                                           final boolean isDefault,
-                                          final List<PluginProperty> props) {
+                                          final Iterable<PluginProperty> props) {
         this(null, externalId, isDefault, props);
     }
 
     public DefaultNoOpPaymentMethodPlugin(@Nullable final UUID kbPaymentMethodId,
                                           final String externalId,
                                           final boolean isDefault,
-                                          final List<PluginProperty> props) {
+                                          final Iterable<PluginProperty> props) {
         this.kbPaymentMethodId = kbPaymentMethodId;
         this.externalId = externalId;
         this.isDefault = isDefault;
-        this.props = props;
+        this.props = ImmutableList.<PluginProperty>copyOf(props);
     }
 
     @Override
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/AutoPayRetryService.java b/payment/src/main/java/org/killbill/billing/payment/retry/AutoPayRetryService.java
index 0686db9..a6f9b7f 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/AutoPayRetryService.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/AutoPayRetryService.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -19,12 +21,12 @@ package org.killbill.billing.payment.retry;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-
-import org.killbill.notificationq.api.NotificationQueueService;
-import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.config.PaymentConfig;
+import org.killbill.notificationq.api.NotificationQueueService;
 
 import com.google.inject.Inject;
 
@@ -49,8 +51,8 @@ public class AutoPayRetryService extends BaseRetryService implements RetryServic
     }
 
     @Override
-    public void retry(final UUID paymentId, final InternalCallContext context) {
-        paymentProcessor.retryAutoPayOff(paymentId, context);
+    public void retry(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
+        paymentProcessor.retryAutoPayOff(paymentId, properties, context);
     }
 
     public static class AutoPayRetryServiceScheduler extends RetryServiceScheduler {
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java b/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java
index 2aa7e45..5251c19 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/BaseRetryService.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -20,24 +22,25 @@ import java.io.IOException;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import org.killbill.billing.ObjectType;
-import org.killbill.notificationq.api.NotificationEvent;
-import org.killbill.notificationq.api.NotificationQueue;
-import org.killbill.notificationq.api.NotificationQueueService;
-import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
-import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueAlreadyExists;
-import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueHandler;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.glue.DefaultPaymentService;
 import org.killbill.billing.util.callcontext.CallOrigin;
-import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.callcontext.UserType;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
 import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import org.killbill.notificationq.api.NotificationEvent;
+import org.killbill.notificationq.api.NotificationQueue;
+import org.killbill.notificationq.api.NotificationQueueService;
+import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
+import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueAlreadyExists;
+import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 public abstract class BaseRetryService implements RetryService {
@@ -69,9 +72,10 @@ public abstract class BaseRetryService implements RetryService {
                                                                               }
                                                                               final PaymentRetryNotificationKey key = (PaymentRetryNotificationKey) notificationKey;
                                                                               final InternalCallContext callContext = internalCallContextFactory.createInternalCallContext(tenantRecordId, accountRecordId, PAYMENT_RETRY_SERVICE, CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
-                                                                              retry(key.getUuidKey(), callContext);
+                                                                              retry(key.getUuidKey(), ImmutableList.<PluginProperty>of(), callContext);
                                                                           }
-                                                                      });
+                                                                      }
+                                                                     );
     }
 
     @Override
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/FailedPaymentRetryService.java b/payment/src/main/java/org/killbill/billing/payment/retry/FailedPaymentRetryService.java
index 18c7f36..ffe5b94 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/FailedPaymentRetryService.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/FailedPaymentRetryService.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -20,15 +22,15 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.killbill.notificationq.api.NotificationQueueService;
-import org.killbill.billing.util.config.PaymentConfig;
-import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
+import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.clock.Clock;
+import org.killbill.notificationq.api.NotificationQueueService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 
@@ -50,8 +52,8 @@ public class FailedPaymentRetryService extends BaseRetryService implements Retry
     }
 
     @Override
-    public void retry(final UUID paymentId, final InternalCallContext context) {
-        paymentProcessor.retryFailedPayment(paymentId, context);
+    public void retry(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
+        paymentProcessor.retryFailedPayment(paymentId, properties, context);
     }
 
     public static class FailedPaymentRetryServiceScheduler extends RetryServiceScheduler {
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/PluginFailureRetryService.java b/payment/src/main/java/org/killbill/billing/payment/retry/PluginFailureRetryService.java
index 93e4765..988caa2 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/PluginFailureRetryService.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/PluginFailureRetryService.java
@@ -19,17 +19,17 @@ package org.killbill.billing.payment.retry;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.killbill.notificationq.api.NotificationQueueService;
-import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.payment.api.PluginProperty;
+import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.killbill.clock.Clock;
 import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.billing.util.entity.dao.EntitySqlDao;
 import org.killbill.billing.util.entity.dao.EntitySqlDaoWrapperFactory;
+import org.killbill.clock.Clock;
+import org.killbill.notificationq.api.NotificationQueueService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.inject.Inject;
 
@@ -50,8 +50,8 @@ public class PluginFailureRetryService extends BaseRetryService implements Retry
     }
 
     @Override
-    public void retry(final UUID paymentId, final InternalCallContext context) {
-        paymentProcessor.retryPluginFailure(paymentId, context);
+    public void retry(final UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context) {
+        paymentProcessor.retryPluginFailure(paymentId, properties, context);
     }
 
     public static class PluginFailureRetryServiceScheduler extends RetryServiceScheduler {
diff --git a/payment/src/main/java/org/killbill/billing/payment/retry/RetryService.java b/payment/src/main/java/org/killbill/billing/payment/retry/RetryService.java
index 657848a..c5f3fbd 100644
--- a/payment/src/main/java/org/killbill/billing/payment/retry/RetryService.java
+++ b/payment/src/main/java/org/killbill/billing/payment/retry/RetryService.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -13,26 +15,25 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package org.killbill.billing.payment.retry;
 
 import java.util.UUID;
 
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.notificationq.api.NotificationQueueService.NoSuchNotificationQueue;
 import org.killbill.notificationq.api.NotificationQueueService.NotificationQueueAlreadyExists;
-import org.killbill.billing.callcontext.InternalCallContext;
 
 public interface RetryService {
 
-    public void initialize(final String svcName)
-            throws NotificationQueueAlreadyExists;
+    public void initialize(final String svcName) throws NotificationQueueAlreadyExists;
 
     public void start();
 
-    public void stop()
-            throws NoSuchNotificationQueue;
+    public void stop() throws NoSuchNotificationQueue;
 
     public String getQueueName();
 
-    public void retry(UUID paymentId, final InternalCallContext context);
-
+    public void retry(UUID paymentId, final Iterable<PluginProperty> properties, final InternalCallContext context);
 }
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 25bd6dd..8627f14 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
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -21,21 +23,21 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
-import org.testng.Assert;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
-import org.killbill.bus.api.PersistentBus.EventBusException;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
 import org.killbill.billing.payment.MockRecurringInvoiceItem;
 import org.killbill.billing.payment.PaymentTestSuiteWithEmbeddedDB;
+import org.killbill.bus.api.PersistentBus.EventBusException;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
 
-public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
+import com.google.common.collect.ImmutableList;
 
+public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
 
     private Account account;
 
@@ -45,11 +47,8 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         account = testHelper.createTestAccount("bobo@gmail.com", false);
     }
 
-
     @Test(groups = "slow")
     public void testCreatePaymentWithNoDefaultPaymentMethod() throws InvoiceApiException, EventBusException, PaymentApiException {
-
-
         final LocalDate now = clock.getUTCToday();
         final Invoice invoice = testHelper.createTestInvoice(account, now, Currency.USD, callContext);
 
@@ -68,8 +67,8 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
                                                             Currency.USD));
 
         try {
-            paymentApi.createPayment(account, invoice.getId(), requestedAmount, callContext);
-        } catch (PaymentApiException e) {
+            paymentApi.createPayment(account, invoice.getId(), requestedAmount, ImmutableList.<PluginProperty>of(), callContext);
+        } catch (final PaymentApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_NO_DEFAULT_PAYMENT_METHOD.getCode());
         }
 
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
index 5d85e82..91c8c22 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApiNoDB.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -17,18 +19,10 @@
 package org.killbill.billing.payment.api;
 
 import java.math.BigDecimal;
-import java.math.RoundingMode;
 import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
-import org.mockito.Mockito;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.catalog.api.Currency;
@@ -37,6 +31,14 @@ import org.killbill.billing.payment.MockRecurringInvoiceItem;
 import org.killbill.billing.payment.PaymentTestSuiteNoDB;
 import org.killbill.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
+import org.mockito.Mockito;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
@@ -47,6 +49,8 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
 
     private static final Logger log = LoggerFactory.getLogger(TestPaymentApiNoDB.class);
 
+    private final Iterable<PluginProperty> PLUGIN_PROPERTIES = ImmutableList.<PluginProperty>of();
+
     private Account account;
 
     @BeforeClass(groups = "fast")
@@ -116,7 +120,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
                                                             Currency.USD));
 
         try {
-            final Payment paymentInfo = paymentApi.createPayment(account, invoice.getId(), requestedAmount, callContext);
+            final Payment paymentInfo = paymentApi.createPayment(account, invoice.getId(), requestedAmount, PLUGIN_PROPERTIES, callContext);
             if (expectedAmount == null) {
                 fail("Expected to fail because requested amount > invoice amount");
             }
@@ -131,7 +135,7 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
             final PaymentAttempt paymentAttempt = paymentInfo.getAttempts().get(0);
             assertNotNull(paymentAttempt);
             assertNotNull(paymentAttempt.getId());
-        } catch (PaymentApiException e) {
+        } catch (final PaymentApiException e) {
             if (expectedAmount != null) {
                 fail("Failed to create payment", e);
             } else {
@@ -143,37 +147,37 @@ public class TestPaymentApiNoDB extends PaymentTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testPaymentMethods() throws Exception {
-        List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, false, callContext);
+        List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, false, PLUGIN_PROPERTIES, callContext);
         assertEquals(methods.size(), 1);
 
         final PaymentMethod initDefaultMethod = methods.get(0);
         assertEquals(initDefaultMethod.getId(), account.getPaymentMethodId());
 
         final PaymentMethodPlugin newPaymenrMethod = new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), true, null);
-        final UUID newPaymentMethodId = paymentApi.addPaymentMethod(MockPaymentProviderPlugin.PLUGIN_NAME, account, true, newPaymenrMethod, callContext);
+        final UUID newPaymentMethodId = paymentApi.addPaymentMethod(MockPaymentProviderPlugin.PLUGIN_NAME, account, true, newPaymenrMethod, PLUGIN_PROPERTIES, callContext);
         Mockito.when(account.getPaymentMethodId()).thenReturn(newPaymentMethodId);
 
-        methods = paymentApi.getPaymentMethods(account, false, callContext);
+        methods = paymentApi.getPaymentMethods(account, false, PLUGIN_PROPERTIES, callContext);
         assertEquals(methods.size(), 2);
 
         assertEquals(newPaymentMethodId, account.getPaymentMethodId());
 
         boolean failed = false;
         try {
-            paymentApi.deletedPaymentMethod(account, newPaymentMethodId, false, callContext);
-        } catch (PaymentApiException e) {
+            paymentApi.deletedPaymentMethod(account, newPaymentMethodId, false, PLUGIN_PROPERTIES, callContext);
+        } catch (final PaymentApiException e) {
             failed = true;
         }
         assertTrue(failed);
 
-        paymentApi.deletedPaymentMethod(account, initDefaultMethod.getId(), true,  callContext);
-        methods = paymentApi.getPaymentMethods(account, false, callContext);
+        paymentApi.deletedPaymentMethod(account, initDefaultMethod.getId(), true, PLUGIN_PROPERTIES, callContext);
+        methods = paymentApi.getPaymentMethods(account, false, PLUGIN_PROPERTIES, callContext);
         assertEquals(methods.size(), 1);
 
         // NOW retry with default payment method with special flag
-        paymentApi.deletedPaymentMethod(account, newPaymentMethodId, true, callContext);
+        paymentApi.deletedPaymentMethod(account, newPaymentMethodId, true, PLUGIN_PROPERTIES, callContext);
 
-        methods = paymentApi.getPaymentMethods(account, false, callContext);
+        methods = paymentApi.getPaymentMethods(account, false, PLUGIN_PROPERTIES, callContext);
         assertEquals(methods.size(), 0);
     }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorNoDB.java b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorNoDB.java
index 1277751..acef033 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorNoDB.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -19,29 +21,32 @@ package org.killbill.billing.payment.core;
 import java.util.List;
 import java.util.UUID;
 
-import org.mockito.Mockito;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.payment.PaymentTestSuiteNoDB;
 import org.killbill.billing.payment.api.PaymentMethod;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.provider.ExternalPaymentProviderPlugin;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
 
 public class TestPaymentMethodProcessorNoDB extends PaymentTestSuiteNoDB {
 
     @Test(groups = "fast")
     public void testGetExternalPaymentProviderPlugin() throws Exception {
+        final Iterable<PluginProperty> properties = ImmutableList.<PluginProperty>of();
         final UUID accountId = UUID.randomUUID();
         final Account account = Mockito.mock(Account.class);
         Mockito.when(account.getId()).thenReturn(accountId);
         Mockito.when(account.getExternalKey()).thenReturn(accountId.toString());
 
-        Assert.assertEquals(paymentMethodProcessor.getPaymentMethods(account, false, internalCallContext).size(), 0);
+        Assert.assertEquals(paymentMethodProcessor.getPaymentMethods(account, false, properties, internalCallContext).size(), 0);
 
         // The first call should create the payment method
-        final ExternalPaymentProviderPlugin providerPlugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, internalCallContext);
-        final List<PaymentMethod> paymentMethods = paymentMethodProcessor.getPaymentMethods(account, false, internalCallContext);
+        final ExternalPaymentProviderPlugin providerPlugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, properties, internalCallContext);
+        final List<PaymentMethod> paymentMethods = paymentMethodProcessor.getPaymentMethods(account, false, properties, internalCallContext);
         Assert.assertEquals(paymentMethods.size(), 1);
         Assert.assertEquals(paymentMethods.get(0).getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
         Assert.assertEquals(paymentMethods.get(0).getAccountId(), account.getId());
@@ -49,10 +54,10 @@ public class TestPaymentMethodProcessorNoDB extends PaymentTestSuiteNoDB {
         // The succeeding calls should not create any other payment method
         final UUID externalPaymentMethodId = paymentMethods.get(0).getId();
         for (int i = 0; i < 50; i++) {
-            final ExternalPaymentProviderPlugin foundProviderPlugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, internalCallContext);
-            Assert.assertNotNull (foundProviderPlugin);
+            final ExternalPaymentProviderPlugin foundProviderPlugin = paymentMethodProcessor.getExternalPaymentProviderPlugin(account, properties, internalCallContext);
+            Assert.assertNotNull(foundProviderPlugin);
 
-            final List<PaymentMethod> foundPaymentMethods = paymentMethodProcessor.getPaymentMethods(account, false, internalCallContext);
+            final List<PaymentMethod> foundPaymentMethods = paymentMethodProcessor.getPaymentMethods(account, false, properties, internalCallContext);
             Assert.assertEquals(foundPaymentMethods.size(), 1);
             Assert.assertEquals(foundPaymentMethods.get(0).getPluginName(), ExternalPaymentProviderPlugin.PLUGIN_NAME);
             Assert.assertEquals(foundPaymentMethods.get(0).getAccountId(), account.getId());
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorRefreshWithDB.java b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorRefreshWithDB.java
index 99ade9c..f85cd60 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorRefreshWithDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/TestPaymentMethodProcessorRefreshWithDB.java
@@ -37,26 +37,26 @@ import com.google.common.collect.ImmutableList;
 
 public class TestPaymentMethodProcessorRefreshWithDB extends PaymentTestSuiteWithEmbeddedDB {
 
+    private static final ImmutableList<PluginProperty> PLUGIN_PROPERTIES = ImmutableList.<PluginProperty>of();
+
     @BeforeMethod(groups = "slow")
     public void beforeMethod() throws Exception {
         super.beforeMethod();
-        getPluginApi().resetPaymentMethods(null, null, ImmutableList.<PluginProperty>of());
+        getPluginApi().resetPaymentMethods(null, null, PLUGIN_PROPERTIES);
     }
 
     @Test(groups = "slow")
     public void testRefreshWithNewPaymentMethod() throws Exception {
-        final ImmutableList<PluginProperty> pluginProperties = ImmutableList.<PluginProperty>of();
-
         final Account account = testHelper.createTestAccount("foo@bar.com", true);
-        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, pluginProperties, callContext).size(), 1);
+        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, PLUGIN_PROPERTIES, callContext).size(), 1);
         final UUID existingPMId = account.getPaymentMethodId();
 
         // Add new payment in plugin directly
         final UUID newPmId = UUID.randomUUID();
-        getPluginApi().addPaymentMethod(account.getId(), newPmId, new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, ImmutableList.<PluginProperty>of()), false, pluginProperties, callContext);
+        getPluginApi().addPaymentMethod(account.getId(), newPmId, new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, ImmutableList.<PluginProperty>of()), false, PLUGIN_PROPERTIES, callContext);
 
         // Verify that the refresh does indeed show 2 PMs
-        final List<PaymentMethod> methods = paymentMethodProcessor.refreshPaymentMethods(MockPaymentProviderPlugin.PLUGIN_NAME, account, internalCallContext);
+        final List<PaymentMethod> methods = paymentMethodProcessor.refreshPaymentMethods(MockPaymentProviderPlugin.PLUGIN_NAME, account, PLUGIN_PROPERTIES, internalCallContext);
         Assert.assertEquals(methods.size(), 2);
         checkPaymentMethodExistsWithStatus(methods, existingPMId, true);
         checkPaymentMethodExistsWithStatus(methods, newPmId, true);
@@ -64,23 +64,21 @@ public class TestPaymentMethodProcessorRefreshWithDB extends PaymentTestSuiteWit
 
     @Test(groups = "slow")
     public void testRefreshWithDeletedPaymentMethod() throws Exception {
-        final ImmutableList<PluginProperty> pluginProperties = ImmutableList.<PluginProperty>of();
-
         final Account account = testHelper.createTestAccount("super@bar.com", true);
-        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, pluginProperties, callContext).size(), 1);
+        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, PLUGIN_PROPERTIES, callContext).size(), 1);
         final UUID firstPmId = account.getPaymentMethodId();
 
-        final UUID secondPmId = paymentApi.addPaymentMethod(MockPaymentProviderPlugin.PLUGIN_NAME, account, true, new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, null), callContext);
-        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, pluginProperties, callContext).size(), 2);
-        Assert.assertEquals(paymentApi.getPaymentMethods(account, false, callContext).size(), 2);
+        final UUID secondPmId = paymentApi.addPaymentMethod(MockPaymentProviderPlugin.PLUGIN_NAME, account, true, new DefaultNoOpPaymentMethodPlugin(UUID.randomUUID().toString(), false, null), PLUGIN_PROPERTIES, callContext);
+        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, PLUGIN_PROPERTIES, callContext).size(), 2);
+        Assert.assertEquals(paymentApi.getPaymentMethods(account, false, PLUGIN_PROPERTIES, callContext).size(), 2);
 
         // Remove second PM from plugin
-        getPluginApi().deletePaymentMethod(account.getId(), secondPmId, pluginProperties, callContext);
-        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, pluginProperties, callContext).size(), 1);
-        Assert.assertEquals(paymentApi.getPaymentMethods(account, false, callContext).size(), 2);
+        getPluginApi().deletePaymentMethod(account.getId(), secondPmId, PLUGIN_PROPERTIES, callContext);
+        Assert.assertEquals(getPluginApi().getPaymentMethods(account.getId(), true, PLUGIN_PROPERTIES, callContext).size(), 1);
+        Assert.assertEquals(paymentApi.getPaymentMethods(account, false, PLUGIN_PROPERTIES, callContext).size(), 2);
 
         // Verify that the refresh sees that PM as being deleted now
-        final List<PaymentMethod> methods = paymentMethodProcessor.refreshPaymentMethods(MockPaymentProviderPlugin.PLUGIN_NAME, account, internalCallContext);
+        final List<PaymentMethod> methods = paymentMethodProcessor.refreshPaymentMethods(MockPaymentProviderPlugin.PLUGIN_NAME, account, PLUGIN_PROPERTIES, internalCallContext);
         Assert.assertEquals(methods.size(), 1);
         checkPaymentMethodExistsWithStatus(methods, firstPmId, true);
 
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java b/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java
index 9bdb5fe..cdb961e 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestPaymentHelper.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project 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:
  *
@@ -19,27 +21,28 @@ package org.killbill.billing.payment;
 import java.util.UUID;
 
 import org.joda.time.LocalDate;
-import org.mockito.Mockito;
-
 import org.killbill.billing.account.api.Account;
-import org.killbill.bus.api.PersistentBus;
-import org.killbill.bus.api.PersistentBus.EventBusException;
+import org.killbill.billing.account.api.AccountInternalApi;
+import org.killbill.billing.callcontext.InternalCallContext;
+import org.killbill.billing.callcontext.InternalTenantContext;
 import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.events.InvoiceCreationInternalEvent;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceApiException;
+import org.killbill.billing.invoice.api.InvoiceInternalApi;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.payment.api.PaymentApi;
 import org.killbill.billing.payment.api.PaymentMethodPlugin;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.provider.DefaultNoOpPaymentMethodPlugin;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
 import org.killbill.billing.util.callcontext.CallContext;
-import org.killbill.billing.callcontext.InternalCallContext;
-import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.bus.api.PersistentBus;
+import org.killbill.bus.api.PersistentBus.EventBusException;
 import org.killbill.clock.Clock;
-import org.killbill.billing.events.InvoiceCreationInternalEvent;
-import org.killbill.billing.account.api.AccountInternalApi;
-import org.killbill.billing.invoice.api.InvoiceInternalApi;
+import org.mockito.Mockito;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Inject;
 
 public class TestPaymentHelper {
@@ -127,7 +130,7 @@ public class TestPaymentHelper {
     }
 
     public void addTestPaymentMethod(final Account account, final PaymentMethodPlugin paymentMethodInfo) throws Exception {
-        final UUID paymentMethodId = paymentApi.addPaymentMethod(MockPaymentProviderPlugin.PLUGIN_NAME, account, true, paymentMethodInfo, context);
+        final UUID paymentMethodId = paymentApi.addPaymentMethod(MockPaymentProviderPlugin.PLUGIN_NAME, account, true, paymentMethodInfo, ImmutableList.<PluginProperty>of(), context);
         Mockito.when(account.getPaymentMethodId()).thenReturn(paymentMethodId);
     }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java b/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java
index be4208a..4c9b676 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestRetryService.java
@@ -25,19 +25,21 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 
 import org.joda.time.LocalDate;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
 import org.killbill.billing.account.api.Account;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.payment.api.Payment;
-import org.killbill.billing.payment.api.PaymentAttempt;
 import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentAttempt;
 import org.killbill.billing.payment.api.PaymentStatus;
+import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.glue.DefaultPaymentService;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
 
 import static com.jayway.awaitility.Awaitility.await;
 import static java.util.concurrent.TimeUnit.SECONDS;
@@ -132,8 +134,8 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
         setPaymentFailure(failureType);
         boolean failed = false;
         try {
-            paymentProcessor.createPayment(account, invoice.getId(), amount, internalCallContext, false, false);
-        } catch (PaymentApiException e) {
+            paymentProcessor.createPayment(account, invoice.getId(), amount, internalCallContext, false, false, ImmutableList.<PluginProperty>of());
+        } catch (final PaymentApiException e) {
             failed = true;
         }
         assertTrue(failed);
@@ -155,7 +157,7 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
                             return payment.getPaymentStatus() == PaymentStatus.SUCCESS;
                         }
                     });
-                } catch (TimeoutException e) {
+                } catch (final TimeoutException e) {
                     if (curFailure == maxTries - 1) {
                         fail("Failed to find successful payment for attempt " + (curFailure + 1) + "/" + maxTries);
                     }
@@ -166,7 +168,7 @@ public class TestRetryService extends PaymentTestSuiteNoDB {
         final List<PaymentAttempt> attempts = payment.getAttempts();
 
         final int expectedAttempts = maxTries < getMaxRetrySizeForFailureType(failureType) ?
-                maxTries + 1 : getMaxRetrySizeForFailureType(failureType) + 1;
+                                     maxTries + 1 : getMaxRetrySizeForFailureType(failureType) + 1;
         assertEquals(attempts.size(), expectedAttempts);
         Collections.sort(attempts, new Comparator<PaymentAttempt>() {
             @Override

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 0f5373e..392015d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -19,7 +19,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.7.1</version>
+        <version>0.7.2</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.11.2-SNAPSHOT</version>