killbill-aplcache

Fix various tests which were broken because of PaymentMethod

6/9/2012 7:22:17 PM

Details

diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
index 682fa02..67c707a 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountBinder.java
@@ -48,7 +48,7 @@ public @interface AccountBinder {
                     Currency currency = account.getCurrency();
                     q.bind("currency", (currency == null) ? null : currency.toString());
                     q.bind("billingCycleDay", account.getBillCycleDay());
-                    q.bind("paymentMethodId", account.getPaymentMethodId());
+                    q.bind("paymentMethodId", account.getPaymentMethodId() != null ? account.getPaymentMethodId().toString() : null);
                     DateTimeZone timeZone = account.getTimeZone();
                     q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
                     q.bind("locale", account.getLocale());
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java b/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java
index c496b53..be30dc6 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountHistoryBinder.java
@@ -53,7 +53,7 @@ public @interface AccountHistoryBinder {
                     Currency currency = account.getCurrency();
                     q.bind("currency", (currency == null) ? null : currency.toString());
                     q.bind("billingCycleDay", account.getBillCycleDay());
-                    q.bind("paymentMethodId", account.getPaymentMethodId());
+                    q.bind("paymentMethodId", account.getPaymentMethodId() !=  null ? account.getPaymentMethodId().toString() : null);
                     DateTimeZone timeZone = account.getTimeZone();
                     q.bind("timeZone", (timeZone == null) ? null : timeZone.toString());
                     q.bind("locale", account.getLocale());
diff --git a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
index 07a3351..ba1d3f6 100644
--- a/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
+++ b/account/src/test/java/com/ning/billing/account/dao/TestAccountDao.java
@@ -67,7 +67,7 @@ public class TestAccountDao extends AccountDaoTestBase {
         int firstNameLength = firstName.length();
 
         return new DefaultAccount(UUID.randomUUID(), thisKey, thisEmail, name, firstNameLength, Currency.USD,
-                billCycleDay, null, timeZone, locale,
+                billCycleDay, UUID.randomUUID(), timeZone, locale,
                 null, null, null, null, null, null, null, // add null address fields
                 phone, false, false);
     }
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java
index 9f7b259..58a9c63 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/BeatrixModule.java
@@ -30,6 +30,7 @@ import com.google.inject.AbstractModule;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 import com.ning.billing.account.api.AccountService;
+import com.ning.billing.account.glue.AccountModule;
 import com.ning.billing.account.glue.AccountModuleWithMocks;
 import com.ning.billing.beatrix.integration.overdue.IntegrationTestOverdueModule;
 import com.ning.billing.beatrix.lifecycle.DefaultLifecycle;
@@ -64,6 +65,7 @@ import com.ning.billing.util.glue.TagStoreModule;
 
 
 public class BeatrixModule extends AbstractModule {
+    
     public static final String PLUGIN_NAME = "yoyo";
 
     @Override
@@ -94,17 +96,17 @@ public class BeatrixModule extends AbstractModule {
         install(new NotificationQueueModule());
         install(new TagStoreModule());
         install(new CustomFieldModule());
-        install(new AccountModuleWithMocks());
+        install(new AccountModule());
         install(new CatalogModule());
         install(new DefaultEntitlementModule());
         install(new DefaultInvoiceModule());
         install(new TemplateModule());
-        install(new PaymentMockModule());
+        install(new PaymentPluginMockModule());
         install(new DefaultJunctionModule());
         install(new IntegrationTestOverdueModule());
     }
 
-    private static final class PaymentMockModule extends PaymentModule {
+    private static final class PaymentPluginMockModule extends PaymentModule {
         @Override
         protected void installPaymentProviderPlugins(PaymentConfig config) {
             install(new MockPaymentProviderPluginModule(PLUGIN_NAME));
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 33c4298..8b205f8 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -27,6 +27,7 @@ import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.Callable;
 
 import org.joda.time.DateTime;
@@ -55,6 +56,7 @@ import com.ning.billing.overdue.OverdueUserApi;
 import com.ning.billing.overdue.config.OverdueConfig;
 import com.ning.billing.overdue.wrapper.OverdueWrapperFactory;
 import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentMethodPlugin;
 import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
 import com.ning.billing.util.callcontext.DefaultCallContext;
 import com.ning.billing.util.clock.ClockMock;
@@ -142,8 +144,28 @@ public class TestOverdueIntegration extends TestIntegrationBase {
         config = XMLLoader.getObjectFromStreamNoValidation(is,  OverdueConfig.class);
         overdueWrapperFactory.setOverdueConfig(config);
         
-        account = accountUserApi.createAccount(getAccountData(25), null, null, context);
+        account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
+        
+        PaymentMethodPlugin info = new PaymentMethodPlugin() {
+            @Override
+            public boolean isDefaultPaymentMethod() {
+                return false;
+            }
+            @Override
+            public String getValueString(String key) {
+                return null;
+            }
+            @Override
+            public List<PaymentMethodKVInfo> getProperties() {
+                return null;
+            }
+            @Override
+            public String getExternalPaymentMethodId() {
+                return UUID.randomUUID().toString();
+            }
+        };
+        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, info, context);
 
         bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
 
@@ -167,7 +189,7 @@ public class TestOverdueIntegration extends TestIntegrationBase {
         clock.setTime(new DateTime(2012, 5, 1, 0, 3, 42, 0));
         paymentPlugin.makeAllInvoicesFailWithError(true);
         
-        // set next invoice to fail and create network 
+        // set next invoice to fail and create subscription 
         busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.INVOICE);
         SubscriptionData baseSubscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                 new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
@@ -177,9 +199,6 @@ public class TestOverdueIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT_ERROR);
         clock.addDays(30); // DAY 30 have to get out of trial before first payment
         
-        // STEPH
-        //Thread.sleep(600000);
-        
         assertTrue(busHandler.isCompleted(DELAY));
         
         // should still be in clear state
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
index 310b99b..943f470 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegration.java
@@ -30,8 +30,6 @@ import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
 import com.ning.billing.account.api.Account;
-import com.ning.billing.account.api.AccountApiException;
-import com.ning.billing.account.api.AccountData;
 import com.ning.billing.api.TestApiListener.NextEvent;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.Currency;
@@ -39,7 +37,6 @@ import com.ning.billing.catalog.api.PhaseType;
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.catalog.api.PriceListSet;
 import com.ning.billing.catalog.api.ProductCategory;
-import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
 import com.ning.billing.entitlement.api.user.SubscriptionData;
 import com.ning.billing.invoice.api.Invoice;
@@ -94,6 +91,7 @@ public class TestIntegration extends TestIntegrationBase {
             testBasePlanCompleteWithBillingDayInFuture();
         }
     }
+    
 
     // STEPH set to disabled until test written properly and fixed
     @Test(groups = "slow", enabled = false)
@@ -104,7 +102,7 @@ public class TestIntegration extends TestIntegrationBase {
         DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
         
-        Account account = accountUserApi.createAccount(getAccountData(25), null, null, context);
+        Account account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
         SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
@@ -154,11 +152,11 @@ public class TestIntegration extends TestIntegrationBase {
     }
    
     @Test(groups = {"slow"})
-    public void testRepairForInvoicing() throws AccountApiException, EntitlementUserApiException {
+    public void testRepairForInvoicing() throws Exception {
 
         log.info("Starting testRepairForInvoicing");
 
-        Account account = accountUserApi.createAccount(getAccountData(1), null, null, context);
+        Account account = createAccountWithPaymentMethod(getAccountData(1));
         UUID accountId = account.getId();
         assertNotNull(account);
 
@@ -194,7 +192,7 @@ public class TestIntegration extends TestIntegrationBase {
         int billingDay = 2;
 
         log.info("Beginning test with BCD of " + billingDay);
-        Account account = accountUserApi.createAccount(getAccountData(billingDay), null, null, context);
+        Account account = createAccountWithPaymentMethod(getAccountData(billingDay));
         UUID accountId = account.getId();
         assertNotNull(account);
 
@@ -263,11 +261,9 @@ public class TestIntegration extends TestIntegrationBase {
                                       boolean proRationExpected) throws Exception {
 
         log.info("Beginning test with BCD of " + billingDay);
-        AccountData accountData = getAccountData(billingDay);
-        Account account = accountUserApi.createAccount(accountData, null, null, context);
+        Account account = createAccountWithPaymentMethod(getAccountData(billingDay));
         UUID accountId = account.getId();
-        assertNotNull(account);
-
+        
         // set clock to the initial start date
         clock.setDeltaFromReality(initialCreationDate.getMillis() - clock.getUTCNow().getMillis());
         SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
@@ -283,9 +279,7 @@ public class TestIntegration extends TestIntegrationBase {
         busHandler.pushExpectedEvent(NextEvent.INVOICE);
         SubscriptionData subscription = subscriptionDataFromSubscription(entitlementUserApi.createSubscription(bundle.getId(),
                 new PlanPhaseSpecifier(productName, ProductCategory.BASE, term, planSetName, null), null, context));
-           
         assertNotNull(subscription);
-
         assertTrue(busHandler.isCompleted(DELAY));
 
         //
@@ -464,14 +458,14 @@ public class TestIntegration extends TestIntegrationBase {
 
 
     @Test(groups = "slow")
-    public void testForMultipleRecurringPhases() throws AccountApiException, EntitlementUserApiException, InterruptedException {
+    public void testForMultipleRecurringPhases() throws Exception {
 
         log.info("Starting testForMultipleRecurringPhases");
         
         DateTime initialCreationDate = new DateTime(2012, 2, 1, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialCreationDate.getMillis() - clock.getUTCNow().getMillis());
 
-        Account account = accountUserApi.createAccount(getAccountData(2), null, null, context);
+        Account account = createAccountWithPaymentMethod(getAccountData(2));
         UUID accountId = account.getId();
 
         String productName = "Blowdart";
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
index 803c20d..fda34cb 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationBase.java
@@ -40,6 +40,8 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 
 import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
+import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountData;
 import com.ning.billing.account.api.AccountService;
 import com.ning.billing.account.api.AccountUserApi;
@@ -60,6 +62,10 @@ import com.ning.billing.invoice.api.InvoiceService;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 import com.ning.billing.invoice.model.InvoicingConfiguration;
 import com.ning.billing.junction.plumbing.api.BlockingSubscription;
+import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentApiException;
+import com.ning.billing.payment.api.PaymentMethodPlugin;
+import com.ning.billing.payment.api.PaymentMethodPlugin.PaymentMethodKVInfo;
 import com.ning.billing.util.bus.BusService;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
@@ -118,6 +124,9 @@ public class TestIntegrationBase implements TestListenerStatus {
     protected InvoiceUserApi invoiceUserApi;
 
     @Inject
+    protected PaymentApi paymentApi;
+    
+    @Inject
     protected AccountUserApi accountUserApi;
 
     protected TestApiListener busHandler;
@@ -251,6 +260,33 @@ public class TestIntegrationBase implements TestListenerStatus {
         return (SubscriptionData)((BlockingSubscription)sub).getDelegateSubscription();
     }
     
+    protected Account createAccountWithPaymentMethod(AccountData accountData) throws Exception {
+        Account account = accountUserApi.createAccount(accountData, null, null, context);
+        assertNotNull(account);
+        
+        PaymentMethodPlugin info = new PaymentMethodPlugin() {
+            @Override
+            public boolean isDefaultPaymentMethod() {
+                return false;
+            }
+            @Override
+            public String getValueString(String key) {
+                return null;
+            }
+            @Override
+            public List<PaymentMethodKVInfo> getProperties() {
+                return null;
+            }
+            @Override
+            public String getExternalPaymentMethodId() {
+                return UUID.randomUUID().toString();
+            }
+        };
+        paymentApi.addPaymentMethod(BeatrixModule.PLUGIN_NAME, account, true, info, context);
+        return accountUserApi.getAccountById(account.getId());
+    }
+
+    
     protected AccountData getAccountData(final int billingDay) {
 
         final String someRandomKey = RandomStringUtils.randomAlphanumeric(10);
@@ -296,7 +332,7 @@ public class TestIntegrationBase implements TestListenerStatus {
             }
             @Override
             public UUID getPaymentMethodId() {
-                return UUID.randomUUID();
+                return null;
             }
 
             @Override
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
index bc4f5a9..3b462f1 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestIntegrationWithAutoInvoiceOffTag.java
@@ -65,7 +65,7 @@ public class TestIntegrationWithAutoInvoiceOffTag extends TestIntegrationBase {
     @BeforeMethod(groups = {"slow"})
     public void setupOverdue() throws Exception {
         
-        account = accountUserApi.createAccount(getAccountData(25), null, null, context);
+        account = createAccountWithPaymentMethod(getAccountData(25));
         assertNotNull(account);
 
         bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
index fe6f8a8..4000606 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
@@ -71,8 +71,7 @@ public class TestRepairIntegration extends TestIntegrationBase {
         DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
         
-        Account account = accountUserApi.createAccount(getAccountData(25), null, null, context);
-        assertNotNull(account);
+        Account account = createAccountWithPaymentMethod(getAccountData(25));
 
         SubscriptionBundle bundle = entitlementUserApi.createBundleForAccount(account.getId(), "whatever", context);
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
new file mode 100644
index 0000000..b9a554f
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentMethodJson.java
@@ -0,0 +1,180 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning licenses this file to you under the Apache License, version 2.0
+ * (the "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at:
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+package com.ning.billing.jaxrs.json;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.ning.billing.payment.api.PaymentMethod;
+import com.ning.billing.payment.api.PaymentMethodPlugin;
+
+public class PaymentMethodJson {
+
+    private final String paymentMethodId;
+    private final String accountId;
+    private final Boolean isActive;
+    private final String pluginName;
+    private final PaymentMethodPluginDetailJson pluginInfo;
+
+    @JsonCreator
+    public PaymentMethodJson(@JsonProperty("paymentMethodId") String paymentMethodId,
+            @JsonProperty("accountId") String accountId,
+            @JsonProperty("isActive") Boolean isActive,
+            @JsonProperty("pluginName") String pluginName,
+            @JsonProperty("pluginInfo") PaymentMethodPluginDetailJson pluginInfo) {
+        super();
+        this.paymentMethodId = paymentMethodId;
+        this.accountId = accountId;
+        this.isActive = isActive;
+        this.pluginName = pluginName;
+        this.pluginInfo = pluginInfo;
+    }
+
+    public PaymentMethod toPaymentMethod() {
+        return new PaymentMethod() {
+            @Override
+            public Boolean isActive() {
+                return isActive;
+            }
+            @Override
+            public String getPluginName() {
+                return pluginName;
+            }
+            @Override
+            public UUID getId() {
+                return UUID.fromString(paymentMethodId);
+            }
+            @Override
+            public UUID getAccountId() {
+                return UUID.fromString(accountId);
+            }
+            @Override
+            public PaymentMethodPlugin getPluginDetail() {
+                return new PaymentMethodPlugin() {
+                    @Override
+                    public boolean isDefaultPaymentMethod() {
+                        // N/A
+                        return false;
+                    }
+                    @Override
+                    public String getValueString(String key) {
+                        // N/A
+                        return null;
+                    }
+                    @Override
+                    public String getExternalPaymentMethodId() {
+                        return pluginInfo.getExternalPaymentId();
+                    }
+                    @Override
+                    public List<PaymentMethodKVInfo> getProperties() {
+                        List<PaymentMethodKVInfo> result = new LinkedList<PaymentMethodPlugin.PaymentMethodKVInfo>();
+                        for (PaymentMethodProperties cur : pluginInfo.getProperties()) {
+                            result.add(new PaymentMethodKVInfo(cur.getKey(), cur.getValue(), cur.isUpdatable));
+                        }
+                        return null;
+                    }
+                };
+            }
+        };
+    }
+
+    public PaymentMethodJson() {
+        this(null, null, null, null, null);
+    }
+
+    public String getPaymentMethodId() {
+        return paymentMethodId;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public Boolean getIsActive() {
+        return isActive;
+    }
+
+    public String getPluginName() {
+        return pluginName;
+    }
+
+    public PaymentMethodPluginDetailJson getPluginInfo() {
+        return pluginInfo;
+    }
+
+    public static class PaymentMethodPluginDetailJson {
+
+        private final String externalPaymentId;
+        private final List<PaymentMethodProperties> properties;
+
+
+        @JsonCreator
+        public PaymentMethodPluginDetailJson(@JsonProperty("externalPaymentId") String externalPaymentId,
+                @JsonProperty("properties") List<PaymentMethodProperties> properties) {
+            super();
+            this.externalPaymentId = externalPaymentId;
+            this.properties = properties;
+        }
+
+        public PaymentMethodPluginDetailJson() {
+            this(null, null);
+        }
+
+        public String getExternalPaymentId() {
+            return externalPaymentId;
+        }
+
+        public List<PaymentMethodProperties> getProperties() {
+            return properties;
+        }
+    }
+    
+    public final static class PaymentMethodProperties {
+        private final String key;
+        private final String value;
+        private final Boolean isUpdatable;
+
+        @JsonCreator
+        public PaymentMethodProperties(@JsonProperty("key") String key,
+                @JsonProperty("value") String value,
+                @JsonProperty("isUpdatable") Boolean isUpdatable) {
+            super();
+            this.key = key;
+            this.value = value;
+            this.isUpdatable = isUpdatable;
+        }
+
+        public PaymentMethodProperties() {
+            this(null, null, null);
+        }
+
+
+        public String getKey() {
+            return key;
+        }
+
+        public String getValue() {
+            return value;
+        }
+
+        public Boolean getIsUpdatable() {
+            return isUpdatable;
+        }
+    }
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index a362d99..bdd3e58 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -41,6 +41,8 @@ import javax.ws.rs.core.Response.Status;
 
 import com.ning.billing.util.api.CustomFieldUserApi;
 import com.ning.billing.util.dao.ObjectType;
+
+import org.skife.config.Default;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -65,6 +67,7 @@ import com.ning.billing.jaxrs.json.AccountTimelineJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
 import com.ning.billing.jaxrs.json.PaymentJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentMethodJson;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.jaxrs.util.TagHelper;
@@ -73,6 +76,7 @@ import com.ning.billing.payment.api.Payment;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.payment.api.PaymentMethod;
 import com.ning.billing.util.api.TagDefinitionApiException;
 
 import com.ning.billing.util.api.TagUserApi;
@@ -284,7 +288,55 @@ public class AccountResource extends JaxRsResourceBase {
             return Response.status(Status.NOT_FOUND).build();     
         }
     }
+    
+    @POST
+    @Path("/{accountId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENT_METHODS)
+    @Consumes(APPLICATION_JSON)
+    @Produces(APPLICATION_JSON)
+    public Response createPaymentMethod(final PaymentMethodJson json,
+            @QueryParam(QUERY_PAYMENT_METHOD_IS_DEFAULT) @DefaultValue("false") final Boolean isDefault,
+            @HeaderParam(HDR_CREATED_BY) final String createdBy,
+            @HeaderParam(HDR_REASON) final String reason,
+            @HeaderParam(HDR_COMMENT) final String comment) {
 
+        try {
+            PaymentMethod data = json.toPaymentMethod();
+            Account account = accountApi.getAccountById(data.getAccountId());
+            
+            // STEPH we might want an API to retrieve a single PaymentMethod based on ID
+            /* UUID paymentMethodId = */ paymentApi.addPaymentMethod(data.getPluginName(), account, isDefault, data.getPluginDetail(), context.createContext(createdBy, reason, comment));
+            return uriBuilder.buildResponse(AccountResource.class, "getPaymentMethods", account.getId());
+        } catch (AccountApiException e) {
+            final String error = String.format("Failed to create account %s", json);
+            log.info(error, e);
+            return Response.status(Status.BAD_REQUEST).entity(error).build();
+        } catch (PaymentApiException e) {
+            final String error = String.format("Failed to create payment Method  %s", json);
+            log.info(error, e);
+            return Response.status(Status.BAD_REQUEST).entity(error).build();
+        } catch (IllegalArgumentException e) {
+            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+        }
+    }
+    
+
+    @GET
+    @Path("/{accountId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENT_METHODS)
+    @Produces(APPLICATION_JSON)
+    public Response getPaymentMethods(@PathParam("accountId") String accountId,
+            @QueryParam(QUERY_PAYMENT_METHOD_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+            @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
+            @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
+        try {
+            Account account = accountApi.getAccountById(UUID.fromString(accountId));
+            List<PaymentMethod> methods = paymentApi.getPaymentMethods(account, withPluginInfo);
+            return Response.status(Status.OK).entity(methods).build();
+        } catch (PaymentApiException e) {
+            return Response.status(Status.NOT_FOUND).build();
+        } catch (AccountApiException e) {
+            return Response.status(Status.NOT_FOUND).build();            
+        }
+    }
     
     /****************************      TAGS     ******************************/
     @GET
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index b9be27c..2b4d6a9 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -58,6 +58,12 @@ public interface JaxrsResource {
 	public static final String QUERY_TAGS = "tag_list";    
 	public static final String QUERY_CUSTOM_FIELDS = "custom_field_list";    	
 	
+	public static final String QUERY_PAYMENT_METHOD_PLUGIN_INFO = "plugin_info";
+	public static final String QUERY_PAYMENT_METHOD_IS_DEFAULT = "is_default";
+	
+	
+	
+	
 	public static final String ACCOUNTS = "accounts";  
     public static final String ACCOUNTS_PATH = PREFIX + "/" + ACCOUNTS;
 
@@ -76,6 +82,8 @@ public interface JaxrsResource {
     public static final String PAYMENTS = "payments";     
     public static final String PAYMENTS_PATH = PREFIX + "/" + PAYMENTS;    
 
+    public static final String PAYMENT_METHODS = "paymentMethods";     
+    
     public static final String CREDITS = "credits";
     public static final String CREDITS_PATH = PREFIX + "/" + CREDITS;
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index d75b15c..324adbd 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -71,7 +71,7 @@ public class TestAccount extends TestJaxrsBase {
 		
 		// Update Account
 		AccountJson newInput = new AccountJson(objFromJson.getAccountId(),
-				"zozo", 4, objFromJson.getExternalKey(), "rr@google.com", 18, "EUR", "none", "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
+				"zozo", 4, objFromJson.getExternalKey(), "rr@google.com", 18, "EUR", null, "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
 		baseJson = mapper.writeValueAsString(newInput);
 		final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + objFromJson.getAccountId();
 		response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -114,7 +114,7 @@ public class TestAccount extends TestJaxrsBase {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
         
         
-	    AccountJson accountJson = createAccount("poney", "shdddqgfhwe", "poney@yahoo.com");
+	    AccountJson accountJson = createAccountWithDefaultPaymentMethod("poney", "shdddqgfhwe", "poney@yahoo.com");
 	    assertNotNull(accountJson);
 	    
 	    BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "996599");
@@ -152,7 +152,7 @@ public class TestAccount extends TestJaxrsBase {
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
 
-        AccountJson accountJson = createAccount("ermenehildo", "shtyrgfhwe", "ermenehildo@yahoo.com");
+        AccountJson accountJson = createAccountWithDefaultPaymentMethod("ermenehildo", "shtyrgfhwe", "ermenehildo@yahoo.com");
         assertNotNull(accountJson);
 
         BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "396199");
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index d42b3cc..5636796 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -133,7 +133,7 @@ public class TestInvoice extends TestJaxrsBase  {
 
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        AccountJson accountJson = createAccount("nohup", "shtergyhwF", "nohup@yahoo.com");
+        AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
         assertNotNull(accountJson);
 
         BundleJsonNoSubscriptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
@@ -185,7 +185,7 @@ public class TestInvoice extends TestJaxrsBase  {
 
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
 
-        AccountJson accountJson = createAccount("nohup", "shtergyhwF", "nohup@yahoo.com");
+        AccountJson accountJson = createAccountWithDefaultPaymentMethod("nohup", "shtergyhwF", "nohup@yahoo.com");
         assertNotNull(accountJson);
 
 
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index ee4cd87..112ce5e 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -20,6 +20,7 @@ import static org.testng.Assert.assertNotNull;
 import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.EventListener;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -49,6 +50,7 @@ import org.testng.annotations.BeforeSuite;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.datatype.joda.JodaModule;
+import com.google.common.collect.Lists;
 import com.google.inject.Module;
 import com.ning.billing.account.glue.AccountModule;
 import com.ning.billing.analytics.setup.AnalyticsModule;
@@ -65,6 +67,9 @@ import com.ning.billing.entitlement.glue.DefaultEntitlementModule;
 import com.ning.billing.invoice.glue.DefaultInvoiceModule;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubscriptions;
+import com.ning.billing.jaxrs.json.PaymentMethodJson;
+import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodPluginDetailJson;
+import com.ning.billing.jaxrs.json.PaymentMethodJson.PaymentMethodProperties;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.junction.glue.DefaultJunctionModule;
 import com.ning.billing.payment.glue.PaymentModule;
@@ -90,6 +95,7 @@ public class TestJaxrsBase {
 
     private final static String PLUGIN_NAME = "noop";
 
+    // STEPH
     protected static final int DEFAULT_HTTP_TIMEOUT_SEC =  500000; // 5;
 
     protected static final Map<String, String> DEFAULT_EMPTY_QUERY = new HashMap<String, String>();
@@ -307,7 +313,39 @@ public class TestJaxrsBase {
         }
     }
 
+    private PaymentMethodJson getPaymentJson(String accountId) {
+        
+        PaymentMethodProperties properties = new PaymentMethodProperties("whatever", "zero", false);
+        PaymentMethodPluginDetailJson info = new PaymentMethodPluginDetailJson(null, Collections.singletonList(properties));
+        return new PaymentMethodJson(null, accountId, true, PLUGIN_NAME, info);
+    }
+    
+    protected AccountJson createAccountWithDefaultPaymentMethod(String name, String key, String email) throws Exception {
+        
+        AccountJson input = createAccount(name, key, email);
+        
+        final String uri = JaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId() + "/" + JaxrsResource.PAYMENT_METHODS;
+        PaymentMethodJson paymentMethodJson = getPaymentJson(input.getAccountId());
+        String baseJson = mapper.writeValueAsString(paymentMethodJson);
+        Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_PAYMENT_METHOD_IS_DEFAULT, "true");
+        
+        Response response = doPost(uri, baseJson, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
 
+        
+        
+        queryParams = new HashMap<String, String>();
+        queryParams.put(JaxrsResource.QUERY_EXTERNAL_KEY, input.getExternalKey());
+        response = doGet(JaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        baseJson = response.getResponseBody();
+        AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertNotNull(objFromJson);
+        Assert.assertNotNull(objFromJson.getPaymentMethodId());
+        return objFromJson;
+    }
+    
     protected AccountJson createAccount(String name, String key, String email) throws Exception {
         AccountJson input = getAccountJson(name, key, email);
         String baseJson = mapper.writeValueAsString(input);
@@ -471,7 +509,6 @@ public class TestJaxrsBase {
         int length = 4;
         int billCycleDay = 12;
         String currency = "USD";
-        String paymentProvider = "noop";
         String timeZone = "UTC";
         String address1 = "12 rue des ecoles";
         String address2 = "Poitier";
@@ -480,7 +517,7 @@ public class TestJaxrsBase {
         String country = "France";
         String phone = "81 53 26 56";
 
-        AccountJson accountJson = new AccountJson(accountId, name, length, externalKey, email, billCycleDay, currency, paymentProvider, timeZone, address1, address2, company, state, country, phone);
+        AccountJson accountJson = new AccountJson(accountId, name, length, externalKey, email, billCycleDay, currency, null, timeZone, address1, address2, company, state, country, phone);
         return accountJson;
     }