killbill-memoizeit

Work on payment retries

2/9/2012 4:29:40 AM

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
+
+    }
+
 }