killbill-memoizeit

Details

diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
index 3b160d5..7117692 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentMethodJson.java
@@ -104,7 +104,7 @@ public class PaymentMethodJson extends JsonBase {
 
             @Override
             public String getExternalKey() {
-                return null;
+                return externalKey;
             }
 
             @Override
@@ -177,6 +177,10 @@ public class PaymentMethodJson extends JsonBase {
         return pluginInfo;
     }
 
+    public String getExternalKey() {
+        return externalKey;
+    }
+
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder("PaymentMethodJson{");
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 3effcae..e8d386a 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
@@ -101,6 +101,23 @@ public class PaymentMethodResource extends JaxRsResourceBase {
     }
 
     @GET
+    @Produces(APPLICATION_JSON)
+    public Response getPaymentMethodByKey(@QueryParam(QUERY_EXTERNAL_KEY) final String externalKey,
+                                          @QueryParam(QUERY_PLUGIN_PROPERTY) final List<String> pluginPropertiesString,
+                                          @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
+                                          @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+                                          @javax.ws.rs.core.Context final HttpServletRequest request) throws AccountApiException, PaymentApiException {
+        final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
+        final TenantContext tenantContext = context.createContext(request);
+
+        final PaymentMethod paymentMethod = paymentApi.getPaymentMethodByExternalKey(externalKey, 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);
+        return Response.status(Status.OK).entity(json).build();
+    }
+
+    @GET
     @Path("/" + PAGINATION)
     @Produces(APPLICATION_JSON)
     public Response getPaymentMethods(@QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset,
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java
index fe300c4..4f79e19 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultDirectPaymentApi.java
@@ -302,6 +302,12 @@ public class DefaultDirectPaymentApi implements DirectPaymentApi {
     }
 
     @Override
+    public PaymentMethod getPaymentMethodByExternalKey(String paymentMethodExternalKey, boolean includedInactive, boolean withPluginInfo, Iterable<PluginProperty> properties, TenantContext context)
+            throws PaymentApiException {
+        return paymentMethodProcessor.getPaymentMethodByExternalKey(paymentMethodExternalKey, includedInactive, withPluginInfo, properties, context, internalCallContextFactory.createInternalTenantContext(context));
+    }
+
+    @Override
     public Pagination<PaymentMethod> getPaymentMethods(final Long offset, final Long limit, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context) {
         return paymentMethodProcessor.getPaymentMethods(offset, limit, properties, context, internalCallContextFactory.createInternalTenantContext(context));
     }
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 2eddaf4..066c19e 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
@@ -104,7 +104,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                         pluginApi = getPaymentPluginApi(paymentPluginServiceName);
                         pm = new DefaultPaymentMethod(paymentMethodExternalKey, account.getId(), paymentPluginServiceName, paymentMethodProps);
                         pluginApi.addPaymentMethod(account.getId(), pm.getId(), paymentMethodProps, setDefault, properties, callContext);
-                        final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getCreatedDate(), pm.getUpdatedDate(),
+                        final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(pm.getId(), pm.getExternalKey(), pm.getCreatedDate(), pm.getUpdatedDate(),
                                                                                         pm.getAccountId(), pm.getPluginName(), pm.isActive());
                         paymentDao.insertPaymentMethod(pmModel, context);
 
@@ -153,6 +153,16 @@ public class PaymentMethodProcessor extends ProcessorBase {
         return buildDefaultPaymentMethod(paymentMethodModel, withPluginInfo, properties, tenantContext, context);
     }
 
+    public PaymentMethod getPaymentMethodByExternalKey(final String paymentMethodExternalKey, final boolean includedDeleted, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext context)
+            throws PaymentApiException {
+        final PaymentMethodModelDao paymentMethodModel = includedDeleted ? paymentDao.getPaymentMethodByExternalKeyIncludedDeleted(paymentMethodExternalKey, context) : paymentDao.getPaymentMethodByExternalKey(paymentMethodExternalKey, context);
+        if (paymentMethodModel == null) {
+            throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, paymentMethodExternalKey);
+        }
+        return buildDefaultPaymentMethod(paymentMethodModel, withPluginInfo, properties, tenantContext, context);
+    }
+
+
     private PaymentMethod buildDefaultPaymentMethod(final PaymentMethodModelDao paymentMethodModelDao, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext context) throws PaymentApiException {
         final PaymentMethodPlugin paymentMethodPlugin;
         if (withPluginInfo) {
@@ -424,7 +434,7 @@ public class PaymentMethodProcessor extends ProcessorBase {
                         // If the kbPaymentId is NULL, the plugin does not know about it, so we create a new UUID
                         final UUID paymentMethodId = cur.getPaymentMethodId() != null ? cur.getPaymentMethodId() : UUID.randomUUID();
                         final PaymentMethod input = new DefaultPaymentMethod(paymentMethodId, paymentMethodId.toString(), account.getId(), pluginName);
-                        final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(input.getId(), input.getCreatedDate(), input.getUpdatedDate(),
+                        final PaymentMethodModelDao pmModel = new PaymentMethodModelDao(input.getId(),  input.getExternalKey(), input.getCreatedDate(), input.getUpdatedDate(),
                                                                                         input.getAccountId(), input.getPluginName(), input.isActive());
                         finalPaymentMethods.add(pmModel);
 
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
index fa1d6a5..a7475b5 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/DefaultPaymentDao.java
@@ -312,6 +312,16 @@ public class DefaultPaymentDao implements PaymentDao {
     }
 
     @Override
+    public PaymentMethodModelDao getPaymentMethodByExternalKey(final String paymentMethodExternalKey, final InternalTenantContext context) {
+        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentMethodModelDao>() {
+            @Override
+            public PaymentMethodModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+                return entitySqlDaoWrapperFactory.become(PaymentMethodSqlDao.class).getByExternalKey(paymentMethodExternalKey, context);
+            }
+        });
+    }
+
+    @Override
     public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId, final InternalTenantContext context) {
         return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentMethodModelDao>() {
             @Override
@@ -322,6 +332,16 @@ public class DefaultPaymentDao implements PaymentDao {
     }
 
     @Override
+    public PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(final String paymentMethodExternalKey, final InternalTenantContext context) {
+        return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<PaymentMethodModelDao>() {
+            @Override
+            public PaymentMethodModelDao inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws Exception {
+                return entitySqlDaoWrapperFactory.become(PaymentMethodSqlDao.class).getPaymentMethodByExternalKeyIncludedDeleted(paymentMethodExternalKey, context);
+            }
+        });
+    }
+
+    @Override
     public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId, final InternalTenantContext context) {
         return transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<List<PaymentMethodModelDao>>() {
             @Override
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
index 6327b14..b1a2df6 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentDao.java
@@ -71,8 +71,12 @@ public interface PaymentDao {
 
     public PaymentMethodModelDao getPaymentMethod(UUID paymentMethodId, InternalTenantContext context);
 
+    public PaymentMethodModelDao getPaymentMethodByExternalKey(String paymentMethodExternalKey, InternalTenantContext context);
+
     public PaymentMethodModelDao getPaymentMethodIncludedDeleted(UUID paymentMethodId, InternalTenantContext context);
 
+    public PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(String paymentMethodExternalKey, InternalTenantContext context);
+
     public List<PaymentMethodModelDao> getPaymentMethods(UUID accountId, InternalTenantContext context);
 
     public Pagination<PaymentMethodModelDao> getPaymentMethods(String pluginName, Long offset, Long limit, InternalTenantContext context);
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodModelDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodModelDao.java
index 2fea339..5475e17 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodModelDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodModelDao.java
@@ -36,11 +36,11 @@ public class PaymentMethodModelDao extends EntityBase implements EntityModelDao<
 
     public PaymentMethodModelDao() { /* For the DAO mapper */ }
 
-    public PaymentMethodModelDao(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate,
+    public PaymentMethodModelDao(final UUID id, final String externalKey, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate,
                                  final UUID accountId, final String pluginName,
                                  final Boolean isActive) {
         super(id, createdDate, updatedDate);
-        this.externalKey = id.toString();
+        this.externalKey = externalKey;
         this.accountId = accountId;
         this.pluginName = pluginName;
         this.isActive = isActive;
diff --git a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
index 659d086..0db4703 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dao/PaymentMethodSqlDao.java
@@ -47,6 +47,12 @@ public interface PaymentMethodSqlDao extends EntitySqlDao<PaymentMethodModelDao,
                                       @BindBean final InternalCallContext context);
 
     @SqlQuery
+    PaymentMethodModelDao getByExternalKey(@Bind("externalKey") String paymentMethodExternalKey, @BindBean InternalTenantContext context);
+
+    @SqlQuery
+    PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(@Bind("externalKey") String paymentMethodExternalKey, @BindBean InternalTenantContext context);
+
+    @SqlQuery
     PaymentMethodModelDao getPaymentMethodIncludedDelete(@Bind("id") final String paymentMethodId,
                                                          @BindBean final InternalTenantContext context);
 
@@ -66,4 +72,5 @@ public interface PaymentMethodSqlDao extends EntitySqlDao<PaymentMethodModelDao,
     @SqlQuery
     public Long getCountByPluginName(@Bind("pluginName") final String pluginName,
                                      @BindBean final InternalTenantContext context);
+
 }
diff --git a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
index ddb5aa3..56d48c9 100644
--- a/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
+++ b/payment/src/main/resources/org/killbill/billing/payment/dao/PaymentMethodSqlDao.sql.stg
@@ -51,6 +51,23 @@ where  id = :id
 ;
 >>
 
+getByExternalKey() ::= <<
+select <allTableFields()>
+from <tableName()>
+where external_key = :externalKey
+and is_active = 1
+<AND_CHECK_TENANT()>
+;
+>>
+
+getPaymentMethodByExternalKeyIncludedDeleted() ::= <<
+select <allTableFields()>
+from <tableName()>
+where external_key = :externalKey
+<AND_CHECK_TENANT()>
+;
+>>
+
 getPaymentMethodIncludedDelete(accountId) ::= <<
 select <allTableFields()>
 from <tableName()>
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestDirectPaymentOperation.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestDirectPaymentOperation.java
index 4fd5d17..e0deb5b 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestDirectPaymentOperation.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestDirectPaymentOperation.java
@@ -116,7 +116,7 @@ public class TestDirectPaymentOperation extends PaymentTestSuiteNoDB {
                                                                   internalCallContext,
                                                                   callContext);
 
-        final PaymentMethodModelDao paymentMethodModelDao = new PaymentMethodModelDao(directPaymentStateContext.getPaymentMethodId(), clock.getUTCNow(), clock.getUTCNow(),
+        final PaymentMethodModelDao paymentMethodModelDao = new PaymentMethodModelDao(directPaymentStateContext.getPaymentMethodId(), UUID.randomUUID().toString(), clock.getUTCNow(), clock.getUTCNow(),
                                                                                       directPaymentStateContext.getAccount().getId(), MockPaymentProviderPlugin.PLUGIN_NAME, true);
         final PaymentDao paymentDao = Mockito.mock(PaymentDao.class);
         Mockito.when(paymentDao.getPaymentMethodIncludedDeleted(directPaymentStateContext.getPaymentMethodId(), internalCallContext)).thenReturn(paymentMethodModelDao);
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
index 52d05b7..98afc31 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/MockPaymentDao.java
@@ -264,6 +264,18 @@ public class MockPaymentDao implements PaymentDao {
     }
 
     @Override
+    public PaymentMethodModelDao getPaymentMethodByExternalKey(final String paymentMethodExternalKey, final InternalTenantContext context) {
+        synchronized (this) {
+            for (final PaymentMethodModelDao cur : paymentMethods) {
+                if (cur.getExternalKey().equals(paymentMethodExternalKey)) {
+                    return cur;
+                }
+            }
+            return null;
+        }
+    }
+
+    @Override
     public List<PaymentMethodModelDao> getPaymentMethods(final UUID accountId, final InternalTenantContext context) {
         synchronized (this) {
             final List<PaymentMethodModelDao> result = new ArrayList<PaymentMethodModelDao>();
@@ -304,4 +316,9 @@ public class MockPaymentDao implements PaymentDao {
     public PaymentMethodModelDao getPaymentMethodIncludedDeleted(final UUID paymentMethodId, final InternalTenantContext context) {
         return getPaymentMethod(paymentMethodId, context);
     }
+
+    @Override
+    public PaymentMethodModelDao getPaymentMethodByExternalKeyIncludedDeleted(final String paymentMethodExternalKey, final InternalTenantContext context) {
+        return getPaymentMethodByExternalKey(paymentMethodExternalKey, context);
+    }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
index 839e65a..19ec769 100644
--- a/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/org/killbill/billing/payment/dao/TestPaymentDao.java
@@ -207,7 +207,7 @@ public class TestPaymentDao extends PaymentTestSuiteWithEmbeddedDB {
         final String pluginName = "nobody";
         final Boolean isActive = Boolean.TRUE;
 
-        final PaymentMethodModelDao method = new PaymentMethodModelDao(paymentMethodId, null, null,
+        final PaymentMethodModelDao method = new PaymentMethodModelDao(paymentMethodId,UUID.randomUUID().toString(), null, null,
                                                                        accountId, pluginName, isActive);
 
         PaymentMethodModelDao savedMethod = paymentDao.insertPaymentMethod(method, internalCallContext);
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
index a7b8811..9f604ed 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/KillbillClient.java
@@ -88,16 +88,20 @@ public abstract class KillbillClient extends GuicyKillbillTestSuiteWithEmbeddedD
         return properties;
     }
 
+    protected Account createAccountWithDefaultPaymentMethod(final String externalkey) throws Exception {
+        return  createAccountWithDefaultPaymentMethod(externalkey, null);
+    }
+
     protected Account createAccountWithDefaultPaymentMethod() throws Exception {
-       return  createAccountWithDefaultPaymentMethod(null);
+        return  createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), null);
     }
 
-    protected Account createAccountWithDefaultPaymentMethod(@Nullable final List<PluginProperty> pmProperties) throws Exception {
+    protected Account createAccountWithDefaultPaymentMethod(final String externalkey, @Nullable final List<PluginProperty> pmProperties) throws Exception {
         final Account input = createAccount();
 
         final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
         info.setProperties(pmProperties);
-        final PaymentMethod paymentMethodJson = new PaymentMethod(null, input.getAccountId(), true, PLUGIN_NAME, info);
+        final PaymentMethod paymentMethodJson = new PaymentMethod(null, externalkey, input.getAccountId(), true, PLUGIN_NAME, info);
         killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
         return killBillClient.getAccount(input.getExternalKey());
     }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
index a74903e..294eec9 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestAccount.java
@@ -100,7 +100,7 @@ public class TestAccount extends TestJaxrsBase {
 
         final PaymentMethodPluginDetail info = new PaymentMethodPluginDetail();
         info.setProperties(getPaymentMethodCCProperties());
-        PaymentMethod paymentMethodJson = new PaymentMethod(null, accountJson.getAccountId(), true, PLUGIN_NAME, info);
+        PaymentMethod paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), accountJson.getAccountId(), true, PLUGIN_NAME, info);
         final PaymentMethod paymentMethodCC = killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
         assertTrue(paymentMethodCC.getIsDefault());
 
@@ -109,7 +109,7 @@ public class TestAccount extends TestJaxrsBase {
         //
         final PaymentMethodPluginDetail info2 = new PaymentMethodPluginDetail();
         info2.setProperties(getPaymentMethodPaypalProperties());
-        paymentMethodJson = new PaymentMethod(null, accountJson.getAccountId(), false, PLUGIN_NAME, info2);
+        paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), accountJson.getAccountId(), false, PLUGIN_NAME, info2);
         final PaymentMethod paymentMethodPP = killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
         assertFalse(paymentMethodPP.getIsDefault());
 
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
index 1ae8ec6..1c11ac8 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPayment.java
@@ -42,7 +42,7 @@ public class TestPayment extends TestJaxrsBase {
         final Account account = createAccountWithDefaultPaymentMethod();
         testCreateRetrievePayment(account, null, UUID.randomUUID().toString(), 1);
 
-        final PaymentMethod paymentMethodJson = new PaymentMethod(null, account.getAccountId(), false, PLUGIN_NAME, new PaymentMethodPluginDetail());
+        final PaymentMethod paymentMethodJson = new PaymentMethod(null, UUID.randomUUID().toString(), account.getAccountId(), false, PLUGIN_NAME, new PaymentMethodPluginDetail());
         final PaymentMethod nonDefaultPaymentMethod = killBillClient.createPaymentMethod(paymentMethodJson, createdBy, reason, comment);
         testCreateRetrievePayment(account, nonDefaultPaymentMethod.getPaymentMethodId(), UUID.randomUUID().toString(), 2);
     }
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java
index 4e6440e..8a21a30 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestPaymentMethod.java
@@ -31,6 +31,20 @@ import org.testng.annotations.Test;
 
 public class TestPaymentMethod extends TestJaxrsBase {
 
+    @Test(groups = "slow", description = "Create/retrieve by externalKey")
+    public void testGePaymentMethodsByKey() throws Exception {
+
+        final Account accountJson = createAccountWithDefaultPaymentMethod("foo");
+
+        final PaymentMethod paymentMethodJson1 = killBillClient.getPaymentMethodByKey("foo", true);
+
+        final PaymentMethod paymentMethodJson2 = killBillClient.getPaymentMethod(accountJson.getPaymentMethodId(), true);
+        Assert.assertEquals(paymentMethodJson1, paymentMethodJson2);
+
+        final PaymentMethod paymentMethodJson3 = killBillClient.getPaymentMethodByKey("doesnotexist", true);
+        Assert.assertNull(paymentMethodJson3);
+    }
+
     @Test(groups = "slow", description = "Can search payment methods")
     public void testSearchPaymentMethods() throws Exception {
         // Search random key
@@ -45,7 +59,7 @@ public class TestPaymentMethod extends TestJaxrsBase {
         pmProperties.add(new PluginProperty("CC_STATE", "CA", false));
         pmProperties.add(new PluginProperty("CC_COUNTRY", "Zimbawe", false));
 
-        final Account accountJson = createAccountWithDefaultPaymentMethod(pmProperties);
+        final Account accountJson = createAccountWithDefaultPaymentMethod(UUID.randomUUID().toString(), pmProperties);
         final PaymentMethod paymentMethodJson = killBillClient.getPaymentMethod(accountJson.getPaymentMethodId(), true);
 
         // Search random key again