killbill-aplcache

#69 - Added new "withAttempts" parameter to the getPayments

6/28/2016 12:08:04 PM

Changes

pom.xml 2(+1 -1)

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index 1fd76ed..e22ef70 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -741,7 +741,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         checkODState(OverdueWrapper.CLEAR_STATE_NAME);
 
         // Now, refund the second (first non-zero dollar) invoice
-        final Payment payment = paymentApi.getPayment(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), false, PLUGIN_PROPERTIES, callContext);
+        final Payment payment = paymentApi.getPayment(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), false, false, PLUGIN_PROPERTIES, callContext);
         refundPaymentAndCheckForCompletion(account, payment, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
         // We should now be in OD1
         checkODState("OD1");
@@ -786,7 +786,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
 
         // Now, create a chargeback for the second (first non-zero dollar) invoice
         final InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayments(invoiceUserApi.getInvoicesByAccount(account.getId(), callContext).get(1).getPayments().get(0).getPaymentId(), callContext).get(0);
-        final Payment payment = paymentApi.getPayment(invoicePayment.getPaymentId(), false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(invoicePayment.getPaymentId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
         createChargeBackAndCheckForCompletion(account, payment, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT, NextEvent.BLOCK);
         // We should now be in OD1
         checkODState("OD1");
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java b/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java
index 6eb8afd..9472f6b 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/util/RefundChecker.java
@@ -67,7 +67,7 @@ public class RefundChecker {
 
     public PaymentTransaction checkRefund(final UUID paymentId, final CallContext context, ExpectedRefundCheck expected) throws PaymentApiException {
 
-        final Payment payment = paymentApi.getPayment(paymentId, false, ImmutableList.<PluginProperty>of(), context);
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), context);
         final PaymentTransaction refund = Iterables.tryFind(payment.getTransactions(), new Predicate<PaymentTransaction>() {
             @Override
             public boolean apply(final PaymentTransaction input) {
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
index f37d2e4..a30a99e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/InvoicePaymentJson.java
@@ -25,6 +25,7 @@ import java.util.UUID;
 import javax.annotation.Nullable;
 
 import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PaymentAttempt;
 import org.killbill.billing.util.audit.AccountAuditLogs;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
@@ -51,8 +52,9 @@ public class InvoicePaymentJson extends PaymentJson {
                               @JsonProperty("currency") final String currency,
                               @JsonProperty("paymentMethodId") final String paymentMethodId,
                               @JsonProperty("transactions") final List<? extends PaymentTransactionJson> transactions,
+                              @JsonProperty("nextScheduledPaymentAttempt") final PaymentAttempt nextScheduledPaymentAttempt,
                               @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
-        super(accountId, paymentId, paymentNumber, paymentExternalKey, authAmount, capturedAmount, purchasedAmount, refundedAmount, creditedAmount, currency, paymentMethodId, transactions, auditLogs);
+        super(accountId, paymentId, paymentNumber, paymentExternalKey, authAmount, capturedAmount, purchasedAmount, refundedAmount, creditedAmount, currency, paymentMethodId, transactions, nextScheduledPaymentAttempt, auditLogs);
         this.targetInvoiceId = targetInvoiceId;
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
index 3a85882..bfac104 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/PaymentJson.java
@@ -22,6 +22,7 @@ import java.util.List;
 import javax.annotation.Nullable;
 
 import org.killbill.billing.payment.api.Payment;
+import org.killbill.billing.payment.api.PaymentAttempt;
 import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.util.audit.AccountAuditLogs;
 import org.killbill.billing.util.audit.AuditLog;
@@ -50,6 +51,7 @@ public class PaymentJson extends JsonBase {
     @ApiModelProperty(dataType = "java.util.UUID")
     private final String paymentMethodId;
     private final List<? extends PaymentTransactionJson> transactions;
+    private final PaymentAttempt nextScheduledPaymentAttempt;
 
     @JsonCreator
     public PaymentJson(@JsonProperty("accountId") final String accountId,
@@ -64,6 +66,7 @@ public class PaymentJson extends JsonBase {
                        @JsonProperty("currency") final String currency,
                        @JsonProperty("paymentMethodId") final String paymentMethodId,
                        @JsonProperty("transactions") final List<? extends PaymentTransactionJson> transactions,
+                       @JsonProperty("nextScheduledPaymentAttempt") final PaymentAttempt nextScheduledPaymentAttempt,
                        @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
         this.accountId = accountId;
@@ -78,6 +81,7 @@ public class PaymentJson extends JsonBase {
         this.currency = currency;
         this.paymentMethodId = paymentMethodId;
         this.transactions = transactions;
+        this.nextScheduledPaymentAttempt = nextScheduledPaymentAttempt;
     }
 
     public PaymentJson(final Payment dp, @Nullable final AccountAuditLogs accountAuditLogs) {
@@ -93,6 +97,7 @@ public class PaymentJson extends JsonBase {
              dp.getCurrency() != null ? dp.getCurrency().toString() : null,
              dp.getPaymentMethodId() != null ? dp.getPaymentMethodId().toString() : null,
              getTransactions(dp.getTransactions(), dp.getExternalKey(), accountAuditLogs),
+             dp.getNextScheduledPaymentAttempt(),
              toAuditLogJson(accountAuditLogs == null ? null : accountAuditLogs.getAuditLogsForPayment(dp.getId())));
     }
 
@@ -156,6 +161,8 @@ public class PaymentJson extends JsonBase {
         return transactions;
     }
 
+    public PaymentAttempt getNextScheduledPaymentRetry() { return nextScheduledPaymentAttempt; }
+
     @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder("PaymentJson{");
@@ -171,6 +178,7 @@ public class PaymentJson extends JsonBase {
         sb.append(", currency='").append(currency).append('\'');
         sb.append(", paymentMethodId='").append(paymentMethodId).append('\'');
         sb.append(", transactions=").append(transactions);
+        sb.append(", nextScheduledPaymentAttempt=").append(nextScheduledPaymentAttempt);
         sb.append('}');
         return sb.toString();
     }
@@ -222,6 +230,9 @@ public class PaymentJson extends JsonBase {
         if (transactions != null ? !transactions.equals(that.transactions) : that.transactions != null) {
             return false;
         }
+        if (nextScheduledPaymentAttempt != null ? !nextScheduledPaymentAttempt.equals(that.nextScheduledPaymentAttempt) : that.nextScheduledPaymentAttempt!= null) {
+            return false;
+        }
 
         return true;
     }
@@ -240,6 +251,7 @@ public class PaymentJson extends JsonBase {
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
         result = 31 * result + (paymentMethodId != null ? paymentMethodId.hashCode() : 0);
         result = 31 * result + (transactions != null ? transactions.hashCode() : 0);
+        result = 31 * result + (nextScheduledPaymentAttempt != null ? nextScheduledPaymentAttempt.hashCode() : 0);
         return result;
     }
 }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index ca85ff4..e9090c2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -945,7 +945,7 @@ public class AccountResource extends JaxRsResourceBase {
         //
         final UUID paymentMethodId;
         if (paymentId != null) {
-            final Payment initialPayment = paymentApi.getPayment(paymentId, false, pluginProperties, callContext);
+            final Payment initialPayment = paymentApi.getPayment(paymentId, false, false, pluginProperties, callContext);
             final PaymentTransaction pendingTransaction = lookupPendingTransaction(initialPayment,
                                                                                    json != null ? json.getTransactionId() : null,
                                                                                    json != null ? json.getTransactionExternalKey() : null,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
index ed98edb..b11a23b 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AdminResource.java
@@ -88,7 +88,7 @@ public class AdminResource extends JaxRsResourceBase {
 
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
-        final Payment payment = paymentApi.getPayment(UUID.fromString(paymentIdStr), false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(UUID.fromString(paymentIdStr), false, false, ImmutableList.<PluginProperty>of(), callContext);
 
         final UUID paymentTransactionId = UUID.fromString(paymentTransactionIdStr);
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
index e308641..b9fe9f5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ComboPaymentResource.java
@@ -121,7 +121,7 @@ public abstract class ComboPaymentResource extends JaxRsResourceBase {
         Preconditions.checkArgument(paymentIdStr != null || externalKey != null, "Need to set either paymentId or payment externalKey");
         if (paymentIdStr != null) {
             final UUID paymentId = UUID.fromString(paymentIdStr);
-            return paymentApi.getPayment(paymentId, false, pluginProperties, tenantContext);
+            return paymentApi.getPayment(paymentId, false, false, pluginProperties, tenantContext);
         } else {
             return paymentApi.getPaymentByExternalKey(externalKey, false, pluginProperties, tenantContext);
         }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
index a7b2c9a..6046bd8 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
@@ -118,7 +118,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final UUID paymentIdId = UUID.fromString(paymentIdStr);
         final TenantContext tenantContext = context.createContext(request);
-        final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, pluginProperties, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, false, pluginProperties, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
 
         final List<InvoicePayment> invoicePayments = invoicePaymentApi.getInvoicePayments(paymentIdId, tenantContext);
@@ -154,7 +154,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
 
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(paymentUuid, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
 
         final Iterable<PluginProperty> pluginProperties;
@@ -201,7 +201,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
 
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
         final UUID paymentUuid = UUID.fromString(paymentId);
-        final Payment payment = paymentApi.getPayment(paymentUuid, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(paymentUuid, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
         final String transactionExternalKey = json.getTransactionExternalKey() != null ? json.getTransactionExternalKey() : UUIDs.randomUUID().toString();
 
@@ -272,7 +272,7 @@ public class InvoicePaymentResource extends JaxRsResourceBase {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final UUID paymentId = UUID.fromString(paymentIdString);
         final TenantContext tenantContext = context.createContext(request);
-        final Payment payment = paymentApi.getPayment(paymentId, false, pluginProperties, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, pluginProperties, tenantContext);
         return super.getTags(payment.getAccountId(), paymentId, auditMode, includedDeleted, tenantContext);
     }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index dcb2738..cbdf5d0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -550,6 +550,7 @@ public class InvoiceResource extends JaxRsResourceBase {
     public Response getPayments(@PathParam("invoiceId") final String invoiceId,
                                 @QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
                                 @QueryParam(QUERY_WITH_PLUGIN_INFO) @DefaultValue("false") final Boolean withPluginInfo,
+                                @QueryParam(QUERY_WITH_ATTEMPTS) @DefaultValue("false") final Boolean withAttempts,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) throws PaymentApiException, InvoiceApiException {
 
         final TenantContext tenantContext = context.createContext(request);
@@ -568,7 +569,7 @@ public class InvoiceResource extends JaxRsResourceBase {
 
         final List<Payment> payments = new ArrayList<Payment>();
         for (final UUID paymentId : invoicePaymentIds) {
-            final Payment payment = paymentApi.getPayment(paymentId, withPluginInfo, ImmutableList.<PluginProperty>of(), tenantContext);
+            final Payment payment = paymentApi.getPayment(paymentId, withPluginInfo, withAttempts, ImmutableList.<PluginProperty>of(), tenantContext);
             payments.add(payment);
         }
 
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index 2fdd31e..97cc39c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -100,6 +100,7 @@ public interface JaxrsResource {
 
     public static final String QUERY_PAYMENT_METHOD_PLUGIN_NAME = "pluginName";
     public static final String QUERY_WITH_PLUGIN_INFO = "withPluginInfo";
+    public static final String QUERY_WITH_ATTEMPTS = "withAttemps";
     public static final String QUERY_PAYMENT_METHOD_IS_DEFAULT = "isDefault";
 
     public static final String QUERY_PAY_ALL_UNPAID_INVOICES = "payAllUnpaidInvoices";
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index bf820e2..bde40a5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -112,7 +112,7 @@ public class PaymentResource extends ComboPaymentResource {
         final Iterable<PluginProperty> pluginProperties = extractPluginProperties(pluginPropertiesString);
         final UUID paymentIdId = UUID.fromString(paymentIdStr);
         final TenantContext tenantContext = context.createContext(request);
-        final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, pluginProperties, tenantContext);
+        final Payment payment = paymentApi.getPayment(paymentIdId, withPluginInfo, false, pluginProperties, tenantContext);
         final AccountAuditLogs accountAuditLogs = auditUserApi.getAccountAuditLogs(payment.getAccountId(), auditMode.getLevel(), tenantContext);
         final PaymentJson result = new PaymentJson(payment, accountAuditLogs);
         return Response.status(Response.Status.OK).entity(result).build();
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
index f994dd7..1d43388 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
@@ -95,7 +95,7 @@ public class TransactionResource extends JaxRsResourceBase {
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final UUID paymentId = UUID.fromString(json.getPaymentId());
-        final Payment payment = paymentApi.getPayment(paymentId, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment payment = paymentApi.getPayment(paymentId, false, false, ImmutableList.<PluginProperty>of(), callContext);
         final Account account = accountUserApi.getAccountById(payment.getAccountId(), callContext);
 
         final boolean success = TransactionStatus.SUCCESS.name().equals(json.getStatus());
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java
index 7303f80..f2b9168 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPayment.java
@@ -52,18 +52,21 @@ public class DefaultPayment extends EntityBase implements Payment {
 
     private final Currency currency;
     private final List<PaymentTransaction> transactions;
+    private final PaymentAttempt nextScheduledPaymentAttempt;
 
     public DefaultPayment(final UUID id, @Nullable final DateTime createdDate, @Nullable final DateTime updatedDate, final UUID accountId,
                           final UUID paymentMethodId,
                           final Integer paymentNumber,
                           final String externalKey,
-                          final List<PaymentTransaction> transactions) {
+                          final List<PaymentTransaction> transactions,
+                          @Nullable final PaymentAttempt nextScheduledPaymentAttempt) {
         super(id, createdDate, updatedDate);
         this.accountId = accountId;
         this.paymentMethodId = paymentMethodId;
         this.paymentNumber = paymentNumber;
         this.externalKey = externalKey;
         this.transactions = transactions;
+        this.nextScheduledPaymentAttempt = nextScheduledPaymentAttempt;
 
         final Collection<PaymentTransaction> voidedTransactions = new LinkedList<PaymentTransaction>();
         final Collection<PaymentTransaction> nonVoidedTransactions = new LinkedList<PaymentTransaction>();
@@ -345,6 +348,9 @@ public class DefaultPayment extends EntityBase implements Payment {
     }
 
     @Override
+    public PaymentAttempt getNextScheduledPaymentAttempt() { return nextScheduledPaymentAttempt; }
+
+    @Override
     public String toString() {
         final StringBuilder sb = new StringBuilder("DefaultPayment{");
         sb.append("accountId=").append(accountId);
@@ -357,6 +363,7 @@ public class DefaultPayment extends EntityBase implements Payment {
         sb.append(", refundAmount=").append(refundAmount);
         sb.append(", currency=").append(currency);
         sb.append(", transactions=").append(transactions);
+        sb.append(", nextScheduledPaymentAttempt=").append(nextScheduledPaymentAttempt);
         sb.append('}');
         return sb.toString();
     }
@@ -405,6 +412,9 @@ public class DefaultPayment extends EntityBase implements Payment {
         if (transactions != null ? !transactions.equals(that.transactions) : that.transactions != null) {
             return false;
         }
+        if (nextScheduledPaymentAttempt != null ? !nextScheduledPaymentAttempt.equals(that.nextScheduledPaymentAttempt) : that.nextScheduledPaymentAttempt!= null) {
+            return false;
+        }
 
         return true;
     }
@@ -422,6 +432,7 @@ public class DefaultPayment extends EntityBase implements Payment {
         result = 31 * result + (refundAmount != null ? refundAmount.hashCode() : 0);
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
         result = 31 * result + (transactions != null ? transactions.hashCode() : 0);
+        result = 31 * result + (nextScheduledPaymentAttempt != null ? nextScheduledPaymentAttempt.hashCode() : 0);
         return result;
     }
 }
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
index 9f2d5b6..30516ed 100644
--- a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentApi.java
@@ -720,8 +720,8 @@ public class DefaultPaymentApi extends DefaultApiBase implements PaymentApi {
     }
 
     @Override
-    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
-        final Payment payment = paymentProcessor.getPayment(paymentId, withPluginInfo, properties, context, internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context));
+    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final boolean withAttempts, final Iterable<PluginProperty> properties, final TenantContext context) throws PaymentApiException {
+        final Payment payment = paymentProcessor.getPayment(paymentId, withPluginInfo, withAttempts, properties, context, internalCallContextFactory.createInternalTenantContext(paymentId, ObjectType.PAYMENT, context));
         if (payment == null) {
             throw new PaymentApiException(ErrorCode.PAYMENT_NO_SUCH_PAYMENT, paymentId);
         }
diff --git a/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java
new file mode 100644
index 0000000..efdc63b
--- /dev/null
+++ b/payment/src/main/java/org/killbill/billing/payment/api/DefaultPaymentAttempt.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2016 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.payment.api;
+
+import java.math.BigDecimal;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.entity.EntityBase;
+
+public class DefaultPaymentAttempt extends EntityBase implements PaymentAttempt {
+
+    private final UUID paymentId;
+    private final TransactionType transactionType;
+    private final DateTime effectiveDate;
+    private final TransactionStatus status;
+    private final BigDecimal amount;
+    private final Currency currency;
+
+    public DefaultPaymentAttempt(final UUID id, final UUID paymentId,
+                                 final TransactionType transactionType, final DateTime effectiveDate,
+                                 final TransactionStatus status, final BigDecimal amount, final Currency currency) {
+        super(id);
+        this.paymentId = paymentId;
+        this.transactionType = transactionType;
+        this.effectiveDate = effectiveDate;
+        this.status = status;
+        this.amount = amount;
+        this.currency = currency;
+    }
+
+    @Override
+    public UUID getPaymentId() {
+        return paymentId;
+    }
+
+    @Override
+    public TransactionType getTransactionType() {
+        return transactionType;
+    }
+
+    @Override
+    public DateTime getEffectiveDate() {
+        return effectiveDate;
+    }
+
+    @Override
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    @Override
+    public Currency getCurrency() {
+        return currency;
+    }
+
+    @Override
+    public TransactionStatus getTransactionStatus() {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder("DefaultPaymentTransaction{");
+        sb.append("paymentId=").append(paymentId);
+        sb.append(", transactionType=").append(transactionType);
+        sb.append(", effectiveDate=").append(effectiveDate);
+        sb.append(", status=").append(status);
+        sb.append(", amount=").append(amount);
+        sb.append(", currency=").append(currency);
+        sb.append('}');
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(final Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        if (!super.equals(o)) {
+            return false;
+        }
+
+        final DefaultPaymentAttempt that = (DefaultPaymentAttempt) o;
+
+        if (amount != null ? amount.compareTo(that.amount) != 0 : that.amount != null) {
+            return false;
+        }
+        if (currency != that.currency) {
+            return false;
+        }
+        if (paymentId != null ? !paymentId.equals(that.paymentId) : that.paymentId != null) {
+            return false;
+        }
+        if (effectiveDate != null ? effectiveDate.compareTo(that.effectiveDate) != 0 : that.effectiveDate != null) {
+            return false;
+        }
+        if (status != that.status) {
+            return false;
+        }
+        if (transactionType != that.transactionType) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = super.hashCode();
+        result = 31 * result + (paymentId != null ? paymentId.hashCode() : 0);
+        result = 31 * result + (transactionType != null ? transactionType.hashCode() : 0);
+        result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
+        result = 31 * result + (status != null ? status.hashCode() : 0);
+        result = 31 * result + (amount != null ? amount.hashCode() : 0);
+        result = 31 * result + (currency != null ? currency.hashCode() : 0);
+        return result;
+    }
+}
diff --git a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
index f9b3dde..812fa29 100644
--- a/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
+++ b/payment/src/main/java/org/killbill/billing/payment/core/PaymentProcessor.java
@@ -31,6 +31,7 @@ import java.util.UUID;
 import javax.annotation.Nullable;
 import javax.inject.Inject;
 
+import org.joda.time.DateTime;
 import org.killbill.automaton.OperationResult;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.account.api.Account;
@@ -41,9 +42,11 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.InvoiceInternalApi;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.api.DefaultPayment;
+import org.killbill.billing.payment.api.DefaultPaymentAttempt;
 import org.killbill.billing.payment.api.DefaultPaymentTransaction;
 import org.killbill.billing.payment.api.Payment;
 import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentAttempt;
 import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.api.TransactionStatus;
@@ -60,6 +63,7 @@ import org.killbill.billing.tag.TagInternalApi;
 import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.callcontext.InternalCallContextFactory;
 import org.killbill.billing.util.callcontext.TenantContext;
+import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.billing.util.entity.DefaultPagination;
 import org.killbill.billing.util.entity.Pagination;
 import org.killbill.billing.util.entity.dao.DefaultPaginationHelper.EntityPaginationBuilder;
@@ -71,6 +75,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Function;
 import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Iterators;
@@ -86,6 +91,7 @@ public class PaymentProcessor extends ProcessorBase {
 
     private final PaymentAutomatonRunner paymentAutomatonRunner;
     private final IncompletePaymentTransactionTask incompletePaymentTransactionTask;
+    private final PaymentConfig paymentConfig;
 
     private static final Logger log = LoggerFactory.getLogger(PaymentProcessor.class);
 
@@ -99,10 +105,12 @@ public class PaymentProcessor extends ProcessorBase {
                             final GlobalLocker locker,
                             final PaymentAutomatonRunner paymentAutomatonRunner,
                             final IncompletePaymentTransactionTask incompletePaymentTransactionTask,
+                            final PaymentConfig paymentConfig,
                             final Clock clock) {
         super(pluginRegistry, accountUserApi, paymentDao, tagUserApi, locker, internalCallContextFactory, invoiceApi, clock);
         this.paymentAutomatonRunner = paymentAutomatonRunner;
         this.incompletePaymentTransactionTask = incompletePaymentTransactionTask;
+        this.paymentConfig = paymentConfig;
     }
 
     public Payment createAuthorization(final boolean isApiPayment, @Nullable final UUID attemptId, final Account account, @Nullable final UUID paymentMethodId, @Nullable final UUID paymentId, final BigDecimal amount, final Currency currency,
@@ -190,7 +198,7 @@ public class PaymentProcessor extends ProcessorBase {
                                                                                                         pluginInfo = getPaymentTransactionInfoPluginsIfNeeded(pluginApi, paymentModelDao, context);
                                                                                                     }
 
-                                                                                                    return toPayment(paymentModelDao, transactionsModelDao, pluginInfo, tenantContext);
+                                                                                                    return toPayment(paymentModelDao, transactionsModelDao, pluginInfo, false, tenantContext);
                                                                                                 }
                                                                                             });
 
@@ -198,12 +206,12 @@ public class PaymentProcessor extends ProcessorBase {
         return ImmutableList.<Payment>copyOf(transformedPayments);
     }
 
-    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
+    public Payment getPayment(final UUID paymentId, final boolean withPluginInfo, final boolean withAttempts, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
         final PaymentModelDao paymentModelDao = paymentDao.getPayment(paymentId, internalTenantContext);
         if (paymentModelDao == null) {
             return null;
         }
-        return toPayment(paymentModelDao, withPluginInfo, properties, tenantContext, internalTenantContext);
+        return toPayment(paymentModelDao, withPluginInfo, withAttempts, properties, tenantContext, internalTenantContext);
     }
 
     public Payment getPaymentByExternalKey(final String paymentExternalKey, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext tenantContext, final InternalTenantContext internalTenantContext) throws PaymentApiException {
@@ -211,7 +219,7 @@ public class PaymentProcessor extends ProcessorBase {
         if (paymentModelDao == null) {
             return null;
         }
-        return toPayment(paymentModelDao, withPluginInfo, properties, tenantContext, internalTenantContext);
+        return toPayment(paymentModelDao, withPluginInfo, false, properties, tenantContext, internalTenantContext);
     }
 
     public Pagination<Payment> getPayments(final Long offset, final Long limit, final boolean withPluginInfo, final Iterable<PluginProperty> properties,
@@ -351,7 +359,7 @@ public class PaymentProcessor extends ProcessorBase {
                                                                  properties,
                                                                  callContext,
                                                                  internalCallContext);
-        return getPayment(nonNullPaymentId, true, properties, callContext, internalCallContext);
+        return getPayment(nonNullPaymentId, true, false, properties, callContext, internalCallContext);
     }
 
     // Used in bulk get API (getAccountPayments / getPayments)
@@ -384,26 +392,27 @@ public class PaymentProcessor extends ProcessorBase {
             return null;
         }
 
-        return toPayment(paymentModelDao, pluginTransactions, tenantContext);
+        return toPayment(paymentModelDao, pluginTransactions, false, tenantContext);
     }
 
     // Used in single get APIs (getPayment / getPaymentByExternalKey)
-    private Payment toPayment(final PaymentModelDao paymentModelDao, final boolean withPluginInfo, final Iterable<PluginProperty> properties, final TenantContext context, final InternalTenantContext tenantContext) throws PaymentApiException {
+    private Payment toPayment(final PaymentModelDao paymentModelDao, final boolean withPluginInfo, final boolean withAttempts, final Iterable<PluginProperty> properties, final TenantContext context, final InternalTenantContext tenantContext) throws PaymentApiException {
         final PaymentPluginApi plugin = getPaymentProviderPlugin(paymentModelDao.getPaymentMethodId(), tenantContext);
         final List<PaymentTransactionInfoPlugin> pluginTransactions = withPluginInfo ? getPaymentTransactionInfoPlugins(plugin, paymentModelDao, properties, context) : null;
 
-        return toPayment(paymentModelDao, pluginTransactions, tenantContext);
+        return toPayment(paymentModelDao, pluginTransactions, withAttempts, tenantContext);
     }
 
-    private Payment toPayment(final PaymentModelDao paymentModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions, final InternalTenantContext tenantContext) {
+    private Payment toPayment(final PaymentModelDao paymentModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions,
+                              final boolean withAttempts, final InternalTenantContext tenantContext) {
         final InternalTenantContext tenantContextWithAccountRecordId = getInternalTenantContextWithAccountRecordId(paymentModelDao.getAccountId(), tenantContext);
         final List<PaymentTransactionModelDao> transactionsForPayment = paymentDao.getTransactionsForPayment(paymentModelDao.getId(), tenantContextWithAccountRecordId);
 
-        return toPayment(paymentModelDao, transactionsForPayment, pluginTransactions, tenantContextWithAccountRecordId);
+        return toPayment(paymentModelDao, transactionsForPayment, pluginTransactions, withAttempts, tenantContextWithAccountRecordId);
     }
 
     // Used in bulk get API (getAccountPayments)
-    private Payment toPayment(final PaymentModelDao curPaymentModelDao, final Iterable<PaymentTransactionModelDao> curTransactionsModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions, final InternalTenantContext internalTenantContext) {
+    private Payment toPayment(final PaymentModelDao curPaymentModelDao, final Iterable<PaymentTransactionModelDao> curTransactionsModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions, final boolean withAttempts, final InternalTenantContext internalTenantContext) {
         final Ordering<PaymentTransaction> perPaymentTransactionOrdering = Ordering.<PaymentTransaction>from(new Comparator<PaymentTransaction>() {
             @Override
             public int compare(final PaymentTransaction o1, final PaymentTransaction o2) {
@@ -462,7 +471,54 @@ public class PaymentProcessor extends ProcessorBase {
                                   curPaymentModelDao.getPaymentMethodId(),
                                   curPaymentModelDao.getPaymentNumber(),
                                   curPaymentModelDao.getExternalKey(),
-                                  sortedTransactions);
+                                  sortedTransactions,
+                                  (withAttempts && !sortedTransactions.isEmpty()) ? getNextRetryDateForFailedPayment(sortedTransactions) : null
+                                  );
+    }
+
+    private PaymentAttempt getNextRetryDateForFailedPayment(final List<PaymentTransaction> purchasedTransactions) {
+        DateTime nextDateTime = null;
+        final List<Integer> retryDays = paymentConfig.getPaymentFailureRetryDays();
+        final int attemptsInState = getNumberAttemptsInState(purchasedTransactions, TransactionStatus.PAYMENT_FAILURE);
+        final int retryCount = (attemptsInState - 1) >= 0 ? (attemptsInState - 1) : 0;
+        if (retryCount < retryDays.size()) {
+            final int retryInDays;
+            final DateTime nextRetryDate = clock.getUTCNow();
+            try {
+                retryInDays = retryDays.get(retryCount);
+                nextDateTime = nextRetryDate.plusDays(retryInDays);
+                log.debug("Next retryDate={}, retryInDays={}, retryCount={}, now={}", nextDateTime, retryInDays, retryCount, clock.getUTCNow());
+            } catch (final NumberFormatException ex) {
+                log.error("Could not get retry day for retry count {}", retryCount);
+            }
+        }
+        PaymentTransaction lastAttempt = purchasedTransactions.get(purchasedTransactions.size() - 1);
+        return new DefaultPaymentAttempt(
+                UUID.randomUUID(),
+                lastAttempt.getPaymentId(),
+                lastAttempt.getTransactionType(),
+                nextDateTime,
+                TransactionStatus.SCHEDULED,
+                lastAttempt.getAmount(),
+                lastAttempt.getCurrency()
+        );
+    }
+
+    private int getNumberAttemptsInState(final Collection<PaymentTransaction> allTransactions, final TransactionStatus... statuses) {
+        if (allTransactions == null || allTransactions.size() == 0) {
+            return 0;
+        }
+        return Collections2.filter(allTransactions, new Predicate<PaymentTransaction>() {
+            @Override
+            public boolean apply(final PaymentTransaction input) {
+                for (final TransactionStatus cur : statuses) {
+                    if (input.getTransactionStatus() == cur) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }).size();
     }
 
     private PaymentTransactionInfoPlugin findPaymentTransactionInfoPlugin(final PaymentTransactionModelDao paymentTransactionModelDao, @Nullable final Iterable<PaymentTransactionInfoPlugin> pluginTransactions) {
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultPayment.java b/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultPayment.java
index 6bf1743..85e0a0a 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultPayment.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestDefaultPayment.java
@@ -220,6 +220,7 @@ public class TestDefaultPayment extends PaymentTestSuiteNoDB {
                                   UUID.randomUUID(),
                                   1,
                                   UUID.randomUUID().toString(),
-                                  transactions);
+                                  transactions,
+                                  null);
     }
 }
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestExternalPaymentPlugin.java b/payment/src/test/java/org/killbill/billing/payment/api/TestExternalPaymentPlugin.java
index 2e6f46e..589ec38 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestExternalPaymentPlugin.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestExternalPaymentPlugin.java
@@ -60,8 +60,8 @@ public class TestExternalPaymentPlugin extends PaymentTestSuiteWithEmbeddedDB {
         final Payment payment = paymentApi.createPurchase(account, account.getPaymentMethodId(), null, requestedAmount, Currency.AED, paymentExternalKey, transactionExternalKey,
                                                           ImmutableList.<PluginProperty>of(), callContext);
 
-        final Payment paymentPluginInfoFalse = paymentApi.getPayment(payment.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
-        final Payment paymentPluginInfoTrue = paymentApi.getPayment(payment.getId(), true, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment paymentPluginInfoFalse = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment paymentPluginInfoTrue = paymentApi.getPayment(payment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext);
 
         Assert.assertEquals(paymentPluginInfoFalse.getAccountId(), paymentPluginInfoTrue.getAccountId());
 
diff --git a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
index a00a2c2..d7cb18f 100644
--- a/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
+++ b/payment/src/test/java/org/killbill/billing/payment/api/TestPaymentApi.java
@@ -1340,7 +1340,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
             assertEquals(e.getCode(), ErrorCode.PAYMENT_NO_SUCH_SUCCESS_PAYMENT.getCode());
         }
 
-        assertEquals(paymentApi.getPayment(payment.getId(), false, ImmutableList.<PluginProperty>of(), callContext).getTransactions().size(), 1);
+        assertEquals(paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext).getTransactions().size(), 1);
 
         assertEquals(paymentDao.getPayment(payment.getId(), internalCallContext).getStateName(), "PURCHASE_SUCCESS");
         assertEquals(paymentDao.getPayment(payment.getId(), internalCallContext).getLastSuccessStateName(), "PURCHASE_SUCCESS");
@@ -1400,7 +1400,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         } catch (final PaymentApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_NO_SUCH_PAYMENT.getCode());
 
-            final Payment latestPayment = paymentApi.getPayment(initialPayment.getId(), true, ImmutableList.<PluginProperty>of(), callContext);
+            final Payment latestPayment = paymentApi.getPayment(initialPayment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext);
             assertEquals(latestPayment, initialPayment);
         }
     }
@@ -1418,7 +1418,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
         } catch (final PaymentApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.PAYMENT_INVALID_PARAMETER.getCode());
 
-            final Payment latestPayment = paymentApi.getPayment(initialPayment.getId(), true, ImmutableList.<PluginProperty>of(), callContext);
+            final Payment latestPayment = paymentApi.getPayment(initialPayment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext);
             assertEquals(latestPayment, initialPayment);
         }
     }
@@ -1760,7 +1760,7 @@ public class TestPaymentApi extends PaymentTestSuiteWithEmbeddedDB {
 
     private void verifyPaymentViaGetPath(final Payment payment) throws PaymentApiException {
         // We can't use Assert.assertEquals because the updateDate may have been updated by the Janitor
-        final Payment refreshedPayment = paymentApi.getPayment(payment.getId(), true, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment refreshedPayment = paymentApi.getPayment(payment.getId(), true, false, ImmutableList.<PluginProperty>of(), callContext);
 
         Assert.assertEquals(refreshedPayment.getAccountId(), payment.getAccountId());
 
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/MockRetryAuthorizeOperationCallback.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/MockRetryAuthorizeOperationCallback.java
index 07f878b..b10b72f 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/MockRetryAuthorizeOperationCallback.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/MockRetryAuthorizeOperationCallback.java
@@ -19,12 +19,11 @@ package org.killbill.billing.payment.core.sm;
 import java.util.Collections;
 
 import org.killbill.automaton.OperationResult;
-import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.api.DefaultPayment;
 import org.killbill.billing.payment.api.DefaultPaymentTransaction;
 import org.killbill.billing.payment.api.Payment;
-import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.payment.api.PaymentApiException;
+import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.payment.api.TransactionStatus;
 import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.payment.core.sm.control.AuthorizeControlOperation;
@@ -34,7 +33,6 @@ import org.killbill.billing.payment.dao.PaymentDao;
 import org.killbill.billing.payment.dao.PaymentModelDao;
 import org.killbill.billing.payment.dao.PaymentTransactionModelDao;
 import org.killbill.billing.payment.dispatcher.PluginDispatcher;
-import org.killbill.billing.control.plugin.api.PaymentControlPluginApi;
 import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.clock.Clock;
 import org.killbill.commons.locker.GlobalLocker;
@@ -108,7 +106,7 @@ public class MockRetryAuthorizeOperationCallback extends AuthorizeControlOperati
                                                                                                   null);
 
         return new DefaultPayment(paymentModelDao.getId(), paymentModelDao.getCreatedDate(), paymentModelDao.getUpdatedDate(), paymentModelDao.getAccountId(),
-                                        paymentModelDao.getPaymentMethodId(), paymentModelDao.getPaymentNumber(), paymentModelDao.getExternalKey(), Collections.singletonList(convertedTransaction));
+                                        paymentModelDao.getPaymentMethodId(), paymentModelDao.getPaymentNumber(), paymentModelDao.getExternalKey(), Collections.singletonList(convertedTransaction), null);
     }
 
     public MockRetryAuthorizeOperationCallback setException(final Exception exception) {
diff --git a/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java b/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
index ccf0a1c..2c3efba 100644
--- a/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
+++ b/payment/src/test/java/org/killbill/billing/payment/TestJanitor.java
@@ -301,7 +301,7 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
         assertNotificationsCompleted(internalCallContext, 5);
         testListener.assertListenerStatus();
 
-        final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
         assertEquals(updatedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
     }
 
@@ -341,7 +341,7 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
         Assert.assertEquals(paymentTransactionHistoryAfterJanitor.size(), 4);
         Assert.assertEquals(paymentTransactionHistoryAfterJanitor.get(3).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
 
-        final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
         // Janitor should have moved us to PAYMENT_FAILURE
         assertEquals(updatedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PAYMENT_FAILURE);
     }
@@ -411,7 +411,7 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
 
         assertNotificationsCompleted(internalCallContext, 5);
         testListener.assertListenerStatus();
-        final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+        final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
         Assert.assertEquals(updatedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.SUCCESS);
     }
 
@@ -458,7 +458,7 @@ public class TestJanitor extends PaymentTestSuiteWithEmbeddedDB {
             Thread.sleep(1000);
             assertNotificationsCompleted(internalCallContext, 5);
 
-            final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, ImmutableList.<PluginProperty>of(), callContext);
+            final Payment updatedPayment = paymentApi.getPayment(payment.getId(), false, false, ImmutableList.<PluginProperty>of(), callContext);
             Assert.assertEquals(updatedPayment.getTransactions().get(0).getTransactionStatus(), TransactionStatus.PENDING);
         }
 

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index fa5ba51..1fa36ba 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.94.1</version>
+        <version>0.94.4-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.16.7-SNAPSHOT</version>