Details
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 9d38f76..d708be3 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
@@ -265,6 +265,7 @@ public class PaymentAttempt {
createdDate,
updatedDate);
}
+
}
@Override
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 1d78623..5a0e2f1 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
@@ -23,6 +23,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
+import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,12 +35,14 @@ import com.ning.billing.invoice.api.InvoicePaymentApi;
import com.ning.billing.payment.dao.PaymentDao;
import com.ning.billing.payment.provider.PaymentProviderPlugin;
import com.ning.billing.payment.provider.PaymentProviderPluginRegistry;
+import com.ning.billing.payment.setup.PaymentConfig;
public class DefaultPaymentApi implements PaymentApi {
private final PaymentProviderPluginRegistry pluginRegistry;
private final AccountUserApi accountUserApi;
private final InvoicePaymentApi invoicePaymentApi;
private final PaymentDao paymentDao;
+ private final PaymentConfig config;
private static final Logger log = LoggerFactory.getLogger(DefaultPaymentApi.class);
@@ -47,11 +50,13 @@ public class DefaultPaymentApi implements PaymentApi {
public DefaultPaymentApi(PaymentProviderPluginRegistry pluginRegistry,
AccountUserApi accountUserApi,
InvoicePaymentApi invoicePaymentApi,
- PaymentDao paymentDao) {
+ PaymentDao paymentDao,
+ PaymentConfig config) {
this.pluginRegistry = pluginRegistry;
this.accountUserApi = accountUserApi;
this.invoicePaymentApi = invoicePaymentApi;
this.paymentDao = paymentDao;
+ this.config = config;
}
@Override
@@ -125,6 +130,42 @@ public class DefaultPaymentApi implements PaymentApi {
return createPayment(account, invoiceIds);
}
+ private void addRetry(UUID paymentAttemptId, String error) {
+// PaymentAttempt paymentAttempt = paymentDao.getPaymentAttemptById(paymentAttemptId);
+// final List<String> retryDays = config.getPaymentRetryDays();
+//
+// int retryCount = 0;
+//
+// if (paymentAttempt != null && paymentAttempt.getRetryCount() != null) {
+// retryCount = paymentAttempt.getRetryCount();
+// }
+//
+// if (retryCount < retryDays.size()) {
+// int retryInDays = 0;
+// DateTime nextRetryDate = new DateTime(DateTimeZone.UTC);
+//
+// try {
+// retryInDays = Integer.valueOf(retryDays.get(retryCount));
+// nextRetryDate = nextRetryDate.plusDays(retryInDays);
+// }
+// catch (NumberFormatException ex) {
+// log.error("Could not get retry day for retry count {}", retryCount);
+// }
+//
+// PaymentAttemptRetry updatedPaymentAttemptRetry = paymentAttempt.cloner().setRetryCount(retryCount + 1)
+// .setNextRetryDate(nextRetryDate)
+// .build();
+//
+// paymentDao.updatePaymentAttempt(updatedPaymentAttemptRetry);
+// }
+// else if (retryCount == retryDays.size()) {
+// log.info("Last payment retry failed for {} ", paymentAttempt);
+// }
+// else {
+// log.error("Cannot update payment retry information because retry count is invalid {} ", retryCount);
+// }
+ }
+
@Override
public List<Either<PaymentError, PaymentInfo>> createPayment(Account account, List<String> invoiceIds) {
final PaymentProviderPlugin plugin = getPaymentProviderPlugin(account);
@@ -149,6 +190,13 @@ public class DefaultPaymentApi implements PaymentApi {
PaymentInfo paymentInfo = null;
+ if (paymentOrError.isLeft()) {
+ String error = StringUtils.substring(paymentOrError.getLeft().getMessage() + paymentOrError.getLeft().getType(), 0, 100);
+ log.info("Could not process a payment for " + paymentAttempt + " error was " + error);
+
+ addRetry(paymentAttempt.getPaymentAttemptId(), error);
+ }
+
if (paymentOrError.isRight()) {
paymentInfo = paymentOrError.getRight();
paymentDao.savePaymentInfo(paymentInfo);
diff --git a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
index eacc226..9cc46a4 100644
--- a/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
+++ b/payment/src/main/java/com/ning/billing/payment/dao/DefaultPaymentDao.java
@@ -66,4 +66,16 @@ public class DefaultPaymentDao implements PaymentDao {
sqlDao.updatePaymentInfo(type, paymentId, cardType, cardCountry);
}
+ @Override
+ public PaymentAttempt getPaymentAttemptById(UUID paymentAttemptId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void updatePaymentAttempt(PaymentAttempt updatedPaymentAttempt) {
+ // TODO Auto-generated method stub
+
+ }
+
}
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 5cf065b..a70098b 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
@@ -36,4 +36,8 @@ public interface PaymentDao {
void updatePaymentInfo(String paymentMethodType, String paymentId, String cardType, String cardCountry);
+ PaymentAttempt getPaymentAttemptById(UUID paymentAttemptId);
+
+ void updatePaymentAttempt(PaymentAttempt updatedPaymentAttempt);
+
}
diff --git a/payment/src/main/java/com/ning/billing/payment/setup/PaymentConfig.java b/payment/src/main/java/com/ning/billing/payment/setup/PaymentConfig.java
index cdc5384..83cb89b 100644
--- a/payment/src/main/java/com/ning/billing/payment/setup/PaymentConfig.java
+++ b/payment/src/main/java/com/ning/billing/payment/setup/PaymentConfig.java
@@ -16,11 +16,30 @@
package com.ning.billing.payment.setup;
+import java.util.List;
+
import org.skife.config.Config;
+import org.skife.config.Default;
import org.skife.config.DefaultNull;
+import org.skife.config.TimeSpan;
public interface PaymentConfig {
@Config("killbill.payment.provider.default")
@DefaultNull
public String getDefaultPaymentProvider();
+
+ @Config("killbill.payment.retry.days")
+ @DefaultNull
+ public List<String> getPaymentRetryDays();
+
+ @Config("killbill.payment.retry.pause")
+ // payment retry job is off by default
+ @DefaultNull
+ TimeSpan getPaymentRetrySchedulePause();
+
+ @Config("killbill.payment.retry.claim.timeout")
+ // if payment retry job is on, then retry abandoned payment attempts after some period of time
+ @Default("1h")
+ TimeSpan getPaymentRetryClaimTimeout();
+
}
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 bb83927..35ebceb 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
@@ -76,4 +76,16 @@ public class MockPaymentDao implements PaymentDao {
}
+ @Override
+ public PaymentAttempt getPaymentAttemptById(UUID paymentAttemptId) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void updatePaymentAttempt(PaymentAttempt updatedPaymentAttempt) {
+ // TODO Auto-generated method stub
+
+ }
+
}