killbill-memoizeit
Changes
beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java 5(+3 -2)
payment/src/main/java/com/ning/billing/payment/provider/DefaultPaymentProviderPluginRegistry.java 5(+3 -2)
payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java 152(+105 -47)
payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java 1(+1 -0)
Details
diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
index 8d107ef..9ba2976 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
@@ -167,9 +167,9 @@ public class BusinessAccountRecorder {
// Retrieve invoices information
final List<Invoice> invoices = invoiceUserApi.getInvoicesByAccount(account.getId());
if (invoices != null && invoices.size() > 0) {
- final List<String> invoiceIds = new ArrayList<String>();
+ final List<UUID> invoiceIds = new ArrayList<UUID>();
for (final Invoice invoice : invoices) {
- invoiceIds.add(invoice.getId().toString());
+ invoiceIds.add(invoice.getId());
totalInvoiceBalance = totalInvoiceBalance.add(invoice.getBalance());
if (lastInvoiceDate == null || invoice.getInvoiceDate().isAfter(lastInvoiceDate)) {
diff --git a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
index b567464..dac4a3a 100644
--- a/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
+++ b/analytics/src/test/java/com/ning/billing/analytics/api/TestAnalyticsService.java
@@ -83,6 +83,7 @@ import com.ning.billing.mock.BrainDeadProxyFactory;
import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.api.PaymentInfoEvent;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.util.bus.Bus;
@@ -280,8 +281,8 @@ public class TestAnalyticsService {
paymentInfoNotification = new DefaultPaymentInfoEvent.Builder().setPaymentId(UUID.randomUUID().toString()).setPaymentMethod(PAYMENT_METHOD).setCardCountry(CARD_COUNTRY).build();
final PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice.getId(), account.getId(), BigDecimal.TEN,
- ACCOUNT_CURRENCY, clock.getUTCNow(), clock.getUTCNow(), paymentInfoNotification.getPaymentId(), 1);
- paymentDao.createPaymentAttempt(paymentAttempt, context);
+ ACCOUNT_CURRENCY, clock.getUTCNow(), clock.getUTCNow(), paymentInfoNotification.getPaymentId(), 1, PaymentAttemptStatus.COMPLETED_SUCCESS);
+ paymentDao.createPaymentAttempt(paymentAttempt, PaymentAttemptStatus.COMPLETED_SUCCESS, context);
paymentDao.savePaymentInfo(paymentInfoNotification, context);
Assert.assertEquals(paymentDao.getPaymentInfo(Arrays.asList(invoice.getId().toString())).size(), 1);
}
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
index c7b5965..00496d2 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApi.java
@@ -44,16 +44,16 @@ public interface PaymentApi {
public void deletePaymentMethod(final String accountKey, final String paymentMethodId, final CallContext context)
throws PaymentApiException;
- public List<PaymentInfoEvent> createPayment(final String accountKey, final List<String> invoiceIds, final CallContext context)
+ public PaymentInfoEvent createPayment(final String accountKey, final UUID invoiceId, final CallContext context)
throws PaymentApiException;
- public List<PaymentInfoEvent> createPayment(final Account account, final List<String> invoiceIds, final CallContext context)
+ public PaymentInfoEvent createPayment(final Account account, final UUID invoiceId, final CallContext context)
throws PaymentApiException;
- public PaymentInfoEvent createPaymentForPaymentAttempt(final UUID paymentAttemptId, final CallContext context)
+ public PaymentInfoEvent createPaymentForPaymentAttempt(final String accountKey, final UUID paymentAttemptId, final CallContext context)
throws PaymentApiException;
- public List<PaymentInfoEvent> createRefund(final Account account, final List<String> invoiceIds, final CallContext context)
+ public PaymentInfoEvent createRefund(final Account account, final UUID paymentId, final CallContext context)
throws PaymentApiException;
public PaymentProviderAccount getPaymentProviderAccount(final String accountKey)
@@ -68,7 +68,7 @@ public interface PaymentApi {
public PaymentAttempt getPaymentAttemptForPaymentId(final String id)
throws PaymentApiException;
- public List<PaymentInfoEvent> getPaymentInfo(final List<String> invoiceIds)
+ public List<PaymentInfoEvent> getPaymentInfo(final List<UUID> invoiceIds)
throws PaymentApiException;
public List<PaymentAttempt> getPaymentAttemptsForInvoiceId(final String invoiceId)
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java b/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java
index ff81b16..90a843f 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentApiException.java
@@ -19,6 +19,7 @@ import com.ning.billing.BillingExceptionBase;
import com.ning.billing.ErrorCode;
import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.catalog.api.CatalogApiException;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
public class PaymentApiException extends BillingExceptionBase {
@@ -29,12 +30,6 @@ public class PaymentApiException extends BillingExceptionBase {
super(e, e.getCode(), e.getMessage());
}
- /*
- public PaymentApiException(CatalogApiException e) {
- super(e, e.getCode(), e.getMessage());
- }
- */
-
public PaymentApiException(Throwable e, ErrorCode code, Object...args) {
super(e, code, args);
}
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java b/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java
index 15ac4ee..54c8ba7 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentAttempt.java
@@ -38,6 +38,7 @@ public class PaymentAttempt {
private final Integer retryCount;
private final DateTime createdDate;
private final DateTime updatedDate;
+ private final PaymentAttemptStatus paymentAttemptStatus;
public PaymentAttempt(UUID paymentAttemptId,
UUID invoiceId,
@@ -48,6 +49,7 @@ public class PaymentAttempt {
DateTime paymentAttemptDate,
String paymentId,
Integer retryCount,
+ PaymentAttemptStatus paymentAttemptStatus,
DateTime createdDate,
DateTime updatedDate) {
this.paymentAttemptId = paymentAttemptId;
@@ -59,6 +61,7 @@ public class PaymentAttempt {
this.paymentAttemptDate = paymentAttemptDate == null ? new DateTime(DateTimeZone.UTC) : paymentAttemptDate;
this.paymentId = paymentId;
this.retryCount = retryCount == null ? 0 : retryCount;
+ this.paymentAttemptStatus = paymentAttemptStatus;
this.createdDate = createdDate;
this.updatedDate = updatedDate;
}
@@ -71,7 +74,8 @@ public class PaymentAttempt {
DateTime invoiceDate,
DateTime paymentAttemptDate,
String paymentId,
- Integer retryCount) {
+ Integer retryCount,
+ PaymentAttemptStatus paymentAttemptStatus) {
this(paymentAttemptId,
invoiceId,
accountId,
@@ -81,10 +85,12 @@ public class PaymentAttempt {
paymentAttemptDate,
paymentId,
retryCount,
+ paymentAttemptStatus,
null,
null);
}
+ /*
public PaymentAttempt(UUID paymentAttemptId, UUID invoiceId, UUID accountId, BigDecimal amount, Currency currency, DateTime invoiceDate, DateTime paymentAttemptDate) {
this(paymentAttemptId, invoiceId, accountId, amount, currency, invoiceDate, paymentAttemptDate, null, null);
}
@@ -93,8 +99,17 @@ public class PaymentAttempt {
this(paymentAttemptId, invoiceId, accountId, null, null, invoiceDate, paymentAttemptDate, null, null);
}
- public PaymentAttempt(UUID paymentAttemptId, Invoice invoice) {
- this(paymentAttemptId, invoice.getId(), invoice.getAccountId(), invoice.getBalance(), invoice.getCurrency(), invoice.getInvoiceDate(), null, null, null);
+*/
+ public PaymentAttempt(UUID paymentAttemptId, Invoice invoice, PaymentAttemptStatus paymentAttemptStatus) {
+ this(paymentAttemptId, invoice.getId(), invoice.getAccountId(), invoice.getBalance(), invoice.getCurrency(), invoice.getInvoiceDate(), null, null, null, paymentAttemptStatus);
+ }
+
+ public enum PaymentAttemptStatus {
+ IN_PROCESSING,
+ COMPLETED_SUCCESS,
+ COMPLETED_FAILED,
+ COMPLETED_ABORTED,
+ PENDING
}
public DateTime getInvoiceDate() {
@@ -140,10 +155,15 @@ public class PaymentAttempt {
public Integer getRetryCount() {
return retryCount;
}
+
+ public PaymentAttemptStatus getPaymentAttemptStatus() {
+ return paymentAttemptStatus;
+ }
@Override
public String toString() {
- return "PaymentAttempt [paymentAttemptId=" + paymentAttemptId + ", invoiceId=" + invoiceId + ", accountId=" + accountId + ", amount=" + amount + ", currency=" + currency + ", paymentId=" + paymentId + ", invoiceDate=" + invoiceDate + ", paymentAttemptDate=" + paymentAttemptDate + ", retryCount=" + retryCount + ", createdDate=" + createdDate + ", updatedDate=" + updatedDate + "]";
+ return "PaymentAttempt [paymentAttemptId=" + paymentAttemptId + ", invoiceId=" + invoiceId + ", accountId=" + accountId + ", amount=" + amount + ", currency=" + currency + ", paymentId=" + paymentId + ", invoiceDate=" + invoiceDate + ", paymentAttemptDate=" + paymentAttemptDate +
+ ", retryCount=" + retryCount + ", createdDate=" + createdDate + ", updatedDate=" + updatedDate + "]";
}
public Builder cloner() {
@@ -162,7 +182,8 @@ public class PaymentAttempt {
private Integer retryCount;
private DateTime createdDate;
private DateTime updatedDate;
-
+ private PaymentAttemptStatus paymentAttemptStatus;
+
public Builder() {
}
@@ -176,6 +197,7 @@ public class PaymentAttempt {
this.paymentAttemptDate = src.paymentAttemptDate;
this.paymentId = src.paymentId;
this.retryCount = src.retryCount;
+ this.paymentAttemptStatus = paymentAttemptStatus;
this.createdDate = src.createdDate;
this.updatedDate = src.updatedDate;
}
@@ -235,6 +257,11 @@ public class PaymentAttempt {
return this;
}
+ public Builder setPaymentAttemptStatus(PaymentAttemptStatus status) {
+ this.paymentAttemptStatus = paymentAttemptStatus;
+ return this;
+ }
+
public PaymentAttempt build() {
return new PaymentAttempt(paymentAttemptId,
invoiceId,
@@ -245,6 +272,7 @@ public class PaymentAttempt {
paymentAttemptDate,
paymentId,
retryCount,
+ paymentAttemptStatus,
createdDate,
updatedDate);
}
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java b/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java
index a93b3bb..5883275 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentInfoEvent.java
@@ -16,12 +16,18 @@
package com.ning.billing.payment.api;
import java.math.BigDecimal;
+import java.util.UUID;
+
import org.joda.time.DateTime;
import com.ning.billing.util.bus.BusEvent;
public interface PaymentInfoEvent extends BusEvent {
+ public UUID getInvoiceId();
+
+ public UUID getAccountId();
+
public String getPaymentId();
public BigDecimal getAmount();
@@ -51,4 +57,5 @@ public interface PaymentInfoEvent extends BusEvent {
public String getType();
public DateTime getUpdatedDate();
+
}
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
new file mode 100644
index 0000000..482c2df
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentInfoPlugin.java
@@ -0,0 +1,53 @@
+/*
+ * 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.payment.plugin.api;
+
+import java.math.BigDecimal;
+
+import org.joda.time.DateTime;
+
+public interface PaymentInfoPlugin {
+
+ public String getPaymentId();
+
+ public BigDecimal getAmount();
+
+ public String getBankIdentificationNumber();
+
+ public DateTime getCreatedDate();
+
+ public DateTime getEffectiveDate();
+
+ public String getPaymentNumber();
+
+ public String getPaymentMethod();
+
+ public String getCardType();
+
+ public String getCardCountry();
+
+ public String getReferenceId();
+
+ public String getPaymentMethodId();
+
+ public BigDecimal getRefundAmount();
+
+ public String getStatus();
+
+ public String getType();
+
+ public DateTime getUpdatedDate();
+}
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java
new file mode 100644
index 0000000..5df657e
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentPluginApiException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.payment.plugin.api;
+
+public class PaymentPluginApiException extends Exception {
+
+ private static final long serialVersionUID = 15642965L;
+
+ private final String errorType;
+ private final String errorMessage;
+
+ public PaymentPluginApiException(final String errorType, final String errorMessage) {
+ this.errorMessage = errorMessage;
+ this.errorType = errorType;
+ }
+
+ public String getErrorType() {
+ return errorType;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+}
diff --git a/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java
new file mode 100644
index 0000000..93192b0
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/payment/plugin/api/PaymentProviderPlugin.java
@@ -0,0 +1,67 @@
+/*
+ * 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.payment.plugin.api;
+
+import java.util.List;
+
+import com.ning.billing.account.api.Account;
+import com.ning.billing.invoice.api.Invoice;
+import com.ning.billing.payment.api.PaymentMethodInfo;
+import com.ning.billing.payment.api.PaymentProviderAccount;
+
+public interface PaymentProviderPlugin {
+
+ public PaymentInfoPlugin processInvoice(Account account, Invoice invoice)
+ throws PaymentPluginApiException;
+
+ public String createPaymentProviderAccount(Account account)
+ throws PaymentPluginApiException;
+
+ public PaymentInfoPlugin getPaymentInfo(String paymentId)
+ throws PaymentPluginApiException;
+
+ public PaymentProviderAccount getPaymentProviderAccount(String accountKey)
+ throws PaymentPluginApiException;
+
+ public void updatePaymentGateway(String accountKey)
+ throws PaymentPluginApiException;
+
+ public PaymentMethodInfo getPaymentMethodInfo(String paymentMethodId)
+ throws PaymentPluginApiException;
+
+ public List<PaymentMethodInfo> getPaymentMethods(String accountKey)
+ throws PaymentPluginApiException;
+
+ public String addPaymentMethod(String accountKey, PaymentMethodInfo paymentMethod)
+ throws PaymentPluginApiException;
+
+ public PaymentMethodInfo updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethodInfo)
+ throws PaymentPluginApiException;
+
+ public void deletePaymentMethod(String accountKey, String paymentMethodId)
+ throws PaymentPluginApiException;
+
+
+ public void updatePaymentProviderAccountExistingContact(Account account)
+ throws PaymentPluginApiException;
+
+ public void updatePaymentProviderAccountWithNewContact(Account account)
+ throws PaymentPluginApiException;
+
+ public List<PaymentInfoPlugin> processRefund(Account account)
+ throws PaymentPluginApiException;
+}
diff --git a/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java b/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
new file mode 100644
index 0000000..bd76f30
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/payment/provider/PaymentProviderPluginRegistry.java
@@ -0,0 +1,25 @@
+/*
+ * 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.payment.provider;
+
+import com.ning.billing.payment.plugin.api.PaymentProviderPlugin;
+
+public interface PaymentProviderPluginRegistry {
+
+ public void register(final PaymentProviderPlugin plugin, final String name);
+
+ public PaymentProviderPlugin getPlugin(final String name);
+}
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java
index d7febde..c2c7932 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/payment/TestNotifyInvoicePaymentApi.java
@@ -40,6 +40,7 @@ import com.ning.billing.mock.BrainDeadProxyFactory.ZombieControl;
import com.ning.billing.mock.glue.MockJunctionModule;
import com.ning.billing.payment.RequestProcessor;
import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.Bus.EventBusException;
@@ -85,7 +86,7 @@ public class TestNotifyInvoicePaymentApi {
final Account account = testHelper.createTestCreditCardAccount();
final Invoice invoice = testHelper.createTestInvoice(account);
- PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+ PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice, PaymentAttemptStatus.COMPLETED_SUCCESS);
invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
invoice.getBalance(),
@@ -104,7 +105,7 @@ public class TestNotifyInvoicePaymentApi {
final Account account = testHelper.createTestCreditCardAccount();
final Invoice invoice = testHelper.createTestInvoice(account);
- PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+ PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice, PaymentAttemptStatus.COMPLETED_SUCCESS);
invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
paymentAttempt.getPaymentAttemptId(),
paymentAttempt.getPaymentAttemptDate(),
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
index 2ac89d2..1333925 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentApi.java
@@ -18,13 +18,10 @@ package com.ning.billing.payment.api;
import java.math.BigDecimal;
import java.util.ArrayList;
-import java.util.LinkedList;
+
import java.util.List;
import java.util.UUID;
-import javax.annotation.Nullable;
-
-import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -37,285 +34,299 @@ import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.config.PaymentConfig;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.invoice.api.InvoicePaymentApi;
-import com.ning.billing.payment.RetryService;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.dao.PaymentDao;
-import com.ning.billing.payment.provider.PaymentProviderPlugin;
+
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
+import com.ning.billing.payment.plugin.api.PaymentProviderPlugin;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
+import com.ning.billing.payment.retry.FailedPaymentRetryService;
import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.globallocker.GlobalLock;
+import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.globallocker.LockFailedException;
+import com.ning.billing.util.globallocker.GlobalLocker.LockerService;
public class DefaultPaymentApi implements PaymentApi {
+
+ private final static int NB_LOCK_TRY = 5;
+
private final PaymentProviderPluginRegistry pluginRegistry;
private final AccountUserApi accountUserApi;
private final InvoicePaymentApi invoicePaymentApi;
- private final RetryService retryService;
+ private final FailedPaymentRetryService retryService;
private final PaymentDao paymentDao;
private final PaymentConfig config;
-
-
+ private final GlobalLocker locker;
+
private static final Logger log = LoggerFactory.getLogger(DefaultPaymentApi.class);
@Inject
- public DefaultPaymentApi(PaymentProviderPluginRegistry pluginRegistry,
- AccountUserApi accountUserApi,
- InvoicePaymentApi invoicePaymentApi,
- RetryService retryService,
- PaymentDao paymentDao,
- PaymentConfig config) {
+ public DefaultPaymentApi(final PaymentProviderPluginRegistry pluginRegistry,
+ final AccountUserApi accountUserApi,
+ final InvoicePaymentApi invoicePaymentApi,
+ final FailedPaymentRetryService retryService,
+ final PaymentDao paymentDao,
+ final PaymentConfig config,
+ final GlobalLocker locker) {
this.pluginRegistry = pluginRegistry;
this.accountUserApi = accountUserApi;
this.invoicePaymentApi = invoicePaymentApi;
this.retryService = retryService;
this.paymentDao = paymentDao;
this.config = config;
+ this.locker = locker;
}
@Override
public PaymentMethodInfo getPaymentMethod(final String accountKey, final String paymentMethodId)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, PaymentMethodInfo> result = plugin.getPaymentMethodInfo(paymentMethodId);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, accountKey, paymentMethodId);
- }
- return result.getRight();
- }
-
- private PaymentProviderPlugin getPaymentProviderPlugin(String accountKey) {
- String paymentProviderName = null;
-
- if (accountKey != null) {
- Account account;
- try {
- account = accountUserApi.getAccountByKey(accountKey);
- return getPaymentProviderPlugin(account);
- } catch (AccountApiException e) {
- log.error("Error getting payment provider plugin.", e);
- }
- }
-
- return pluginRegistry.getPlugin(paymentProviderName);
- }
-
- private PaymentProviderPlugin getPaymentProviderPlugin(Account account) {
- String paymentProviderName = null;
-
- if (account != null) {
- paymentProviderName = account.getPaymentProviderName();
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ return plugin.getPaymentMethodInfo(paymentMethodId);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_NO_SUCH_PAYMENT_METHOD, accountKey, paymentMethodId);
}
-
- return pluginRegistry.getPlugin(paymentProviderName);
}
@Override
public List<PaymentMethodInfo> getPaymentMethods(String accountKey)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, List<PaymentMethodInfo>> result = plugin.getPaymentMethods(accountKey);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_NO_PAYMENT_METHODS, accountKey);
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ return plugin.getPaymentMethods(accountKey);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_NO_PAYMENT_METHODS, accountKey);
}
- return result.getRight();
}
@Override
- public void updatePaymentGateway(String accountKey, CallContext context)
+ public void updatePaymentGateway(final String accountKey, final CallContext context)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, Void> result = plugin.updatePaymentGateway(accountKey);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_UPD_GATEWAY_FAILED, accountKey, result.getLeft().getMessage());
- }
- return;
+
+ new WithAccountLock<Void>().processAccountWithLock(locker, accountKey, new WithAccountLockCallback<Void>() {
+ @Override
+ public Void doOperation() throws PaymentApiException {
+
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ plugin.updatePaymentGateway(accountKey);
+ return null;
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_UPD_GATEWAY_FAILED, accountKey, e.getMessage());
+ }
+ }
+ });
}
@Override
public PaymentProviderAccount getPaymentProviderAccount(String accountKey)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, PaymentProviderAccount> result = plugin.getPaymentProviderAccount(accountKey);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_GET_PAYMENT_PROVIDER, accountKey, result.getLeft().getMessage());
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ return plugin.getPaymentProviderAccount(accountKey);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_GET_PAYMENT_PROVIDER, accountKey, e.getMessage());
}
- return result.getRight();
}
@Override
- public String addPaymentMethod(String accountKey, PaymentMethodInfo paymentMethod, CallContext context)
+ public String addPaymentMethod(final String accountKey, final PaymentMethodInfo paymentMethod, final CallContext context)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, String> result = plugin.addPaymentMethod(accountKey, paymentMethod);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, accountKey, result.getLeft().getMessage());
- }
- return result.getRight();
+
+ return new WithAccountLock<String>().processAccountWithLock(locker, accountKey, new WithAccountLockCallback<String>() {
+
+ @Override
+ public String doOperation() throws PaymentApiException {
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ return plugin.addPaymentMethod(accountKey, paymentMethod);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_ADD_PAYMENT_METHOD, accountKey, e.getMessage());
+ }
+ }
+ });
}
@Override
- public void deletePaymentMethod(String accountKey, String paymentMethodId, CallContext context)
+ public void deletePaymentMethod(final String accountKey, final String paymentMethodId, final CallContext context)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, Void> result = plugin.deletePaymentMethod(accountKey, paymentMethodId);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_DEL_PAYMENT_METHOD, accountKey, result.getLeft().getMessage());
- }
- return;
+
+ new WithAccountLock<Void>().processAccountWithLock(locker, accountKey, new WithAccountLockCallback<Void>() {
+
+ @Override
+ public Void doOperation() throws PaymentApiException {
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ plugin.deletePaymentMethod(accountKey, paymentMethodId);
+ return null;
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_DEL_PAYMENT_METHOD, accountKey, e.getMessage());
+ }
+ }
+ });
}
@Override
- public PaymentMethodInfo updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethodInfo, CallContext context)
+ public PaymentMethodInfo updatePaymentMethod(final String accountKey, final PaymentMethodInfo paymentMethodInfo, final CallContext context)
throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
- Either<PaymentErrorEvent, PaymentMethodInfo> result = plugin.updatePaymentMethod(accountKey, paymentMethodInfo);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_METHOD, accountKey, result.getLeft().getMessage());
- }
- return result.getRight();
+
+ return new WithAccountLock<PaymentMethodInfo>().processAccountWithLock(locker, accountKey, new WithAccountLockCallback<PaymentMethodInfo>() {
+
+ @Override
+ public PaymentMethodInfo doOperation() throws PaymentApiException {
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(accountKey);
+ return plugin.updatePaymentMethod(accountKey, paymentMethodInfo);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_UPD_PAYMENT_METHOD, accountKey, e.getMessage());
+ }
+ }
+ });
}
@Override
- public List<PaymentInfoEvent> createPayment(String accountKey, List<String> invoiceIds, CallContext context)
- throws PaymentApiException {
- try {
- final Account account = accountUserApi.getAccountByKey(accountKey);
- return createPayment(account, invoiceIds, context);
- } catch (AccountApiException e) {
- throw new PaymentApiException(e);
- }
+ public PaymentInfoEvent createPayment(final String accountKey, final UUID invoiceId, final CallContext context)
+ throws PaymentApiException {
+
+ return new WithAccountLock<PaymentInfoEvent>().processAccountWithLock(locker, accountKey, new WithAccountLockCallback<PaymentInfoEvent>() {
+
+ @Override
+ public PaymentInfoEvent doOperation() throws PaymentApiException {
+ try {
+ final Account account = accountUserApi.getAccountByKey(accountKey);
+ return createPayment(account, invoiceId, context);
+ } catch (AccountApiException e) {
+ throw new PaymentApiException(e);
+ }
+ }
+ });
}
@Override
- public PaymentInfoEvent createPaymentForPaymentAttempt(UUID paymentAttemptId, CallContext context)
+ public PaymentInfoEvent createPaymentForPaymentAttempt(final String accountKey, final UUID paymentAttemptId, final CallContext context)
throws PaymentApiException {
- PaymentAttempt paymentAttempt = paymentDao.getPaymentAttemptById(paymentAttemptId);
- if (paymentAttempt != null) {
- try {
- Invoice invoice = invoicePaymentApi.getInvoice(paymentAttempt.getInvoiceId());
- Account account = accountUserApi.getAccountById(paymentAttempt.getAccountId());
+ return new WithAccountLock<PaymentInfoEvent>().processAccountWithLock(locker, accountKey, new WithAccountLockCallback<PaymentInfoEvent>() {
+
+ @Override
+ public PaymentInfoEvent doOperation() throws PaymentApiException {
+ PaymentAttempt paymentAttempt = paymentDao.getPaymentAttemptById(paymentAttemptId);
+ try {
+
+ Invoice invoice = paymentAttempt != null ? invoicePaymentApi.getInvoice(paymentAttempt.getInvoiceId()) : null;
+ Account account = paymentAttempt != null ? accountUserApi.getAccountById(paymentAttempt.getAccountId()) : null;
+ if (invoice == null || account == null) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_BAD, paymentAttemptId);
+ }
- if (invoice != null && account != null) {
if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0 ) {
- // TODO: send a notification that invoice was ignored?
log.info("Received invoice for payment with outstanding amount of 0 {} ", invoice);
throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_WITH_NON_POSITIVE_INV, account.getId());
+ }
- } else {
-
+ try {
PaymentAttempt newPaymentAttempt = new PaymentAttempt.Builder(paymentAttempt)
.setRetryCount(paymentAttempt.getRetryCount() + 1)
.setPaymentAttemptId(UUID.randomUUID())
.build();
- paymentDao.createPaymentAttempt(newPaymentAttempt, context);
- Either<PaymentErrorEvent, PaymentInfoEvent> result = processPayment(getPaymentProviderPlugin(account), account, invoice, newPaymentAttempt, context);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT, account.getId(), paymentAttemptId, result.getLeft().getMessage());
- }
- return result.getRight();
+ paymentDao.createPaymentAttempt(newPaymentAttempt, PaymentAttemptStatus.IN_PROCESSING, context);
+ PaymentInfoEvent result = processPaymentWithAccountLocked(getPaymentProviderPlugin(account), account, invoice, newPaymentAttempt, context);
+ return result;
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT, account.getId(), paymentAttemptId, e.getMessage());
}
+ } catch (AccountApiException e) {
+ throw new PaymentApiException(e);
}
- } catch (AccountApiException e) {
- throw new PaymentApiException(e);
}
- }
- throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_FOR_ATTEMPT_BAD, paymentAttemptId);
+ });
}
@Override
- public List<PaymentInfoEvent> createPayment(Account account, List<String> invoiceIds, CallContext context)
- throws PaymentApiException {
-
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
+ public PaymentInfoEvent createPayment(final Account account, final UUID invoiceId, final CallContext context)
+ throws PaymentApiException {
- List<Either<PaymentErrorEvent, PaymentInfoEvent>> processedPaymentsOrErrors = new ArrayList<Either<PaymentErrorEvent, PaymentInfoEvent>>(invoiceIds.size());
+ return new WithAccountLock<PaymentInfoEvent>().processAccountWithLock(locker, account.getExternalKey(), new WithAccountLockCallback<PaymentInfoEvent>() {
- for (String invoiceId : invoiceIds) {
- Invoice invoice = invoicePaymentApi.getInvoice(UUID.fromString(invoiceId));
+ @Override
+ public PaymentInfoEvent doOperation()
+ throws PaymentApiException {
+
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
- if (invoice.getBalance().compareTo(BigDecimal.ZERO) <= 0 ) {
- log.debug("Received invoice for payment with balance of 0 {} ", invoice);
- }
- else if (invoice.isMigrationInvoice()) {
- log.info("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
- Either<PaymentErrorEvent, PaymentInfoEvent> result = Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("migration invoice",
- "Invoice balance was a migration invoice",
- account.getId(),
- UUID.fromString(invoiceId),
- context.getUserToken()));
- processedPaymentsOrErrors.add(result);
- }
- else {
- PaymentAttempt paymentAttempt = paymentDao.createPaymentAttempt(invoice, context);
- processedPaymentsOrErrors.add(processPayment(plugin, account, invoice, paymentAttempt, context));
- }
- }
- List<Either<PaymentErrorEvent, PaymentInfoEvent>> result = processedPaymentsOrErrors;
- List<PaymentInfoEvent> info = new LinkedList<PaymentInfoEvent>();
- for (Either<PaymentErrorEvent, PaymentInfoEvent> cur : result) {
- if (cur.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT, account.getId(), cur.getLeft().getMessage());
+ Invoice invoice = invoicePaymentApi.getInvoice(invoiceId);
+
+ if (invoice.isMigrationInvoice()) {
+ log.error("Received invoice for payment that is a migration invoice - don't know how to handle those yet: {}", invoice);
+ return null;
+ }
+
+ PaymentInfoEvent result = null;
+ if (invoice.getBalance().compareTo(BigDecimal.ZERO) > 0 ) {
+ // STEPH null
+ PaymentAttempt paymentAttempt = paymentDao.createPaymentAttempt(invoice, null, context);
+ result = processPaymentWithAccountLocked(plugin, account, invoice, paymentAttempt, context);
+ }
+
+ return result;
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(e, ErrorCode.PAYMENT_CREATE_PAYMENT, account.getId(), e.getMessage());
+ }
}
- info.add(cur.getRight());
- }
- return info;
+ });
}
- private Either<PaymentErrorEvent, PaymentInfoEvent> processPayment(PaymentProviderPlugin plugin, Account account, Invoice invoice,
- PaymentAttempt paymentAttempt, CallContext context) {
- Either<PaymentErrorEvent, PaymentInfoEvent> paymentOrError = plugin.processInvoice(account, invoice);
- PaymentInfoEvent paymentInfo = null;
- if (paymentOrError.isLeft()) {
- String error = StringUtils.substring(paymentOrError.getLeft().getMessage() + paymentOrError.getLeft().getBusEventType(), 0, 100);
- log.info("Could not process a payment for " + paymentAttempt + " error was " + error);
+ private PaymentInfoEvent processPaymentWithAccountLocked(PaymentProviderPlugin plugin, Account account, Invoice invoice,
+ PaymentAttempt paymentAttempt, CallContext context) throws PaymentPluginApiException {
- scheduleRetry(paymentAttempt, error);
+ PaymentInfoEvent paymentInfo = null;
+ try {
+ paymentInfo = new DefaultPaymentInfoEvent(plugin.processInvoice(account, invoice), account.getId(), invoice.getId());
+ } catch (PaymentPluginApiException e) {
+ log.info("Could not process a payment for " + paymentAttempt + ", error was " + e.getMessage());
+ scheduleRetry(paymentAttempt);
+ throw e;
}
- else {
- paymentInfo = paymentOrError.getRight();
- paymentDao.savePaymentInfo(paymentInfo, context);
- final String paymentMethodId = paymentInfo.getPaymentMethodId();
- log.debug("Fetching payment method info for payment method id " + ((paymentMethodId == null) ? "null" : paymentMethodId));
- Either<PaymentErrorEvent, PaymentMethodInfo> paymentMethodInfoOrError = plugin.getPaymentMethodInfo(paymentMethodId);
+ paymentDao.savePaymentInfo(paymentInfo, context);
- if (paymentMethodInfoOrError.isRight()) {
- PaymentMethodInfo paymentMethodInfo = paymentMethodInfoOrError.getRight();
+ final String paymentMethodId = paymentInfo.getPaymentMethodId();
+ log.debug("Fetching payment method info for payment method id " + ((paymentMethodId == null) ? "null" : paymentMethodId));
+ PaymentMethodInfo paymentMethodInfo = plugin.getPaymentMethodInfo(paymentMethodId);
- if (paymentMethodInfo instanceof CreditCardPaymentMethodInfo) {
- CreditCardPaymentMethodInfo ccPaymentMethod = (CreditCardPaymentMethodInfo)paymentMethodInfo;
- paymentDao.updatePaymentInfo(ccPaymentMethod.getType(), paymentInfo.getPaymentId(), ccPaymentMethod.getCardType(), ccPaymentMethod.getCardCountry(), context);
- }
- else if (paymentMethodInfo instanceof PaypalPaymentMethodInfo) {
- PaypalPaymentMethodInfo paypalPaymentMethodInfo = (PaypalPaymentMethodInfo)paymentMethodInfo;
- paymentDao.updatePaymentInfo(paypalPaymentMethodInfo.getType(), paymentInfo.getPaymentId(), null, null, context);
- }
- } else {
- log.info(paymentMethodInfoOrError.getLeft().getMessage());
- }
+ if (paymentMethodInfo instanceof CreditCardPaymentMethodInfo) {
+ CreditCardPaymentMethodInfo ccPaymentMethod = (CreditCardPaymentMethodInfo)paymentMethodInfo;
+ paymentDao.updatePaymentInfo(ccPaymentMethod.getType(), paymentInfo.getPaymentId(), ccPaymentMethod.getCardType(), ccPaymentMethod.getCardCountry(), context);
- if (paymentInfo.getPaymentId() != null) {
- paymentDao.updatePaymentAttemptWithPaymentId(paymentAttempt.getPaymentAttemptId(), paymentInfo.getPaymentId(), context);
- }
+ } else if (paymentMethodInfo instanceof PaypalPaymentMethodInfo) {
+ PaypalPaymentMethodInfo paypalPaymentMethodInfo = (PaypalPaymentMethodInfo)paymentMethodInfo;
+ paymentDao.updatePaymentInfo(paypalPaymentMethodInfo.getType(), paymentInfo.getPaymentId(), null, null, context);
}
+ if (paymentInfo.getPaymentId() != null) {
+ paymentDao.updatePaymentAttemptWithPaymentId(paymentAttempt.getPaymentAttemptId(), paymentInfo.getPaymentId(), context);
+ }
+
+ invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
+ paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : paymentInfo.getAmount(),
+ /*paymentInfo.getRefundAmount(), */
+ paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : invoice.getCurrency(),
+ paymentAttempt.getPaymentAttemptId(),
+ paymentAttempt.getPaymentAttemptDate(),
+ context);
- invoicePaymentApi.notifyOfPaymentAttempt(
- invoice.getId(),
- paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : paymentInfo.getAmount(),
- // paymentInfo.getRefundAmount(), TODO
- paymentInfo == null || paymentInfo.getStatus().equalsIgnoreCase("Error") ? null : invoice.getCurrency(),
- paymentAttempt.getPaymentAttemptId(),
- paymentAttempt.getPaymentAttemptDate(),
- context);
+ return paymentInfo;
- return paymentOrError;
}
- private void scheduleRetry(PaymentAttempt paymentAttempt, String error) {
+ private void scheduleRetry(PaymentAttempt paymentAttempt) {
final List<Integer> retryDays = config.getPaymentRetryDays();
int retryCount = 0;
@@ -348,28 +359,28 @@ public class DefaultPaymentApi implements PaymentApi {
@Override
public String createPaymentProviderAccount(Account account, CallContext context)
- throws PaymentApiException {
- final PaymentProviderPlugin plugin = getPaymentProviderPlugin((Account)null);
- Either<PaymentErrorEvent, String> result = plugin.createPaymentProviderAccount(account);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_PROVIDER_ACCOUNT, account.getId(), result.getLeft().getMessage());
+ throws PaymentApiException {
+ try {
+ final PaymentProviderPlugin plugin = getPaymentProviderPlugin((Account)null);
+ return plugin.createPaymentProviderAccount(account);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_PAYMENT_PROVIDER_ACCOUNT, account.getId(), e.getMessage());
}
- return result.getRight();
}
@Override
public void updatePaymentProviderAccountContact(String externalKey, CallContext context)
throws PaymentApiException {
+
+ Account account = null;
try {
- Account account = accountUserApi.getAccountByKey(externalKey);
+ account = accountUserApi.getAccountByKey(externalKey);
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
- Either<PaymentErrorEvent, Void> result = plugin.updatePaymentProviderAccountExistingContact(account);
- if (result.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_PROVIDER_ACCOUNT, account.getId(), result.getLeft().getMessage());
- }
- return;
+ plugin.updatePaymentProviderAccountExistingContact(account);
} catch (AccountApiException e) {
throw new PaymentApiException(e);
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_UPD_PAYMENT_PROVIDER_ACCOUNT, account.getId(), e.getMessage());
}
}
@@ -379,24 +390,37 @@ public class DefaultPaymentApi implements PaymentApi {
}
@Override
- public List<PaymentInfoEvent> createRefund(Account account, List<String> invoiceIds, CallContext context)
+ public PaymentInfoEvent createRefund(Account account, UUID paymentId, CallContext context)
throws PaymentApiException {
+
+ /*
+ try {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
- List<Either<PaymentErrorEvent, PaymentInfoEvent>> result = plugin.processRefund(account);
+ List<PaymentInfoPlugin> result = plugin.processRefund(account);
List<PaymentInfoEvent> info = new LinkedList<PaymentInfoEvent>();
- for (Either<PaymentErrorEvent, PaymentInfoEvent> cur : result) {
- if (cur.isLeft()) {
- throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_REFUND, account.getId(), cur.getLeft().getMessage());
- }
- info.add(cur.getRight());
+ int i = 0;
+ for (PaymentInfoPlugin cur : result) {
+ // STEPH
+ //info.add(new DefaultPaymentInfoEvent(cur, account.getId(), invoiceIds.get(i)));
}
return info;
+ } catch (PaymentPluginApiException e) {
+ throw new PaymentApiException(ErrorCode.PAYMENT_CREATE_REFUND, account.getId(), e.getMessage());
+ }
+ */
+ // STEPH
+ return null;
}
@Override
- public List<PaymentInfoEvent> getPaymentInfo(List<String> invoiceIds) {
- return paymentDao.getPaymentInfo(invoiceIds);
+ public List<PaymentInfoEvent> getPaymentInfo(List<UUID> invoiceIds) {
+ // STEPH until DAO is changed:
+ List<String> invoiceIdStrings = new ArrayList<String>();
+ for (UUID cur : invoiceIds) {
+ invoiceIdStrings.add(cur.toString());
+ }
+ return paymentDao.getPaymentInfo(invoiceIdStrings);
}
@Override
@@ -409,4 +433,59 @@ public class DefaultPaymentApi implements PaymentApi {
return paymentDao.getPaymentInfoForPaymentAttemptId(paymentAttemptId);
}
+
+
+ private PaymentProviderPlugin getPaymentProviderPlugin(String accountKey) {
+
+ String paymentProviderName = null;
+ if (accountKey != null) {
+ Account account;
+ try {
+ account = accountUserApi.getAccountByKey(accountKey);
+ return getPaymentProviderPlugin(account);
+ } catch (AccountApiException e) {
+ log.error("Error getting payment provider plugin.", e);
+ }
+ }
+ return pluginRegistry.getPlugin(paymentProviderName);
+ }
+
+ private PaymentProviderPlugin getPaymentProviderPlugin(Account account) {
+ String paymentProviderName = null;
+
+ if (account != null) {
+ paymentProviderName = account.getPaymentProviderName();
+ }
+
+ return pluginRegistry.getPlugin(paymentProviderName);
+ }
+
+
+
+ public interface WithAccountLockCallback<T> {
+ public T doOperation() throws PaymentApiException;
+ }
+
+ public static class WithAccountLock<T> {
+ public T processAccountWithLock(final GlobalLocker locker, final String accountExternalKey, final WithAccountLockCallback<T> callback)
+ throws PaymentApiException {
+ GlobalLock lock = null;
+ try {
+ lock = locker.lockWithNumberOfTries(LockerService.PAYMENT, accountExternalKey, NB_LOCK_TRY);
+ return callback.doOperation();
+ } catch (LockFailedException e) {
+ // Not good!
+ log.error(String.format("Failed to lock account %s",
+ accountExternalKey), e);
+ // STEPH or throws
+ return null;
+ } finally {
+ if (lock != null) {
+ lock.release();
+ }
+ }
+ }
+ }
+
+
}
diff --git a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java
index e592294..ac0f3bb 100644
--- a/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java
+++ b/payment/src/main/java/com/ning/billing/payment/api/DefaultPaymentInfoEvent.java
@@ -26,12 +26,15 @@ import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import com.google.common.base.Objects;
+import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
import com.ning.billing.util.bus.BusEvent;
import com.ning.billing.util.bus.BusEvent.BusEventType;
public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
+ private final UUID invoiceId;
+ private final UUID accountId;
private final String paymentId;
private final BigDecimal amount;
private final BigDecimal refundAmount;
@@ -50,22 +53,27 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
private final DateTime updatedDate;
@JsonCreator
- public DefaultPaymentInfoEvent(@JsonProperty("paymentId") String paymentId,
- @JsonProperty("amount") BigDecimal amount,
- @JsonProperty("refundAmount") BigDecimal refundAmount,
- @JsonProperty("bankIdentificationNumber") String bankIdentificationNumber,
- @JsonProperty("paymentNumber") String paymentNumber,
- @JsonProperty("status") String status,
- @JsonProperty("type") String type,
- @JsonProperty("referenceId") String referenceId,
- @JsonProperty("paymentMethodId") String paymentMethodId,
- @JsonProperty("paymentMethod") String paymentMethod,
- @JsonProperty("cardType") String cardType,
- @JsonProperty("cardCountry") String cardCountry,
- @JsonProperty("userToken") UUID userToken,
- @JsonProperty("effectiveDate") DateTime effectiveDate,
- @JsonProperty("createdDate") DateTime createdDate,
- @JsonProperty("updatedDate") DateTime updatedDate) {
+ public DefaultPaymentInfoEvent(@JsonProperty("accountId") UUID accountId,
+ @JsonProperty("invoiceId") UUID invoiceId,
+ @JsonProperty("paymentId") String paymentId,
+ @JsonProperty("amount") BigDecimal amount,
+ @JsonProperty("refundAmount") BigDecimal refundAmount,
+ @JsonProperty("bankIdentificationNumber") String bankIdentificationNumber,
+ @JsonProperty("paymentNumber") String paymentNumber,
+ @JsonProperty("status") String status,
+ @JsonProperty("type") String type,
+ @JsonProperty("referenceId") String referenceId,
+ @JsonProperty("paymentMethodId") String paymentMethodId,
+ @JsonProperty("paymentMethod") String paymentMethod,
+ @JsonProperty("cardType") String cardType,
+ @JsonProperty("cardCountry") String cardCountry,
+ @JsonProperty("userToken") UUID userToken,
+ @JsonProperty("effectiveDate") DateTime effectiveDate,
+ @JsonProperty("createdDate") DateTime createdDate,
+ @JsonProperty("updatedDate") DateTime updatedDate) {
+
+ this.accountId = accountId;
+ this.invoiceId = invoiceId;
this.paymentId = paymentId;
this.amount = amount;
this.refundAmount = refundAmount;
@@ -85,22 +93,30 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
}
public DefaultPaymentInfoEvent(DefaultPaymentInfoEvent src) {
- this(src.paymentId,
- src.amount,
- src.refundAmount,
- src.bankIdentificationNumber,
- src.paymentNumber,
- src.status,
- src.type,
- src.referenceId,
- src.paymentMethodId,
- src.paymentMethod,
- src.cardType,
- src.cardCountry,
- src.userToken,
- src.effectiveDate,
- src.createdDate,
- src.updatedDate);
+ this(src.accountId,
+ src.invoiceId,
+ src.paymentId,
+ src.amount,
+ src.refundAmount,
+ src.bankIdentificationNumber,
+ src.paymentNumber,
+ src.status,
+ src.type,
+ src.referenceId,
+ src.paymentMethodId,
+ src.paymentMethod,
+ src.cardType,
+ src.cardCountry,
+ src.userToken,
+ src.effectiveDate,
+ src.createdDate,
+ src.updatedDate);
+ }
+
+ public DefaultPaymentInfoEvent(PaymentInfoPlugin info, UUID accountId, UUID invoiceId) {
+ this(accountId, invoiceId, info.getPaymentId(), info.getAmount(), info.getRefundAmount(), info.getBankIdentificationNumber(), info.getPaymentNumber(),
+ info.getStatus(), info.getCardType(), info.getReferenceId(), info.getPaymentMethodId(), info.getPaymentMethod(), info.getCardType(), info.getCardCountry(),
+ null, info.getEffectiveDate(), info.getCreatedDate(), info.getUpdatedDate());
}
@JsonIgnore
@@ -124,6 +140,16 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
}
@Override
+ public UUID getInvoiceId() {
+ return invoiceId;
+ }
+
+ @Override
+ public UUID getAccountId() {
+ return accountId;
+ }
+
+ @Override
public BigDecimal getAmount() {
return amount;
}
@@ -194,6 +220,9 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
}
public static class Builder {
+
+ private UUID invoiceId;
+ private UUID accountId;
private String paymentId;
private BigDecimal amount;
private BigDecimal refundAmount;
@@ -215,6 +244,8 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
}
public Builder(DefaultPaymentInfoEvent src) {
+ this.accountId = src.accountId;
+ this.invoiceId = src.invoiceId;
this.paymentId = src.paymentId;
this.amount = src.amount;
this.refundAmount = src.refundAmount;
@@ -233,6 +264,17 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
this.updatedDate = src.updatedDate;
}
+
+ public Builder setAccountId(UUID accountId) {
+ this.accountId = accountId;
+ return this;
+ }
+
+ public Builder setInvoiceId(UUID invoiceId) {
+ this.invoiceId = invoiceId;
+ return this;
+ }
+
public Builder setPaymentId(String paymentId) {
this.paymentId = paymentId;
return this;
@@ -314,22 +356,24 @@ public class DefaultPaymentInfoEvent implements PaymentInfoEvent {
}
public PaymentInfoEvent build() {
- return new DefaultPaymentInfoEvent(paymentId,
- amount,
- refundAmount,
- bankIdentificationNumber,
- paymentNumber,
- status,
- type,
- referenceId,
- paymentMethodId,
- paymentMethod,
- cardType,
- cardCountry,
- userToken,
- effectiveDate,
- createdDate,
- updatedDate);
+ return new DefaultPaymentInfoEvent(accountId,
+ invoiceId,
+ paymentId,
+ amount,
+ refundAmount,
+ bankIdentificationNumber,
+ paymentNumber,
+ status,
+ type,
+ referenceId,
+ paymentMethodId,
+ paymentMethod,
+ cardType,
+ cardCountry,
+ userToken,
+ effectiveDate,
+ createdDate,
+ updatedDate);
}
}
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
index a21a90c..8b0e163 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/AuditedPaymentDao.java
@@ -29,6 +29,7 @@ import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.api.PaymentInfoEvent;
import org.skife.jdbi.v2.Transaction;
import org.skife.jdbi.v2.TransactionStatus;
@@ -52,7 +53,7 @@ public class AuditedPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttempt createPaymentAttempt(final PaymentAttempt paymentAttempt, final CallContext context) {
+ public PaymentAttempt createPaymentAttempt(final PaymentAttempt paymentAttempt, final PaymentAttemptStatus paymentAttemptStatus, final CallContext context) {
return sqlDao.inTransaction(new Transaction<PaymentAttempt, PaymentSqlDao>() {
@Override
public PaymentAttempt inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
@@ -69,11 +70,11 @@ public class AuditedPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttempt createPaymentAttempt(final Invoice invoice, final CallContext context) {
+ public PaymentAttempt createPaymentAttempt(final Invoice invoice, final PaymentAttemptStatus paymentAttemptStatus, final CallContext context) {
return sqlDao.inTransaction(new Transaction<PaymentAttempt, PaymentSqlDao>() {
@Override
public PaymentAttempt inTransaction(PaymentSqlDao transactional, TransactionStatus status) throws Exception {
- final PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
+ final PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice, paymentAttemptStatus);
transactional.insertPaymentAttempt(paymentAttempt, context);
UUID historyRecordId = UUID.randomUUID();
transactional.insertPaymentAttemptHistory(historyRecordId.toString(), paymentAttempt, context);
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
index 8c07824..f289d5c 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentDao.java
@@ -22,12 +22,13 @@ import java.util.UUID;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentInfoEvent;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.util.callcontext.CallContext;
public interface PaymentDao {
- PaymentAttempt createPaymentAttempt(Invoice invoice, CallContext context);
- PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt, CallContext context);
+ PaymentAttempt createPaymentAttempt(Invoice invoice, PaymentAttemptStatus status, CallContext context);
+ PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt, PaymentAttemptStatus status, CallContext context);
void savePaymentInfo(PaymentInfoEvent right, CallContext context);
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
index b7b861a..9b27f23 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/PaymentSqlDao.java
@@ -44,6 +44,7 @@ import org.skife.jdbi.v2.unstable.BindIn;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.api.PaymentInfoEvent;
@ExternalizedSqlViaStringTemplate3()
@@ -117,6 +118,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
stmt.bind("payment_attempt_dt", getDate(paymentAttempt.getPaymentAttemptDate()));
stmt.bind("payment_id", paymentAttempt.getPaymentId());
stmt.bind("retry_count", paymentAttempt.getRetryCount());
+ stmt.bind("processing_status", paymentAttempt.getPaymentAttemptStatus().toString());
stmt.bind("created_dt", getDate(paymentAttempt.getCreatedDate()));
stmt.bind("updated_dt", getDate(paymentAttempt.getUpdatedDate()));
}
@@ -135,6 +137,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
DateTime paymentAttemptDate = getDate(rs, "payment_attempt_dt");
String paymentId = rs.getString("payment_id");
Integer retryCount = rs.getInt("retry_count");
+ PaymentAttemptStatus paymentAttemptStatus = PaymentAttemptStatus.valueOf(rs.getString("processing_status"));
DateTime createdDate = getDate(rs, "created_dt");
DateTime updatedDate = getDate(rs, "updated_dt");
@@ -147,6 +150,7 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
paymentAttemptDate,
paymentId,
retryCount,
+ paymentAttemptStatus,
createdDate,
updatedDate);
}
@@ -177,6 +181,8 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
@Override
public PaymentInfoEvent map(int index, ResultSet rs, StatementContext ctx) throws SQLException {
+ UUID accountId = null;
+ UUID invoiceId = null;
String paymentId = rs.getString("payment_id");
BigDecimal amount = rs.getBigDecimal("amount");
BigDecimal refundAmount = rs.getBigDecimal("refund_amount");
@@ -193,24 +199,26 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
DateTime createdDate = getDate(rs, "created_dt");
DateTime updatedDate = getDate(rs, "updated_dt");
- UUID userToken = null; //rs.getString("user_token") != null ? UUID.fromString(rs.getString("user_token")) : null;
+ UUID userToken = rs.getString("user_token") != null ? UUID.fromString(rs.getString("user_token")) : null;
- return new DefaultPaymentInfoEvent(paymentId,
- amount,
- refundAmount,
- bankIdentificationNumber,
- paymentNumber,
- status,
- type,
- referenceId,
- paymentMethodId,
- paymentMethod,
- cardType,
- cardCountry,
- userToken,
- effectiveDate,
- createdDate,
- updatedDate);
+ return new DefaultPaymentInfoEvent(accountId,
+ invoiceId,
+ paymentId,
+ amount,
+ refundAmount,
+ bankIdentificationNumber,
+ paymentNumber,
+ status,
+ type,
+ referenceId,
+ paymentMethodId,
+ paymentMethod,
+ cardType,
+ cardCountry,
+ userToken,
+ effectiveDate,
+ createdDate,
+ updatedDate);
}
}
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
index 62785c9..98e9e59 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPlugin.java
@@ -16,7 +16,7 @@
package com.ning.billing.payment.provider;
-import java.util.Arrays;
+import java.math.BigDecimal;
import java.util.List;
import java.util.UUID;
@@ -25,94 +25,152 @@ import org.joda.time.DateTimeZone;
import com.ning.billing.account.api.Account;
import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.payment.api.DefaultPaymentErrorEvent;
-import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
-import com.ning.billing.payment.api.Either;
-import com.ning.billing.payment.api.PaymentErrorEvent;
-import com.ning.billing.payment.api.PaymentInfoEvent;
import com.ning.billing.payment.api.PaymentMethodInfo;
import com.ning.billing.payment.api.PaymentProviderAccount;
+import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
+import com.ning.billing.payment.plugin.api.PaymentProviderPlugin;
public class NoOpPaymentProviderPlugin implements PaymentProviderPlugin {
@Override
- public Either<PaymentErrorEvent, PaymentInfoEvent> processInvoice(Account account, Invoice invoice) {
- PaymentInfoEvent payment = new DefaultPaymentInfoEvent.Builder()
- .setPaymentId(UUID.randomUUID().toString())
- .setAmount(invoice.getBalance())
- .setStatus("Processed")
- .setCreatedDate(new DateTime(DateTimeZone.UTC))
- .setEffectiveDate(new DateTime(DateTimeZone.UTC))
- .setType("Electronic")
- .build();
- return Either.right(payment);
+ public PaymentInfoPlugin processInvoice(final Account account, final Invoice invoice)
+ throws PaymentPluginApiException {
+ PaymentInfoPlugin payment = new PaymentInfoPlugin() {
+ @Override
+ public DateTime getUpdatedDate() {
+ return new DateTime(DateTimeZone.UTC);
+ }
+ @Override
+ public String getType() {
+ return "Electronic";
+ }
+ @Override
+ public String getStatus() {
+ return "Processed";
+ }
+ @Override
+ public BigDecimal getRefundAmount() {
+ return null;
+ }
+ @Override
+ public String getReferenceId() {
+ return null;
+ }
+ @Override
+ public String getPaymentNumber() {
+ return null;
+ }
+ @Override
+ public String getPaymentMethodId() {
+ return null;
+ }
+ @Override
+ public String getPaymentMethod() {
+ return null;
+ }
+ @Override
+ public String getPaymentId() {
+ return UUID.randomUUID().toString();
+ }
+ @Override
+ public DateTime getEffectiveDate() {
+ return null;
+ }
+ @Override
+ public DateTime getCreatedDate() {
+ return new DateTime(DateTimeZone.UTC);
+ }
+ @Override
+ public String getCardType() {
+ return null;
+ }
+ @Override
+ public String getCardCountry() {
+ return null;
+ }
+ @Override
+ public String getBankIdentificationNumber() {
+ return null;
+ }
+ @Override
+ public BigDecimal getAmount() {
+ return invoice.getBalance();
+ }
+ };
+ return payment;
}
@Override
- public Either<PaymentErrorEvent, PaymentInfoEvent> getPaymentInfo(String paymentId) {
- return Either.right(null);
+ public String createPaymentProviderAccount(Account account)
+ throws PaymentPluginApiException {
+
+ return null;
}
@Override
- public Either<PaymentErrorEvent, String> createPaymentProviderAccount(Account account) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unsupported",
- "Account creation not supported in this plugin",
- account.getId(),
- null, null));
+ public PaymentInfoPlugin getPaymentInfo(String paymentId)
+ throws PaymentPluginApiException {
+
+ return null;
}
@Override
- public Either<PaymentErrorEvent, PaymentProviderAccount> getPaymentProviderAccount(String accountKey) {
- return Either.right(null);
+ public PaymentProviderAccount getPaymentProviderAccount(String accountKey)
+ throws PaymentPluginApiException {
+ return null;
}
@Override
- public Either<PaymentErrorEvent, String> addPaymentMethod(String accountKey, PaymentMethodInfo paymentMethod) {
- return Either.right(null);
- }
-
- public void setDefaultPaymentMethodOnAccount(PaymentProviderAccount account, String paymentMethodId) {
- // NO-OP
+ public void updatePaymentGateway(String accountKey)
+ throws PaymentPluginApiException {
}
@Override
- public Either<PaymentErrorEvent, PaymentMethodInfo> updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethod) {
- return Either.right(paymentMethod);
+ public PaymentMethodInfo getPaymentMethodInfo(String paymentMethodId)
+ throws PaymentPluginApiException {
+ return null;
}
@Override
- public Either<PaymentErrorEvent, Void> deletePaymentMethod(String accountKey, String paymentMethodId) {
- return Either.right(null);
+ public List<PaymentMethodInfo> getPaymentMethods(String accountKey)
+ throws PaymentPluginApiException {
+ return null;
}
@Override
- public Either<PaymentErrorEvent, PaymentMethodInfo> getPaymentMethodInfo(String paymentMethodId) {
- return Either.right(null);
+ public String addPaymentMethod(String accountKey,
+ PaymentMethodInfo paymentMethod) throws PaymentPluginApiException {
+ return null;
}
@Override
- public Either<PaymentErrorEvent, List<PaymentMethodInfo>> getPaymentMethods(final String accountKey) {
- return Either.right(Arrays.<PaymentMethodInfo>asList());
+ public PaymentMethodInfo updatePaymentMethod(String accountKey,
+ PaymentMethodInfo paymentMethodInfo)
+ throws PaymentPluginApiException {
+ return null;
}
@Override
- public Either<PaymentErrorEvent, Void> updatePaymentGateway(String accountKey) {
- return Either.right(null);
+ public void deletePaymentMethod(String accountKey, String paymentMethodId)
+ throws PaymentPluginApiException {
}
@Override
- public Either<PaymentErrorEvent, Void> updatePaymentProviderAccountExistingContact(Account account) {
- return Either.right(null);
+ public void updatePaymentProviderAccountExistingContact(Account account)
+ throws PaymentPluginApiException {
+
}
@Override
- public Either<PaymentErrorEvent, Void> updatePaymentProviderAccountWithNewContact(Account account) {
- return Either.right(null);
+ public void updatePaymentProviderAccountWithNewContact(Account account)
+ throws PaymentPluginApiException {
+
}
@Override
- public List<Either<PaymentErrorEvent, PaymentInfoEvent>> processRefund(Account account) {
- // TODO Auto-generated method stub
+ public List<PaymentInfoPlugin> processRefund(Account account)
+ throws PaymentPluginApiException {
return null;
}
diff --git a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java
index 5ba98b7..ceb36f9 100644
--- a/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java
+++ b/payment/src/main/java/com/ning/billing/payment/provider/NoOpPaymentProviderPluginProvider.java
@@ -20,6 +20,7 @@ import com.google.inject.Inject;
import com.google.inject.Provider;
public class NoOpPaymentProviderPluginProvider implements Provider<NoOpPaymentProviderPlugin> {
+
private PaymentProviderPluginRegistry registry;
private final String instanceName;
diff --git a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
index 2077c5e..d11a70c 100644
--- a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
@@ -19,11 +19,13 @@ package com.ning.billing.payment;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
import com.ning.billing.account.api.Account;
@@ -31,57 +33,64 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.account.api.AccountUserApi;
import com.ning.billing.invoice.api.InvoiceCreationEvent;
import com.ning.billing.payment.api.DefaultPaymentErrorEvent;
-import com.ning.billing.payment.api.Either;
import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.payment.api.PaymentApiException;
import com.ning.billing.payment.api.PaymentErrorEvent;
import com.ning.billing.payment.api.PaymentInfoEvent;
-import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
+
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.bus.BusEvent.BusEventType;
import com.ning.billing.util.bus.BusEvent;
import com.ning.billing.util.callcontext.CallContext;
import com.ning.billing.util.callcontext.CallOrigin;
import com.ning.billing.util.callcontext.DefaultCallContext;
import com.ning.billing.util.callcontext.UserType;
import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.globallocker.GlobalLock;
+import com.ning.billing.util.globallocker.GlobalLocker;
+import com.ning.billing.util.globallocker.LockFailedException;
+import com.ning.billing.util.globallocker.GlobalLocker.LockerService;
public class RequestProcessor {
+
public static final String PAYMENT_PROVIDER_KEY = "paymentProvider";
+
+ private final static int NB_PAYMENT_THREADS = 3; // STEPH
+ private final static String PAYMENT_GROUP_NAME = "payment-grp";
+ private final static String PAYMENT_TH_NAME = "payment-th";
+
+
private final AccountUserApi accountUserApi;
private final PaymentApi paymentApi;
private final Bus eventBus;
private final Clock clock;
-
+ private final ExecutorService executor;
+
private static final Logger log = LoggerFactory.getLogger(RequestProcessor.class);
@Inject
- public RequestProcessor(Clock clock,
- AccountUserApi accountUserApi,
- PaymentApi paymentApi,
- PaymentProviderPluginRegistry pluginRegistry,
- Bus eventBus) {
+ public RequestProcessor(final Clock clock,
+ final AccountUserApi accountUserApi,
+ final PaymentApi paymentApi,
+ final Bus eventBus,
+ final GlobalLocker locker) {
this.clock = clock;
this.accountUserApi = accountUserApi;
this.paymentApi = paymentApi;
this.eventBus = eventBus;
+ this.executor = Executors.newFixedThreadPool(NB_PAYMENT_THREADS, new ThreadFactory() {
+ @Override
+ public Thread newThread(Runnable r) {
+ return new Thread(new ThreadGroup(PAYMENT_GROUP_NAME),
+ r,
+ PAYMENT_TH_NAME);
+ }
+ });
}
- private void postPaymentEvent(BusEvent ev, UUID accountId) {
- if (ev == null) {
- return;
- }
- try {
- eventBus.post(ev);
- } catch (EventBusException e) {
- log.error("Failed to post Payment event event for account {} ", accountId, e);
- }
- }
@Subscribe
- public void receiveInvoice(InvoiceCreationEvent event) {
-
+ public void processInvoiceEvent(InvoiceCreationEvent event) {
log.info("Received invoice creation notification for account {} and invoice {}", event.getAccountId(), event.getInvoiceId());
PaymentErrorEvent errorEvent = null;
@@ -89,9 +98,8 @@ public class RequestProcessor {
final Account account = accountUserApi.getAccountById(event.getAccountId());
if (account != null) {
CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
- List<PaymentInfoEvent> results = paymentApi.createPayment(account, Arrays.asList(event.getInvoiceId().toString()), context);
- PaymentInfoEvent infoEvent = (!results.isEmpty()) ? results.get(0) : null;
- postPaymentEvent(infoEvent, account.getId());
+ PaymentInfoEvent result = paymentApi.createPayment(account, event.getInvoiceId(), context);
+ postPaymentEvent(result, account.getId());
return;
} else {
errorEvent = new DefaultPaymentErrorEvent(null, "Failed to retrieve account", event.getAccountId(), null, null);
@@ -105,4 +113,16 @@ public class RequestProcessor {
}
postPaymentEvent(errorEvent, event.getAccountId());
}
+
+ private void postPaymentEvent(BusEvent ev, UUID accountId) {
+ if (ev == null) {
+ return;
+ }
+ try {
+ eventBus.post(ev);
+ } catch (EventBusException e) {
+ log.error("Failed to post Payment event event for account {} ", accountId, e);
+ }
+ }
+
}
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
new file mode 100644
index 0000000..6809514
--- /dev/null
+++ b/payment/src/main/java/com/ning/billing/payment/retry/RetryService.java
@@ -0,0 +1,29 @@
+/*
+ * 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.payment.retry;
+
+import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
+
+public interface RetryService {
+
+ public void initialize(final String svcName)
+ throws NotificationQueueAlreadyExists;
+
+ public void start();
+
+ public void stop();
+
+}
diff --git a/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java b/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java
new file mode 100644
index 0000000..3a1647f
--- /dev/null
+++ b/payment/src/main/java/com/ning/billing/payment/retry/TimedoutPaymentRetryService.java
@@ -0,0 +1,118 @@
+/*
+ * 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.payment.retry;
+
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+import com.ning.billing.config.PaymentConfig;
+import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.clock.Clock;
+import com.ning.billing.util.notificationq.NotificationQueue;
+import com.ning.billing.util.notificationq.NotificationQueueService;
+import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
+import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
+
+public class TimedoutPaymentRetryService implements RetryService {
+
+
+
+ private static final Logger log = LoggerFactory.getLogger(TimedoutPaymentRetryService.class);
+
+ public static final String QUEUE_NAME = "timedout-retry";
+
+ private final Clock clock;
+ private final NotificationQueueService notificationQueueService;
+ private final PaymentConfig config;
+ private final PaymentApi paymentApi;
+ private NotificationQueue retryQueue;
+
+ @Inject
+ public TimedoutPaymentRetryService(Clock clock,
+ NotificationQueueService notificationQueueService,
+ PaymentConfig config,
+ PaymentApi paymentApi) {
+ this.clock = clock;
+ this.notificationQueueService = notificationQueueService;
+ this.paymentApi = paymentApi;
+ this.config = config;
+ }
+
+ @Override
+ public void initialize(final String svcName) throws NotificationQueueAlreadyExists {
+ retryQueue = notificationQueueService.createNotificationQueue(svcName, QUEUE_NAME, new NotificationQueueHandler() {
+ @Override
+ public void handleReadyNotification(String notificationKey, DateTime eventDateTime) {
+ CallContext context = new DefaultCallContext("TimedoutRetryService", CallOrigin.INTERNAL, UserType.SYSTEM, clock);
+ retry(notificationKey, context);
+ }
+ },
+ config);
+ }
+
+ @Override
+ public void start() {
+ retryQueue.startQueue();
+ }
+
+ @Override
+ public void stop() {
+ if (retryQueue != null) {
+ retryQueue.stopQueue();
+ }
+ }
+
+ public void scheduleRetry(PaymentAttempt paymentAttempt, DateTime timeOfRetry) {
+ /*
+ final String id = paymentAttempt.getPaymentAttemptId().toString();
+
+ NotificationKey key = new NotificationKey() {
+ @Override
+ public String toString() {
+ return id;
+ }
+ };
+
+ if (retryQueue != null) {
+ retryQueue.recordFutureNotification(timeOfRetry, key);
+ }
+ */
+ }
+
+ private void retry(String paymentAttemptId, CallContext context) {
+
+ /*
+ try {
+ PaymentInfoEvent paymentInfo = paymentApi.getPaymentInfoForPaymentAttemptId(paymentAttemptId);
+ if (paymentInfo != null && PaymentStatus.Processed.equals(PaymentStatus.valueOf(paymentInfo.getStatus()))) {
+ return;
+ }
+ paymentApi.createPaymentForPaymentAttempt(UUID.fromString(paymentAttemptId), context);
+ } catch (PaymentApiException e) {
+ log.error(String.format("Failed to retry payment for %s"), e);
+ }
+ */
+ }
+}
diff --git a/payment/src/main/java/com/ning/billing/payment/setup/DefaultPaymentService.java b/payment/src/main/java/com/ning/billing/payment/setup/DefaultPaymentService.java
index eae1baa..4bc3ed3 100644
--- a/payment/src/main/java/com/ning/billing/payment/setup/DefaultPaymentService.java
+++ b/payment/src/main/java/com/ning/billing/payment/setup/DefaultPaymentService.java
@@ -16,16 +16,26 @@
package com.ning.billing.payment.setup;
+import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.ning.billing.lifecycle.KillbillService;
import com.ning.billing.lifecycle.LifecycleHandlerType;
+import com.ning.billing.lifecycle.LifecycleHandlerType.LifecycleLevel;
import com.ning.billing.payment.RequestProcessor;
import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.payment.api.PaymentService;
+import com.ning.billing.payment.retry.FailedPaymentRetryService;
+import com.ning.billing.payment.retry.TimedoutPaymentRetryService;
import com.ning.billing.util.bus.Bus;
+import com.ning.billing.util.callcontext.CallContext;
+import com.ning.billing.util.callcontext.CallOrigin;
+import com.ning.billing.util.callcontext.DefaultCallContext;
+import com.ning.billing.util.callcontext.UserType;
+import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueAlreadyExists;
+import com.ning.billing.util.notificationq.NotificationQueueService.NotificationQueueHandler;
public class DefaultPaymentService implements PaymentService {
private static final Logger log = LoggerFactory.getLogger(DefaultPaymentService.class);
@@ -35,12 +45,17 @@ public class DefaultPaymentService implements PaymentService {
private final RequestProcessor requestProcessor;
private final Bus eventBus;
private final PaymentApi api;
+ private final FailedPaymentRetryService failedRetryService;
+ private final TimedoutPaymentRetryService timedoutRetryService;
@Inject
- public DefaultPaymentService(final RequestProcessor requestProcessor, final PaymentApi api, final Bus eventBus) {
+ public DefaultPaymentService(final RequestProcessor requestProcessor, final PaymentApi api, final Bus eventBus,
+ final FailedPaymentRetryService failedRetryService, final TimedoutPaymentRetryService timedoutRetryService) {
this.requestProcessor = requestProcessor;
this.eventBus = eventBus;
this.api = api;
+ this.failedRetryService = failedRetryService;
+ this.timedoutRetryService = timedoutRetryService;
}
@Override
@@ -48,6 +63,12 @@ public class DefaultPaymentService implements PaymentService {
return SERVICE_NAME;
}
+ @LifecycleHandlerType(LifecycleLevel.INIT_SERVICE)
+ public void initialize() throws NotificationQueueAlreadyExists {
+ failedRetryService.initialize(SERVICE_NAME);
+ timedoutRetryService.initialize(SERVICE_NAME);
+ }
+
@LifecycleHandlerType(LifecycleHandlerType.LifecycleLevel.REGISTER_EVENTS)
public void registerForNotifications() {
try {
@@ -57,10 +78,21 @@ public class DefaultPaymentService implements PaymentService {
log.error("Unable to register with the EventBus!", e);
}
}
+
+ @LifecycleHandlerType(LifecycleLevel.START_SERVICE)
+ public void start() {
+ failedRetryService.start();
+ timedoutRetryService.start();
+ }
+
+ @LifecycleHandlerType(LifecycleLevel.STOP_SERVICE)
+ public void stop() {
+ failedRetryService.stop();
+ timedoutRetryService.stop();
+ }
@Override
public PaymentApi getPaymentApi() {
return api;
}
-
}
diff --git a/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java b/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
index de4bf3c..9475f7c 100644
--- a/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
+++ b/payment/src/main/java/com/ning/billing/payment/setup/PaymentModule.java
@@ -23,13 +23,14 @@ import org.skife.config.ConfigurationObjectFactory;
import com.google.inject.AbstractModule;
import com.ning.billing.config.PaymentConfig;
import com.ning.billing.payment.RequestProcessor;
-import com.ning.billing.payment.RetryService;
import com.ning.billing.payment.api.DefaultPaymentApi;
import com.ning.billing.payment.api.PaymentApi;
import com.ning.billing.payment.api.PaymentService;
import com.ning.billing.payment.dao.AuditedPaymentDao;
import com.ning.billing.payment.dao.PaymentDao;
+import com.ning.billing.payment.provider.DefaultPaymentProviderPluginRegistry;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
+import com.ning.billing.payment.retry.FailedPaymentRetryService;
public class PaymentModule extends AbstractModule {
private final Properties props;
@@ -50,7 +51,7 @@ public class PaymentModule extends AbstractModule {
}
protected void installRetryEngine() {
- bind(RetryService.class).asEagerSingleton();
+ bind(FailedPaymentRetryService.class).asEagerSingleton();
}
@Override
@@ -59,7 +60,7 @@ public class PaymentModule extends AbstractModule {
final PaymentConfig paymentConfig = factory.build(PaymentConfig.class);
bind(PaymentConfig.class).toInstance(paymentConfig);
- bind(PaymentProviderPluginRegistry.class).asEagerSingleton();
+ bind(PaymentProviderPluginRegistry.class).to(DefaultPaymentProviderPluginRegistry.class).asEagerSingleton();
bind(PaymentApi.class).to(DefaultPaymentApi.class).asEagerSingleton();
bind(RequestProcessor.class).asEagerSingleton();
bind(PaymentService.class).to(DefaultPaymentService.class).asEagerSingleton();
diff --git a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
index 87c8d8f..cb9effa 100644
--- a/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
+++ b/payment/src/main/resources/com/ning/billing/payment/dao/PaymentSqlDao.sql.stg
@@ -10,6 +10,7 @@ paymentAttemptFields(prefix) ::= <<
<prefix>payment_attempt_dt,
<prefix>invoice_dt,
<prefix>retry_count,
+ <prefix>processing_status,
<prefix>created_by,
<prefix>created_dt,
<prefix>updated_by,
@@ -39,13 +40,13 @@ paymentInfoFields(prefix) ::= <<
insertPaymentAttempt() ::= <<
INSERT INTO payment_attempts (<paymentAttemptFields()>)
VALUES (:payment_attempt_id, :invoice_id, :account_id, :amount, :currency, :payment_id,
- :payment_attempt_dt, :invoice_dt, :retry_count, :userName, :createdDate, :userName, :createdDate);
+ :payment_attempt_dt, :invoice_dt, :retry_count, :processing_status, :userName, :createdDate, :userName, :createdDate);
>>
insertPaymentAttemptHistory() ::= <<
INSERT INTO payment_attempt_history (history_record_id, <paymentAttemptFields()>)
VALUES (:historyRecordId, :payment_attempt_id, :invoice_id, :account_id, :amount, :currency, :payment_id,
- :payment_attempt_dt, :invoice_dt, :retry_count, :userName, :createdDate, :userName, :createdDate);
+ :payment_attempt_dt, :invoice_dt, :retry_count, :processing_status, :userName, :createdDate, :userName, :createdDate);
>>
getPaymentAttemptForPaymentId() ::= <<
@@ -112,7 +113,7 @@ getPaymentInfos(invoiceIds) ::= <<
>>
getPaymentInfoForPaymentAttemptId() ::= <<
- SELECT <paymentInfoFields("p.")>
+ SELECT <paymentInfoFields("p.")>,
FROM payments p, payment_attempts pa
WHERE pa.payment_attempt_id = :payment_attempt_id
AND pa.payment_id = p.payment_id
diff --git a/payment/src/main/resources/com/ning/billing/payment/ddl.sql b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
index 3a344f9..f374569 100644
--- a/payment/src/main/resources/com/ning/billing/payment/ddl.sql
+++ b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
@@ -8,6 +8,7 @@ CREATE TABLE payment_attempts (
payment_attempt_dt datetime NOT NULL,
payment_id varchar(36) COLLATE utf8_bin,
retry_count tinyint,
+ processing_status varchar(20),
invoice_dt datetime NOT NULL,
created_by varchar(50) NOT NULL,
created_dt datetime NOT NULL,
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java b/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java
index 14a5dba..0725dce 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestEventJson.java
@@ -49,7 +49,7 @@ public class TestEventJson {
@Test(groups= {"fast"})
public void testPaymentInfoEvent() throws Exception {
- PaymentInfoEvent e = new DefaultPaymentInfoEvent(UUID.randomUUID().toString(), new BigDecimal(12), new BigDecimal(12.9), "BNP", "eeert", "success",
+ PaymentInfoEvent e = new DefaultPaymentInfoEvent(UUID.randomUUID(), UUID.randomUUID(), UUID.randomUUID().toString(), new BigDecimal(12), new BigDecimal(12.9), "BNP", "eeert", "success",
"credit", "ref", "paypal", "paypal", "", "", UUID.randomUUID(), new DateTime(), new DateTime(), new DateTime());
String json = mapper.writeValueAsString(e);
diff --git a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
index 85aa07b..4dea9c5 100644
--- a/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/api/TestPaymentApi.java
@@ -102,11 +102,7 @@ public abstract class TestPaymentApi {
new BigDecimal("1.0"),
Currency.USD));
- List<PaymentInfoEvent> results = paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()), context);
-
- assertEquals(results.size(), 1);
-
- PaymentInfoEvent paymentInfo = results.get(0);
+ PaymentInfoEvent paymentInfo = paymentApi.createPayment(account.getExternalKey(), invoice.getId(), context);
assertNotNull(paymentInfo.getPaymentId());
assertTrue(paymentInfo.getAmount().compareTo(amount.setScale(2, RoundingMode.HALF_EVEN)) == 0);
@@ -124,7 +120,7 @@ public abstract class TestPaymentApi {
DateTime paymentAttemptDateTruncated = paymentAttempt.getPaymentAttemptDate().withMillisOfSecond(0).withSecondOfMinute(0);
assertEquals(paymentAttemptDateTruncated.compareTo(nowTruncated), 0);
- List<PaymentInfoEvent> paymentInfos = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId().toString()));
+ List<PaymentInfoEvent> paymentInfos = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId()));
assertNotNull(paymentInfos);
assertTrue(paymentInfos.size() > 0);
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
index cad55f0..e9c6545 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/MockPaymentDao.java
@@ -31,6 +31,7 @@ import com.google.common.collect.Collections2;
import com.ning.billing.invoice.api.Invoice;
import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.api.PaymentInfoEvent;
public class MockPaymentDao implements PaymentDao {
@@ -48,22 +49,23 @@ public class MockPaymentDao implements PaymentDao {
}
@Override
- public PaymentAttempt createPaymentAttempt(Invoice invoice, CallContext context) {
+ public PaymentAttempt createPaymentAttempt(Invoice invoice, PaymentAttemptStatus paymentAttemptStatus, CallContext context) {
PaymentAttempt updatedPaymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice.getId(), invoice.getAccountId(),
invoice.getBalance(), invoice.getCurrency(), invoice.getInvoiceDate(),
- null, null, null, context.getCreatedDate(), context.getUpdatedDate());
+ null, null, null, paymentAttemptStatus, context.getCreatedDate(), context.getUpdatedDate());
paymentAttempts.put(updatedPaymentAttempt.getPaymentAttemptId(), updatedPaymentAttempt);
return updatedPaymentAttempt;
}
@Override
- public PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt, CallContext context) {
+ public PaymentAttempt createPaymentAttempt(PaymentAttempt paymentAttempt, PaymentAttemptStatus paymentAttemptStatus, CallContext context) {
PaymentAttempt updatedPaymentAttempt = new PaymentAttempt(paymentAttempt.getPaymentAttemptId(),
paymentAttempt.getInvoiceId(),
paymentAttempt.getAccountId(), paymentAttempt.getAmount(), paymentAttempt.getCurrency(),
paymentAttempt.getInvoiceDate(), paymentAttempt.getPaymentAttemptDate(),
paymentAttempt.getPaymentId(), paymentAttempt.getRetryCount(),
+ paymentAttemptStatus,
context.getCreatedDate(), context.getUpdatedDate());
paymentAttempts.put(updatedPaymentAttempt.getPaymentAttemptId(), updatedPaymentAttempt);
diff --git a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
index 902db05..8baaec0 100644
--- a/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
+++ b/payment/src/test/java/com/ning/billing/payment/dao/TestPaymentDao.java
@@ -36,6 +36,7 @@ import com.ning.billing.account.api.AccountApiException;
import com.ning.billing.catalog.api.Currency;
import com.ning.billing.payment.api.DefaultPaymentInfoEvent;
import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.api.PaymentInfoEvent;
public abstract class TestPaymentDao {
@@ -89,7 +90,7 @@ public abstract class TestPaymentDao {
.setInvoiceDate(context.getCreatedDate())
.build();
- paymentDao.createPaymentAttempt(paymentAttempt, context);
+ paymentDao.createPaymentAttempt(paymentAttempt, PaymentAttemptStatus.IN_PROCESSING, context);
}
@Test
@@ -104,8 +105,8 @@ public abstract class TestPaymentDao {
ClockMock clock = new ClockMock();
CallContext thisContext = new DefaultCallContext("Payment Tests", CallOrigin.TEST, UserType.TEST, clock);
- PaymentAttempt originalPaymentAttempt = new PaymentAttempt(paymentAttemptId, invoiceId, accountId, invoiceAmount, Currency.USD, clock.getUTCNow(), clock.getUTCNow(), paymentId, 0);
- PaymentAttempt attempt = paymentDao.createPaymentAttempt(originalPaymentAttempt, thisContext);
+ PaymentAttempt originalPaymentAttempt = new PaymentAttempt(paymentAttemptId, invoiceId, accountId, invoiceAmount, Currency.USD, clock.getUTCNow(), clock.getUTCNow(), paymentId, 0, PaymentAttemptStatus.IN_PROCESSING);
+ PaymentAttempt attempt = paymentDao.createPaymentAttempt(originalPaymentAttempt, PaymentAttemptStatus.IN_PROCESSING, thisContext);
List<PaymentAttempt> attemptsFromGet = paymentDao.getPaymentAttemptsForInvoiceId(invoiceId.toString());
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
index 492bf30..ba767c3 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPlugin.java
@@ -40,9 +40,13 @@ import com.ning.billing.payment.api.PaymentInfoEvent;
import com.ning.billing.payment.api.PaymentMethodInfo;
import com.ning.billing.payment.api.PaymentProviderAccount;
import com.ning.billing.payment.api.PaypalPaymentMethodInfo;
+import com.ning.billing.payment.plugin.api.PaymentInfoPlugin;
+import com.ning.billing.payment.plugin.api.PaymentPluginApiException;
+import com.ning.billing.payment.plugin.api.PaymentProviderPlugin;
import com.ning.billing.util.clock.Clock;
public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
+
private final AtomicBoolean makeNextInvoiceFail = new AtomicBoolean(false);
private final Map<String, PaymentInfoEvent> payments = new ConcurrentHashMap<String, PaymentInfoEvent>();
private final Map<String, PaymentProviderAccount> accounts = new ConcurrentHashMap<String, PaymentProviderAccount>();
@@ -59,66 +63,63 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
}
@Override
- public Either<PaymentErrorEvent, PaymentInfoEvent> processInvoice(Account account, Invoice invoice) {
+ public PaymentInfoPlugin processInvoice(Account account, Invoice invoice) throws PaymentPluginApiException {
if (makeNextInvoiceFail.getAndSet(false)) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "test error", account.getId(), invoice.getId(), null));
- }
- else {
- PaymentInfoEvent payment = new DefaultPaymentInfoEvent.Builder().setPaymentId(UUID.randomUUID().toString())
- .setAmount(invoice.getBalance())
- .setStatus("Processed")
- .setBankIdentificationNumber("1234")
- .setCreatedDate(clock.getUTCNow())
- .setEffectiveDate(clock.getUTCNow())
- .setPaymentNumber("12345")
- .setReferenceId("12345")
- .setType("Electronic")
- .build();
- payments.put(payment.getPaymentId(), payment);
- return Either.right(payment);
+ throw new PaymentPluginApiException("", "test error");
}
+ PaymentInfoEvent payment = new DefaultPaymentInfoEvent.Builder().setPaymentId(UUID.randomUUID().toString())
+ .setAmount(invoice.getBalance())
+ .setStatus("Processed")
+ .setBankIdentificationNumber("1234")
+ .setCreatedDate(clock.getUTCNow())
+ .setEffectiveDate(clock.getUTCNow())
+ .setPaymentNumber("12345")
+ .setReferenceId("12345")
+ .setType("Electronic")
+ .build();
+ // STEPH
+ //return payment;
+ return null;
}
+
@Override
- public Either<PaymentErrorEvent, PaymentInfoEvent> getPaymentInfo(String paymentId) {
+ public PaymentInfoPlugin getPaymentInfo(String paymentId) throws PaymentPluginApiException {
PaymentInfoEvent payment = payments.get(paymentId);
-
if (payment == null) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("notfound", "No payment found for id " + paymentId, null, null, null));
- }
- else {
- return Either.right(payment);
+ throw new PaymentPluginApiException("", "No payment found for id " + paymentId);
}
+ // STEPH
+ return null;
}
@Override
- public Either<PaymentErrorEvent, String> createPaymentProviderAccount(Account account) {
+ public String createPaymentProviderAccount(Account account) throws PaymentPluginApiException {
if (account != null) {
String id = String.valueOf(RandomStringUtils.randomAlphanumeric(10));
accounts.put(account.getExternalKey(),
new PaymentProviderAccount.Builder().setAccountKey(account.getExternalKey())
.setId(id)
.build());
-
- return Either.right(id);
+ return id;
}
else {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "Did not get account to create payment provider account", null, null, null));
+ throw new PaymentPluginApiException("", "Did not get account to create payment provider account");
}
}
@Override
- public Either<PaymentErrorEvent, PaymentProviderAccount> getPaymentProviderAccount(String accountKey) {
+ public PaymentProviderAccount getPaymentProviderAccount(String accountKey) throws PaymentPluginApiException {
if (accountKey != null) {
- return Either.right(accounts.get(accountKey));
+ return accounts.get(accountKey);
}
else {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "Did not get account for accountKey " + accountKey, null, null, null));
+ throw new PaymentPluginApiException("", "Did not get account for accountKey " + accountKey);
}
}
@Override
- public Either<PaymentErrorEvent, String> addPaymentMethod(String accountKey, PaymentMethodInfo paymentMethod) {
+ public String addPaymentMethod(String accountKey, PaymentMethodInfo paymentMethod) throws PaymentPluginApiException {
if (paymentMethod != null) {
PaymentProviderAccount account = accounts.get(accountKey);
@@ -133,34 +134,34 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
PaypalPaymentMethodInfo paypalPaymentMethod = (PaypalPaymentMethodInfo)paymentMethod;
realPaymentMethod = new PaypalPaymentMethodInfo.Builder(paypalPaymentMethod)
- .setId(paymentMethodId)
- .setAccountId(accountKey)
- .setDefaultMethod(shouldBeDefault)
- .setBaid(paypalPaymentMethod.getBaid())
- .setEmail(paypalPaymentMethod.getEmail())
- .build();
+ .setId(paymentMethodId)
+ .setAccountId(accountKey)
+ .setDefaultMethod(shouldBeDefault)
+ .setBaid(paypalPaymentMethod.getBaid())
+ .setEmail(paypalPaymentMethod.getEmail())
+ .build();
}
else if (paymentMethod instanceof CreditCardPaymentMethodInfo) {
CreditCardPaymentMethodInfo ccPaymentMethod = (CreditCardPaymentMethodInfo)paymentMethod;
realPaymentMethod = new CreditCardPaymentMethodInfo.Builder(ccPaymentMethod).setId(paymentMethodId).build();
}
if (realPaymentMethod == null) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unsupported", "Payment method " + paymentMethod.getType() + " not supported by the plugin", null, null, null));
+ throw new PaymentPluginApiException("", "Payment method " + paymentMethod.getType() + " not supported by the plugin");
}
else {
if (shouldBeDefault) {
setDefaultPaymentMethodOnAccount(account, paymentMethodId);
}
paymentMethods.put(paymentMethodId, realPaymentMethod);
- return Either.right(paymentMethodId);
+ return paymentMethodId;
}
}
- else {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("noaccount", "Could not retrieve account for accountKey " + accountKey, null, null, null));
- }
+ else {
+ throw new PaymentPluginApiException("", "Could not retrieve account for accountKey " + accountKey);
+ }
}
else {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "Could not create add payment method " + paymentMethod + " for " + accountKey, null, null, null));
+ throw new PaymentPluginApiException("", "Could not create add payment method " + paymentMethod + " for " + accountKey);
}
}
@@ -191,7 +192,7 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
}
@Override
- public Either<PaymentErrorEvent, PaymentMethodInfo> updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethod) {
+ public PaymentMethodInfo updatePaymentMethod(String accountKey, PaymentMethodInfo paymentMethod) throws PaymentPluginApiException {
if (paymentMethod != null) {
PaymentMethodInfo realPaymentMethod = null;
@@ -204,45 +205,43 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
realPaymentMethod = new CreditCardPaymentMethodInfo.Builder(ccPaymentMethod).build();
}
if (realPaymentMethod == null) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unsupported", "Payment method " + paymentMethod.getType() + " not supported by the plugin", null, null, null));
+ throw new PaymentPluginApiException("", "Payment method " + paymentMethod.getType() + " not supported by the plugin");
}
else {
paymentMethods.put(paymentMethod.getId(), paymentMethod);
- return Either.right(realPaymentMethod);
+ return realPaymentMethod;
}
}
else {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "Could not create add payment method " + paymentMethod + " for " + accountKey, null, null, null));
+ throw new PaymentPluginApiException("", "Could not create add payment method " + paymentMethod + " for " + accountKey);
}
}
@Override
- public Either<PaymentErrorEvent, Void> deletePaymentMethod(String accountKey, String paymentMethodId) {
+ public void deletePaymentMethod(String accountKey, String paymentMethodId) throws PaymentPluginApiException {
PaymentMethodInfo paymentMethodInfo = paymentMethods.get(paymentMethodId);
if (paymentMethodInfo != null) {
if (Boolean.FALSE.equals(paymentMethodInfo.getDefaultMethod()) || paymentMethodInfo.getDefaultMethod() == null) {
if (paymentMethods.remove(paymentMethodId) == null) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "Did not get any result back", null, null, null));
+ throw new PaymentPluginApiException("", "Did not get any result back");
}
- }
- else {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("error", "Cannot delete default payment method", null, null, null));
+ } else {
+ throw new PaymentPluginApiException("", "Cannot delete default payment method");
}
}
- return Either.right(null);
+ return;
}
@Override
- public Either<PaymentErrorEvent, PaymentMethodInfo> getPaymentMethodInfo(String paymentMethodId) {
+ public PaymentMethodInfo getPaymentMethodInfo(String paymentMethodId) throws PaymentPluginApiException {
if (paymentMethodId == null) {
- return Either.left((PaymentErrorEvent) new DefaultPaymentErrorEvent("unknown", "Could not retrieve payment method for paymentMethodId " + paymentMethodId, null, null, null));
+ throw new PaymentPluginApiException("", "Could not retrieve payment method for paymentMethodId " + paymentMethodId);
}
-
- return Either.right(paymentMethods.get(paymentMethodId));
+ return paymentMethods.get(paymentMethodId);
}
@Override
- public Either<PaymentErrorEvent, List<PaymentMethodInfo>> getPaymentMethods(final String accountKey) {
+ public List<PaymentMethodInfo> getPaymentMethods(final String accountKey) throws PaymentPluginApiException {
Collection<PaymentMethodInfo> filteredPaymentMethods = Collections2.filter(paymentMethods.values(), new Predicate<PaymentMethodInfo>() {
@Override
@@ -251,27 +250,23 @@ public class MockPaymentProviderPlugin implements PaymentProviderPlugin {
}
});
List<PaymentMethodInfo> result = new ArrayList<PaymentMethodInfo>(filteredPaymentMethods);
- return Either.right(result);
+ return result;
}
@Override
- public Either<PaymentErrorEvent, Void> updatePaymentGateway(String accountKey) {
- return Either.right(null);
+ public void updatePaymentGateway(String accountKey) throws PaymentPluginApiException {
}
@Override
- public Either<PaymentErrorEvent, Void> updatePaymentProviderAccountExistingContact(Account account) {
- // nothing to do here
- return Either.right(null);
+ public void updatePaymentProviderAccountExistingContact(Account account) throws PaymentPluginApiException {
}
@Override
- public Either<PaymentErrorEvent, Void> updatePaymentProviderAccountWithNewContact(Account account) {
- return Either.right(null);
+ public void updatePaymentProviderAccountWithNewContact(Account account) throws PaymentPluginApiException {
}
@Override
- public List<Either<PaymentErrorEvent, PaymentInfoEvent>> processRefund(Account account) {
+ public List<PaymentInfoPlugin> processRefund(Account account) throws PaymentPluginApiException {
return null;
}
}
diff --git a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java
index 05bba03..fa778e9 100644
--- a/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java
+++ b/payment/src/test/java/com/ning/billing/payment/provider/MockPaymentProviderPluginProvider.java
@@ -21,6 +21,7 @@ import com.google.inject.Provider;
import com.ning.billing.util.clock.Clock;
public class MockPaymentProviderPluginProvider implements Provider<MockPaymentProviderPlugin> {
+
private PaymentProviderPluginRegistry registry;
private final String instanceName;
diff --git a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
index 9a49780..77d344a 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestRetryService.java
@@ -49,9 +49,12 @@ import com.ning.billing.payment.api.PaymentAttempt;
import com.ning.billing.payment.api.PaymentErrorEvent;
import com.ning.billing.payment.api.PaymentInfoEvent;
import com.ning.billing.payment.api.PaymentStatus;
+import com.ning.billing.payment.api.PaymentAttempt.PaymentAttemptStatus;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.MockPaymentProviderPlugin;
+import com.ning.billing.payment.provider.DefaultPaymentProviderPluginRegistry;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
+import com.ning.billing.payment.retry.FailedPaymentRetryService;
import com.ning.billing.payment.setup.PaymentTestModuleWithMocks;
import com.ning.billing.util.bus.Bus;
import com.ning.billing.util.callcontext.CallContext;
@@ -84,7 +87,7 @@ public class TestRetryService {
@Inject
private PaymentDao paymentDao;
@Inject
- private RetryService retryService;
+ private FailedPaymentRetryService retryService;
@Inject
private NotificationQueueService notificationQueueService;
@@ -97,7 +100,7 @@ public class TestRetryService {
@BeforeClass(alwaysRun = true)
public void initialize() throws Exception {
- retryService.initialize();
+ retryService.initialize("payment-service");
}
@BeforeMethod(alwaysRun = true)
@@ -106,7 +109,7 @@ public class TestRetryService {
retryService.start();
mockPaymentProviderPlugin = (MockPaymentProviderPlugin)registry.getPlugin(null);
- mockNotificationQueue = (MockNotificationQueue)notificationQueueService.getNotificationQueue(RetryService.SERVICE_NAME, RetryService.QUEUE_NAME);
+ mockNotificationQueue = (MockNotificationQueue)notificationQueueService.getNotificationQueue("payment-service", FailedPaymentRetryService.QUEUE_NAME);
context = new DefaultCallContext("RetryServiceTests", CallOrigin.INTERNAL, UserType.TEST, clock);
((ZombieControl)invoicePaymentApi).addResult("notifyOfPaymentAttempt", BrainDeadProxyFactory.ZOMBIE_VOID);
@@ -142,7 +145,7 @@ public class TestRetryService {
mockPaymentProviderPlugin.makeNextInvoiceFail();
boolean failed = false;
try {
- paymentApi.createPayment(account.getExternalKey(), Arrays.asList(invoice.getId().toString()), context);
+ paymentApi.createPayment(account.getExternalKey(), invoice.getId(), context);
} catch (PaymentApiException e) {
failed = true;
}
@@ -186,12 +189,12 @@ public class TestRetryService {
int numberOfDays = paymentConfig.getPaymentRetryDays().get(0);
DateTime nextRetryDate = now.plusDays(numberOfDays);
- PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice).cloner()
+ PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice, PaymentAttemptStatus.COMPLETED_FAILED).cloner()
.setRetryCount(1)
.setPaymentAttemptDate(now)
.build();
- paymentDao.createPaymentAttempt(paymentAttempt, context);
+ paymentDao.createPaymentAttempt(paymentAttempt, PaymentAttemptStatus.COMPLETED_FAILED, context);
retryService.scheduleRetry(paymentAttempt, nextRetryDate);
((ClockMock)clock).setDeltaFromReality(Days.days(numberOfDays).toStandardSeconds().getSeconds() * 1000);
Thread.sleep(2000);
@@ -199,7 +202,7 @@ public class TestRetryService {
List<Notification> pendingNotifications = mockNotificationQueue.getPendingEvents();
assertEquals(pendingNotifications.size(), 0);
- List<PaymentInfoEvent> paymentInfoList = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId().toString()));
+ List<PaymentInfoEvent> paymentInfoList = paymentApi.getPaymentInfo(Arrays.asList(invoice.getId()));
assertEquals(paymentInfoList.size(), 1);
PaymentInfoEvent paymentInfo = paymentInfoList.get(0);
diff --git a/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java b/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java
index 5312e09..8e30d52 100644
--- a/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java
+++ b/util/src/main/java/com/ning/billing/util/globallocker/GlobalLocker.java
@@ -23,8 +23,8 @@ public interface GlobalLocker {
public enum LockerService {
- // Only service needing global lock
- INVOICE("invoice");
+ INVOICE("invoice"),
+ PAYMENT("payment");
private final String svcName;