killbill-memoizeit

Changed invoice payment notification

1/13/2012 10:18:21 PM

Changes

Details

diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
index b339d0f..aaa89a5 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoicePaymentApi.java
@@ -26,9 +26,6 @@ import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.payment.api.InvoicePayment;
 
 public interface InvoicePaymentApi {
-    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentDate);
-
-    public void paymentFailed(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate);
 
     public List<Invoice> getInvoicesByAccount(UUID accountId);
 
@@ -36,5 +33,12 @@ public interface InvoicePaymentApi {
 
     public Invoice getInvoiceForPaymentAttemptId(UUID paymentAttemptId);
 
-    InvoicePayment getInvoicePayment(UUID paymentAttemptId);
+    public InvoicePayment getInvoicePayment(UUID paymentAttemptId);
+
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment);
+
+    public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate);
+
+    public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate);
+
 }
diff --git a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
index 2c8d02e..ed4e671 100644
--- a/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
+++ b/api/src/main/java/com/ning/billing/invoice/api/InvoiceUserApi.java
@@ -16,12 +16,12 @@
 
 package com.ning.billing.invoice.api;
 
-import org.joda.time.DateTime;
-
-import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
-import com.ning.billing.catalog.api.Currency;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.payment.api.InvoicePayment;
 
 public interface InvoiceUserApi {
     public List<UUID> getInvoicesForPayment(DateTime targetDate, int numberOfDays);
@@ -30,8 +30,10 @@ public interface InvoiceUserApi {
 
     public Invoice getInvoice(UUID invoiceId);
 
-    public void paymentAttemptFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate);
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment);
 
-    public void paymentAttemptSuccessful(UUID invoiceId, BigDecimal amount, Currency currency,
-                                         UUID paymentId, DateTime paymentDate);
+//    public void paymentAttemptFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate);
+//
+//    public void paymentAttemptSuccessful(UUID invoiceId, BigDecimal amount, Currency currency,
+//                                         UUID paymentId, DateTime paymentDate);
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/InvoicePayment.java b/api/src/main/java/com/ning/billing/payment/api/InvoicePayment.java
index aaed6ff..c43c179 100644
--- a/api/src/main/java/com/ning/billing/payment/api/InvoicePayment.java
+++ b/api/src/main/java/com/ning/billing/payment/api/InvoicePayment.java
@@ -32,10 +32,14 @@ public class InvoicePayment {
 
         public InvoicePayment(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
             this.invoiceId = invoiceId;
-            this.paymentAttemptId = paymentAttemptId;
-            this.paymentAttemptDate = paymentAttemptDate;
             this.amount = amount;
             this.currency = currency;
+            this.paymentAttemptId = paymentAttemptId;
+            this.paymentAttemptDate = paymentAttemptDate;
+        }
+
+        public InvoicePayment(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+            this(invoiceId, null, null, paymentAttemptId, paymentAttemptDate);
         }
 
         public UUID getInvoiceId() {
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 58016e0..0e330a0 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
@@ -16,35 +16,51 @@
 
 package com.ning.billing.payment.api;
 
+import java.math.BigDecimal;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
 import org.joda.time.DateTimeZone;
 
+import com.google.common.base.Objects;
+import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 
 public class PaymentAttempt {
     private final UUID paymentAttemptId;
+    private final UUID invoiceId;
+    private final UUID accountId;
+    private final BigDecimal amount;
+    private final Currency currency;
     private final String paymentId;
+    private final DateTime invoiceDate;
     private final DateTime paymentAttemptDate;
-    private final Invoice invoice;
 
-    public PaymentAttempt(UUID paymentAttemptId, Invoice invoice) {
+    public PaymentAttempt(UUID paymentAttemptId, UUID invoiceId, UUID accountId, BigDecimal amount, Currency currency, DateTime invoiceDate, DateTime paymentAttemptDate, String paymentId) {
         this.paymentAttemptId = paymentAttemptId;
-        this.paymentAttemptDate = new DateTime(DateTimeZone.UTC);
-        this.invoice = invoice;
-        this.paymentId = null;
+        this.invoiceId = invoiceId;
+        this.accountId = accountId;
+        this.amount = amount;
+        this.currency = currency;
+        this.invoiceDate = invoiceDate;
+        this.paymentAttemptDate = paymentAttemptDate == null ? new DateTime(DateTimeZone.UTC) : paymentAttemptDate;
+        this.paymentId = paymentId;
     }
 
-    public PaymentAttempt(UUID paymentAttemptId, Invoice invoice, String paymentId) {
-        this(paymentAttemptId, invoice, paymentId, 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);
     }
 
-    public PaymentAttempt(UUID paymentAttemptId, Invoice invoice, String paymentId, DateTime paymentAttemptDate) {
-        this.paymentAttemptId = paymentAttemptId;
-        this.paymentAttemptDate = paymentAttemptDate == null ? new DateTime(DateTimeZone.UTC) : paymentAttemptDate;
-        this.invoice = invoice;
-        this.paymentId = paymentId;
+    public PaymentAttempt(UUID paymentAttemptId, UUID invoiceId, UUID accountId, DateTime invoiceDate, DateTime paymentAttemptDate) {
+        this(paymentAttemptId, invoiceId, accountId, null, null, invoiceDate, paymentAttemptDate, null);
+    }
+
+    public PaymentAttempt(UUID paymentAttemptId, Invoice invoice) {
+        this(paymentAttemptId, invoice.getId(), invoice.getAccountId(), invoice.getAmountOutstanding(), invoice.getCurrency(), invoice.getInvoiceDate(), null);
+    }
+
+    public DateTime getInvoiceDate() {
+        return invoiceDate;
     }
 
     public UUID getPaymentAttemptId() {
@@ -59,13 +75,138 @@ public class PaymentAttempt {
         return paymentAttemptDate;
     }
 
-    public Invoice getInvoice() {
-        return invoice;
+    public UUID getInvoiceId() {
+        return invoiceId;
+    }
+
+    public UUID getAccountId() {
+        return accountId;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public Currency getCurrency() {
+        return currency;
     }
 
     @Override
     public String toString() {
-        return "PaymentAttempt [paymentAttemptId=" + paymentAttemptId + ", paymentId=" + paymentId + ", paymentAttemptDate=" + paymentAttemptDate + ", invoice=" + invoice + "]";
+        return "PaymentAttempt [paymentAttemptId=" + paymentAttemptId + ", invoiceId=" + invoiceId + ", amount=" + amount + ", currency=" + currency + ", paymentId=" + paymentId + ", paymentAttemptDate=" + paymentAttemptDate + "]";
+    }
+
+    public Builder cloner() {
+        return new Builder(this);
+    }
+
+    public static class Builder {
+        private UUID paymentAttemptId;
+        private UUID invoiceId;
+        private UUID accountId;
+        private BigDecimal amount;
+        private Currency currency;
+        private DateTime invoiceDate;
+        private DateTime paymentAttemptDate;
+        private String paymentId;
+
+        public Builder() {
+        }
+
+        public Builder(PaymentAttempt src) {
+            this.paymentAttemptId = src.paymentAttemptId;
+            this.invoiceId = src.invoiceId;
+            this.accountId = src.accountId;
+            this.amount = src.amount;
+            this.currency = src.currency;
+            this.invoiceDate = src.invoiceDate;
+            this.paymentAttemptDate = src.paymentAttemptDate;
+            this.paymentId = src.paymentId;
+        }
+
+        public Builder setPaymentAttemptId(UUID paymentAttemptId) {
+            this.paymentAttemptId = paymentAttemptId;
+            return this;
+        }
+
+        public Builder setInvoiceId(UUID invoiceId) {
+            this.invoiceId = invoiceId;
+            return this;
+        }
+
+        public Builder setAccountId(UUID accountId) {
+            this.accountId = accountId;
+            return this;
+        }
+
+        public Builder setAmount(BigDecimal amount) {
+            this.amount = amount;
+            return this;
+        }
+
+        public Builder setCurrency(Currency currency) {
+            this.currency = currency;
+            return this;
+        }
+
+        public Builder setInvoiceDate(DateTime invoiceDate) {
+            this.invoiceDate = invoiceDate;
+            return this;
+        }
+
+        public Builder setPaymentAttemptDate(DateTime paymentAttemptDate) {
+            this.paymentAttemptDate = paymentAttemptDate;
+            return this;
+        }
+
+        public Builder setPaymentId(String paymentId) {
+            this.paymentId = paymentId;
+            return this;
+        }
+
+        public PaymentAttempt build() {
+            return new PaymentAttempt(paymentAttemptId,
+                                      invoiceId,
+                                      accountId,
+                                      amount,
+                                      currency,
+                                      invoiceDate,
+                                      paymentAttemptDate,
+                                      paymentId);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hashCode(paymentAttemptId,
+                                invoiceId,
+                                accountId,
+                                amount,
+                                currency,
+                                invoiceDate,
+                                paymentAttemptDate,
+                                paymentId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (getClass() == obj.getClass()) {
+            PaymentAttempt other = (PaymentAttempt)obj;
+            if (obj == other) {
+                return true;
+            }
+            else {
+                return Objects.equal(paymentAttemptId, other.paymentAttemptId) &&
+                       Objects.equal(invoiceId, other.invoiceId) &&
+                       Objects.equal(accountId, other.accountId) &&
+                       Objects.equal(amount, other.amount) &&
+                       Objects.equal(currency, other.currency) &&
+                       Objects.equal(invoiceDate, other.invoiceDate) &&
+                       Objects.equal(paymentAttemptDate, other.paymentAttemptDate) &&
+                       Objects.equal(paymentId, other.paymentId);
+            }
+        }
+        return false;
     }
 
 }
diff --git a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
index fce8d45..9cfa71f 100644
--- a/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
+++ b/api/src/main/java/com/ning/billing/payment/api/PaymentInfo.java
@@ -129,7 +129,6 @@ public class PaymentInfo implements EventBusNotification {
         private String paymentId;
         private BigDecimal amount;
         private BigDecimal refundAmount;
-        private BigDecimal appliedCreditBalanceAmount;
         private String paymentNumber;
         private String bankIdentificationNumber;
         private String type;
@@ -166,11 +165,6 @@ public class PaymentInfo implements EventBusNotification {
             return this;
         }
 
-        public Builder setAppliedCreditBalanceAmount(BigDecimal appliedCreditBalanceAmount) {
-            this.appliedCreditBalanceAmount = appliedCreditBalanceAmount;
-            return this;
-        }
-
         public Builder setBankIdentificationNumber(String bankIdentificationNumber) {
             this.bankIdentificationNumber = bankIdentificationNumber;
             return this;
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
index 36a2a68..31006ea 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/invoice/DefaultInvoicePaymentApi.java
@@ -39,14 +39,14 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
     }
 
     @Override
-    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentId, DateTime paymentAttemptDate) {
-        dao.notifySuccessfulPayment(invoiceId.toString(), amount, currency.toString(), paymentId.toString(), paymentAttemptDate.toDate());
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
+        dao.notifyOfPaymentAttempt(invoicePayment);
     }
 
-    @Override
-    public void paymentFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate) {
-        dao.notifyFailedPayment(invoiceId.toString(), paymentId.toString(), paymentAttemptDate.toDate());
-    }
+//    @Override
+//    public void paymentFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate) {
+//        dao.notifyFailedPayment(invoiceId.toString(), paymentId.toString(), paymentAttemptDate.toDate());
+//    }
 
     @Override
     public List<Invoice> getInvoicesByAccount(UUID accountId) {
@@ -69,4 +69,16 @@ public class DefaultInvoicePaymentApi implements InvoicePaymentApi {
         return dao.getInvoicePayment(paymentAttemptId);
     }
 
+    @Override
+    public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, amountOutstanding, currency, paymentAttemptId, paymentAttemptDate);
+        dao.notifyOfPaymentAttempt(invoicePayment);
+    }
+
+    @Override
+    public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, null, null, paymentAttemptId, paymentAttemptDate);
+        dao.notifyOfPaymentAttempt(invoicePayment);
+    }
+
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 22f4990..739868a 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -16,19 +16,16 @@
 
 package com.ning.billing.invoice.api.user;
 
+import java.util.List;
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
 import com.google.inject.Inject;
-import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceUserApi;
-import com.ning.billing.invoice.dao.DefaultInvoiceDao;
 import com.ning.billing.invoice.dao.InvoiceDao;
-import com.ning.billing.util.eventbus.EventBus;
-import org.joda.time.DateTime;
-import org.skife.jdbi.v2.IDBI;
-
-import java.math.BigDecimal;
-import java.util.List;
-import java.util.UUID;
+import com.ning.billing.payment.api.InvoicePayment;
 
 public class DefaultInvoiceUserApi implements InvoiceUserApi {
     private final InvoiceDao dao;
@@ -54,12 +51,17 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
     }
 
     @Override
-    public void paymentAttemptFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate) {
-        dao.notifyFailedPayment(invoiceId.toString(), paymentId.toString(), paymentAttemptDate.toDate());
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
+        dao.notifyOfPaymentAttempt(invoicePayment);
     }
 
-    @Override
-    public void paymentAttemptSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentId, DateTime paymentDate) {
-        dao.notifySuccessfulPayment(invoiceId.toString(), amount, currency.toString(), paymentId.toString(), paymentDate.toDate());
-    }
+//    @Override
+//    public void paymentAttemptFailed(UUID invoiceId, UUID paymentId, DateTime paymentAttemptDate) {
+//        dao.notifyFailedPayment(invoiceId.toString(), paymentId.toString(), paymentAttemptDate.toDate());
+//    }
+//
+//    @Override
+//    public void paymentAttemptSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentId, DateTime paymentDate) {
+//        dao.notifySuccessfulPayment(invoiceId.toString(), amount, currency.toString(), paymentId.toString(), paymentDate.toDate());
+//    }
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
index 016028c..b9ed8fa 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/DefaultInvoiceDao.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.invoice.dao;
 
-import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
@@ -137,14 +136,19 @@ public class DefaultInvoiceDao implements InvoiceDao {
         return invoiceDao.getInvoicesForPayment(targetDate, numberOfDays);
     }
 
-    @Override
-    public void notifySuccessfulPayment(String invoiceId, BigDecimal paymentAmount, String currency, String paymentId, Date paymentDate) {
-        invoiceDao.notifySuccessfulPayment(invoiceId, paymentAmount, currency, paymentId, paymentDate);
-    }
+//    @Override
+//    public void notifySuccessfulPayment(String invoiceId, BigDecimal paymentAmount, String currency, String paymentId, Date paymentDate) {
+//        invoiceDao.notifySuccessfulPayment(invoiceId, paymentAmount, currency, paymentId, paymentDate);
+//    }
+//
+//    @Override
+//    public void notifyFailedPayment(String invoiceId, String paymentId, Date paymentAttemptDate) {
+//        invoiceDao.notifyFailedPayment(invoiceId, paymentId, paymentAttemptDate);
+//    }
 
     @Override
-    public void notifyFailedPayment(String invoiceId, String paymentId, Date paymentAttemptDate) {
-        invoiceDao.notifyFailedPayment(invoiceId, paymentId, paymentAttemptDate);
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
+        invoiceDao.notifyOfPaymentAttempt(invoicePayment);
     }
 
     @Override
@@ -161,4 +165,5 @@ public class DefaultInvoiceDao implements InvoiceDao {
     public InvoicePayment getInvoicePayment(UUID paymentAttemptId) {
         return invoiceDao.getInvoicePayment(paymentAttemptId);
     }
+
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
index 043cb0f..7deac54 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceDao.java
@@ -16,7 +16,6 @@
 
 package com.ning.billing.invoice.dao;
 
-import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.UUID;
@@ -38,15 +37,15 @@ public interface InvoiceDao {
     List<UUID> getInvoicesForPayment(final Date targetDate,
                                      final int numberOfDays);
 
-    void notifySuccessfulPayment(final String invoiceId,
-                                 final BigDecimal paymentAmount,
-                                 final String currency,
-                                 final String paymentId,
-                                 final Date paymentDate);
-
-    void notifyFailedPayment(final String invoiceId,
-                             final String paymentId,
-                             final Date paymentAttemptDate);
+//    void notifySuccessfulPayment(final String invoiceId,
+//                                 final BigDecimal paymentAmount,
+//                                 final String currency,
+//                                 final String paymentId,
+//                                 final Date paymentDate);
+//
+//    void notifyFailedPayment(final String invoiceId,
+//                             final String paymentId,
+//                             final Date paymentAttemptDate);
 
     String getInvoiceIdByPaymentAttemptId(UUID paymentAttemptId);
 
@@ -54,4 +53,6 @@ public interface InvoiceDao {
 
     InvoicePayment getInvoicePayment(UUID paymentAttemptId);
 
+    void notifyOfPaymentAttempt(InvoicePayment invoicePayment);
+
 }
diff --git a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
index 2759236..e22033f 100644
--- a/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
+++ b/invoice/src/main/java/com/ning/billing/invoice/dao/InvoiceSqlDao.java
@@ -31,6 +31,7 @@ import java.util.List;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.skife.jdbi.v2.SQLStatement;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
@@ -81,17 +82,12 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
     @SqlQuery
     InvoicePayment getInvoicePayment(@Bind("paymentAttemptId") UUID paymentAttemptId);
 
-    @SqlUpdate
-    void notifySuccessfulPayment(@Bind("invoiceId") final String invoiceId,
-                                 @Bind("amount") final BigDecimal paymentAmount,
-                                 @Bind("currency") final String currency,
-                                 @Bind("paymentId") final String paymentId,
-                                 @Bind("paymentDate") final Date paymentDate);
+//    void notifySuccessfulPayment(@Bind(binder = InvoicePaymentBinder.class) InvoicePayment invoicePayment);
+
+//    void notifySuccessfulPayment(String invoiceId, BigDecimal paymentAmount, String currency, String paymentId, Date paymentDate);
 
     @SqlUpdate
-    void notifyFailedPayment(@Bind("invoiceId") final String invoiceId,
-                             @Bind("paymentId") final String paymentId,
-                             @Bind("paymentAttemptDate") final Date paymentAttemptDate);
+    void notifyOfPaymentAttempt(@Bind(binder = InvoicePaymentBinder.class) InvoicePayment invoicePayment);
 
     @BindingAnnotation(InvoiceBinder.InvoiceBinderFactory.class)
     @Retention(RetentionPolicy.RUNTIME)
@@ -99,10 +95,10 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
     public @interface InvoiceBinder {
         public static class InvoiceBinderFactory implements BinderFactory {
             @Override
-            public Binder build(Annotation annotation) {
+            public Binder<InvoiceBinder, Invoice> build(Annotation annotation) {
                 return new Binder<InvoiceBinder, Invoice>() {
                     @Override
-                    public void bind(SQLStatement q, InvoiceBinder bind, Invoice invoice) {
+                    public void bind(@SuppressWarnings("rawtypes") SQLStatement q, InvoiceBinder bind, Invoice invoice) {
                         q.bind("id", invoice.getId().toString());
                         q.bind("accountId", invoice.getAccountId().toString());
                         q.bind("invoiceDate", invoice.getInvoiceDate().toDate());
@@ -137,5 +133,40 @@ public interface InvoiceSqlDao extends EntityDao<Invoice>, Transactional<Invoice
         }
     }
 
+    @SqlUpdate
+    void notifyFailedPayment(@Bind(binder = InvoicePaymentBinder.class) InvoicePayment invoicePayment);
+
+    public static final class InvoicePaymentBinder implements Binder<Bind, InvoicePayment> {
+
+        @Override
+        public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, InvoicePayment invoicePayment) {
+            stmt.bind("invoice_id", invoicePayment.getInvoiceId().toString());
+            stmt.bind("amount", invoicePayment.getAmount());
+            stmt.bind("currency", invoicePayment.getCurrency().toString());
+            stmt.bind("payment_attempt_id", invoicePayment.getPaymentAttemptId());
+            stmt.bind("payment_attempt_date", invoicePayment.getPaymentAttemptDate() == null ? null : invoicePayment.getPaymentAttemptDate().toDate());
+        }
+    }
+
+
+    public static class InvoicePaymentMapper implements ResultSetMapper<InvoicePayment> {
+
+        private DateTime getDate(ResultSet rs, String fieldName) throws SQLException {
+            final Timestamp resultStamp = rs.getTimestamp(fieldName);
+            return rs.wasNull() ? null : new DateTime(resultStamp).toDateTime(DateTimeZone.UTC);
+        }
+
+        @Override
+        public InvoicePayment map(int index, ResultSet rs, StatementContext ctx) throws SQLException {
+
+            UUID invoiceId = UUID.fromString(rs.getString("invoice_id"));
+            BigDecimal amount = rs.getBigDecimal("amount");
+            Currency currency = Currency.valueOf(rs.getString("currency"));
+            UUID paymentAttemptId = UUID.fromString(rs.getString("payment_attempt_id"));
+            DateTime paymentAttemptDate = getDate(rs, "payment_attempt_date");
+
+            return new InvoicePayment(invoiceId, amount, currency, paymentAttemptId, paymentAttemptDate);
+        }
+    }
 }
 
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
index c8fbad3..d79b951 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
+++ b/invoice/src/main/resources/com/ning/billing/invoice/dao/InvoiceSqlDao.sql.stg
@@ -70,18 +70,13 @@ update() ::= <<
   WHERE id = :id;
 >>
 
-notifySuccessfulPayment() ::= <<
-  INSERT INTO invoice_payments(invoice_id, payment_attempt_id, payment_date, amount, currency)
-  VALUES(:invoice_id, :payment_attempt_id, :payment_date, :amount, :currency);
->>
-
-notifyFailedPayment() ::= <<
-  INSERT INTO invoice_payments(invoice_id, payment_attempt_id)
-  VALUES(:invoice_id, :payment_attempt_id);
+notifyOfPaymentAttempt() ::= <<
+  INSERT INTO invoice_payments(invoice_id, payment_attempt_id, payment_attempt_date, amount, currency, created_date, updated_date)
+  VALUES(:invoice_id, :payment_attempt_id, :payment_attempt_date, :amount, :currency, NOW(), NOW());
 >>
 
 getInvoicePayment() ::= <<
-    SELECT invoice_id, payment_id, payment_date, amount, currency
+    SELECT invoice_id, payment_attempt_id, payment_attempt_date, amount, currency, created_date, updated_date
       FROM invoice_payments
      WHERE payment_id = :payment_id
 >>
diff --git a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
index 330e82c..ce3641e 100644
--- a/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
+++ b/invoice/src/main/resources/com/ning/billing/invoice/ddl.sql
@@ -30,10 +30,12 @@ DROP TABLE IF EXISTS invoice_payments;
 CREATE TABLE invoice_payments (
   invoice_id char(36) NOT NULL,
   payment_attempt_id char(36) NOT NULL,
-  payment_date datetime,
-  payment_attempt_date datetime,
+  payment_dt datetime,
+  payment_attempt_dt datetime,
   amount numeric(10,4),
   currency char(3),
+  created_dt datetime NOT NULL,
+  updated_dt datetime NOT NULL,
   PRIMARY KEY(invoice_id, payment_attempt_id)
 ) ENGINE=innodb;
 CREATE UNIQUE INDEX invoice_payments_unique ON invoice_payments(invoice_id, payment_attempt_id);
diff --git a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
index 821b880..37d5f0c 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/api/MockInvoicePaymentApi.java
@@ -37,11 +37,9 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
     }
 
     @Override
-    public void paymentSuccessful(UUID invoiceId, BigDecimal amount, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
-        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, amount, currency, paymentAttemptId, paymentAttemptDate);
-
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
         for (InvoicePayment existingInvoicePayment : invoicePayments) {
-            if (existingInvoicePayment.getInvoiceId().equals(invoiceId) && existingInvoicePayment.getPaymentAttemptId().equals(paymentAttemptId)) {
+            if (existingInvoicePayment.getInvoiceId().equals(invoicePayment.getInvoiceId()) && existingInvoicePayment.getPaymentAttemptId().equals(invoicePayment.getPaymentAttemptId())) {
                 invoicePayments.remove(existingInvoicePayment);
             }
         }
@@ -71,17 +69,6 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
     }
 
     @Override
-    public void paymentFailed(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
-        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, null, null, paymentAttemptId, paymentAttemptDate);
-        for (InvoicePayment existingInvoicePayment : invoicePayments) {
-            if (existingInvoicePayment.getInvoiceId().equals(invoiceId) && existingInvoicePayment.getPaymentAttemptId().equals(paymentAttemptId)) {
-                invoicePayments.remove(existingInvoicePayment);
-            }
-        }
-        invoicePayments.add(invoicePayment);
-    }
-
-    @Override
     public Invoice getInvoiceForPaymentAttemptId(UUID paymentAttemptId) {
         for (InvoicePayment invoicePayment : invoicePayments) {
             if (invoicePayment.getPaymentAttemptId().equals(paymentAttemptId)) {
@@ -100,4 +87,16 @@ public class MockInvoicePaymentApi implements InvoicePaymentApi
         }
         return null;
     }
+
+    @Override
+    public void notifyOfPaymentAttempt(UUID invoiceId, BigDecimal amountOutstanding, Currency currency, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, amountOutstanding, currency, paymentAttemptId, paymentAttemptDate);
+        notifyOfPaymentAttempt(invoicePayment);
+    }
+
+    @Override
+    public void notifyOfPaymentAttempt(UUID invoiceId, UUID paymentAttemptId, DateTime paymentAttemptDate) {
+        InvoicePayment invoicePayment = new InvoicePayment(invoiceId, null, null, paymentAttemptId, paymentAttemptDate);
+        notifyOfPaymentAttempt(invoicePayment);
+    }
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
index 3fe72ed..c840928 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/InvoiceDaoTests.java
@@ -16,25 +16,28 @@
 
 package com.ning.billing.invoice.dao;
 
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
 import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
+
 import org.joda.time.DateTime;
-import org.joda.time.Days;
+import org.joda.time.DateTimeZone;
 import org.testng.annotations.Test;
+
 import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.invoice.model.DefaultInvoiceItem;
+import com.ning.billing.payment.api.InvoicePayment;
 import com.ning.billing.util.clock.DefaultClock;
 
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
 @Test(groups = {"invoicing", "invoicing-invoiceDao"})
 public class InvoiceDaoTests extends InvoiceDaoTestBase {
     private final int NUMBER_OF_DAY_BETWEEN_RETRIES = 8;
@@ -78,8 +81,9 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         assertEquals(savedInvoice.getItems().size(), 1);
 
         BigDecimal paymentAmount = new BigDecimal("11.00");
-        String paymentId = UUID.randomUUID().toString();
-        invoiceDao.notifySuccessfulPayment(invoiceId.toString(), paymentAmount, Currency.USD.toString(), paymentId, new DefaultClock().getUTCNow().plusDays(12).toDate());
+        UUID paymentAttemptId = UUID.randomUUID();
+
+        invoiceDao.notifyOfPaymentAttempt(new InvoicePayment(invoiceId, paymentAmount, Currency.USD, paymentAttemptId, new DateTime(DateTimeZone.UTC).plusDays(12)));
 
         Invoice retrievedInvoice = invoiceDao.getById(invoiceId.toString());
         assertNotNull(retrievedInvoice);
@@ -101,12 +105,13 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
         Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
 
-        String paymentId = UUID.randomUUID().toString();
+        UUID paymentAttemptId = UUID.randomUUID();
         DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
         BigDecimal paymentAmount = new BigDecimal("14.0");
 
         invoiceDao.create(invoice);
-        invoiceDao.notifySuccessfulPayment(invoice.getId().toString(), paymentAmount, Currency.USD.toString(), paymentId, paymentAttemptDate.toDate());
+
+        invoiceDao.notifyOfPaymentAttempt(new InvoicePayment(invoice.getId(), paymentAmount, Currency.USD, paymentAttemptId, paymentAttemptDate));
 
         invoice = invoiceDao.getById(invoice.getId().toString());
         assertEquals(invoice.getAmountPaid().compareTo(paymentAmount), 0);
@@ -122,7 +127,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         DateTime paymentAttemptDate = new DateTime(2011, 6, 24, 12, 14, 36, 0);
 
         invoiceDao.create(invoice);
-        invoiceDao.notifyFailedPayment(invoice.getId().toString(), UUID.randomUUID().toString(), paymentAttemptDate.toDate());
+        invoiceDao.notifyOfPaymentAttempt(new InvoicePayment(invoice.getId(), UUID.randomUUID(), paymentAttemptDate));
 
         invoice = invoiceDao.getById(invoice.getId().toString());
         assertTrue(invoice.getLastPaymentAttempt().equals(paymentAttemptDate));
@@ -132,11 +137,11 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
     public void testGetInvoicesForPaymentWithNoResults() {
         DateTime notionalDate = new DateTime();
         DateTime targetDate = new DateTime(2011, 10, 6, 0, 0, 0, 0);
-        
+
         // determine the number of existing invoices available for payment (to avoid side effects from other tests)
         List<UUID> invoices = invoiceDao.getInvoicesForPayment(notionalDate.toDate(), NUMBER_OF_DAY_BETWEEN_RETRIES);
         int existingInvoiceCount = invoices.size();
-        
+
         UUID accountId = UUID.randomUUID();
         Invoice invoice = new DefaultInvoice(accountId, targetDate, Currency.USD);
 
@@ -174,7 +179,7 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
 
         // attempt a payment; ensure that the number of invoices for payment has decreased by 1
         // (no retries for NUMBER_OF_DAYS_BETWEEN_RETRIES days)
-        invoiceDao.notifyFailedPayment(invoice.getId().toString(), UUID.randomUUID().toString(), notionalDate.toDate());
+        invoiceDao.notifyOfPaymentAttempt(new InvoicePayment(invoice.getId(), UUID.randomUUID(), notionalDate));
         invoices = invoiceDao.getInvoicesForPayment(notionalDate.toDate(), NUMBER_OF_DAY_BETWEEN_RETRIES);
         count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
         assertEquals(invoices.size(), count);
@@ -187,7 +192,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         assertEquals(invoices.size(), count);
 
         // post successful partial payment; ensure that number of invoices for payment has decreased by 1
-        invoiceDao.notifySuccessfulPayment(invoiceId.toString(), new BigDecimal("22.0000"), Currency.USD.toString(), UUID.randomUUID().toString(), notionalDate.toDate());
+        invoiceDao.notifyOfPaymentAttempt(new InvoicePayment(invoice.getId(), new BigDecimal("22.0000"), Currency.USD, UUID.randomUUID(), notionalDate));
+
         invoices = invoiceDao.getInvoicesForPayment(notionalDate.toDate(), NUMBER_OF_DAY_BETWEEN_RETRIES);
         count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
         assertEquals(invoices.size(), count);
@@ -204,7 +210,8 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         assertEquals(invoices.size(), count);
 
         // post completed payment; ensure that the number of invoices for payment has decreased by 1
-        invoiceDao.notifySuccessfulPayment(invoiceId.toString(), new BigDecimal("5.0000"), Currency.USD.toString(), UUID.randomUUID().toString(), notionalDate.toDate());
+        invoiceDao.notifyOfPaymentAttempt(new InvoicePayment(invoice.getId(), new BigDecimal("5.0000"), Currency.USD, UUID.randomUUID(), notionalDate));
+
         invoices = invoiceDao.getInvoicesForPayment(notionalDate.toDate(), NUMBER_OF_DAY_BETWEEN_RETRIES);
         count = getInvoicesDueForPaymentAttempt(invoiceDao.get(), notionalDate).size();
         assertEquals(invoices.size(), count);
@@ -298,5 +305,5 @@ public class InvoiceDaoTests extends InvoiceDaoTestBase {
         List<Invoice> items4 = invoiceDao.getInvoicesBySubscription(subscriptionId4.toString());
         assertEquals(items4.size(), 1);
     }
-    
+
 }
diff --git a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
index c549a61..cf8b130 100644
--- a/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
+++ b/invoice/src/test/java/com/ning/billing/invoice/dao/MockInvoiceDao.java
@@ -29,7 +29,6 @@ import java.util.UUID;
 
 import org.joda.time.DateTime;
 
-import com.ning.billing.catalog.api.Currency;
 import com.ning.billing.invoice.api.Invoice;
 import com.ning.billing.invoice.api.InvoiceItem;
 import com.ning.billing.invoice.model.DefaultInvoice;
@@ -147,24 +146,24 @@ public class MockInvoiceDao implements InvoiceDao {
         return new ArrayList<UUID>(result);
     }
 
-    @Override
-    public void notifySuccessfulPayment(String invoiceId, BigDecimal paymentAmount, String currency, String paymentAttemptId, Date paymentAttemptDate) {
-        synchronized (monitor) {
-            invoicePayments.put(UUID.fromString(paymentAttemptId),
-                                new InvoicePayment(UUID.fromString(invoiceId), paymentAmount, Currency.valueOf(currency), UUID.fromString(paymentAttemptId), new DateTime(paymentAttemptDate)));
-        }
-    }
-
-    @Override
-    public void notifyFailedPayment(String invoiceId,
-                                    String paymentAttemptId,
-                                    Date paymentAttemptDate) {
-        synchronized (monitor) {
-            invoicePayments.put(UUID.fromString(paymentAttemptId),
-                                new InvoicePayment(UUID.fromString(invoiceId), null, null, UUID.fromString(paymentAttemptId), new DateTime(paymentAttemptDate)));
-
-        }
-    }
+//    @Override
+//    public void notifySuccessfulPayment(String invoiceId, BigDecimal paymentAmount, String currency, String paymentAttemptId, Date paymentAttemptDate) {
+//        synchronized (monitor) {
+//            invoicePayments.put(UUID.fromString(paymentAttemptId),
+//                                new InvoicePayment(UUID.fromString(invoiceId), paymentAmount, Currency.valueOf(currency), UUID.fromString(paymentAttemptId), new DateTime(paymentAttemptDate)));
+//        }
+//    }
+//
+//    @Override
+//    public void notifyFailedPayment(String invoiceId,
+//                                    String paymentAttemptId,
+//                                    Date paymentAttemptDate) {
+//        synchronized (monitor) {
+//            invoicePayments.put(UUID.fromString(paymentAttemptId),
+//                                new InvoicePayment(UUID.fromString(invoiceId), null, null, UUID.fromString(paymentAttemptId), new DateTime(paymentAttemptDate)));
+//
+//        }
+//    }
 
     @Override
     public void test() {
@@ -188,4 +187,11 @@ public class MockInvoiceDao implements InvoiceDao {
             return invoicePayments.get(paymentAttemptId);
         }
     }
+
+    @Override
+    public void notifyOfPaymentAttempt(InvoicePayment invoicePayment) {
+      synchronized (monitor) {
+          invoicePayments.put(invoicePayment.getPaymentAttemptId(), invoicePayment);
+      }
+    }
 }
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 ad91c85..5cba9e6 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
@@ -138,27 +138,25 @@ public class DefaultPaymentApi implements PaymentApi {
                 Either<PaymentError, PaymentInfo> paymentOrError = plugin.processInvoice(account, invoice);
                 processedPaymentsOrErrors.add(paymentOrError);
 
+                PaymentInfo paymentInfo = null;
+
                 if (paymentOrError.isRight()) {
-                    PaymentInfo paymentInfo = paymentOrError.getRight();
+                    paymentInfo = paymentOrError.getRight();
 
                     paymentDao.savePaymentInfo(paymentInfo);
 
                     if (paymentInfo.getPaymentId() != null) {
                         paymentDao.updatePaymentAttemptWithPaymentId(paymentAttempt.getPaymentAttemptId(), paymentInfo.getPaymentId());
                     }
-
-                    invoicePaymentApi.paymentSuccessful(invoice.getId(),
-                                                        paymentInfo.getAmount(),
-//                                                      info.getRefundAmount(), TODO
-                                                        invoice.getCurrency(),
-                                                        paymentAttempt.getPaymentAttemptId(),
-                                                        paymentAttempt.getPaymentAttemptDate());
-                }
-                else {
-                    invoicePaymentApi.paymentFailed(invoice.getId(),
-                                                    paymentAttempt.getPaymentAttemptId(),
-                                                    paymentAttempt.getPaymentAttemptDate());
                 }
+
+                invoicePaymentApi.notifyOfPaymentAttempt(new InvoicePayment(invoice.getId(),
+                                                                     paymentInfo == null ? null : paymentInfo.getAmount(),
+//                                                                   info.getRefundAmount(), TODO
+                                                                     paymentInfo == null ? null : invoice.getCurrency(),
+                                                                     paymentAttempt.getPaymentAttemptId(),
+                                                                     paymentAttempt.getPaymentAttemptDate()));
+
             }
         }
 
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 0c19196..efd64fc 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
@@ -39,8 +39,6 @@ import org.skife.jdbi.v2.sqlobject.stringtemplate.ExternalizedSqlViaStringTempla
 import org.skife.jdbi.v2.tweak.ResultSetMapper;
 
 import com.ning.billing.catalog.api.Currency;
-import com.ning.billing.invoice.api.Invoice;
-import com.ning.billing.invoice.model.DefaultInvoice;
 import com.ning.billing.payment.api.PaymentAttempt;
 import com.ning.billing.payment.api.PaymentInfo;
 
@@ -72,20 +70,14 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
 
         @Override
         public void bind(@SuppressWarnings("rawtypes") SQLStatement stmt, Bind bind, PaymentAttempt paymentAttempt) {
-            Invoice invoice = paymentAttempt.getInvoice();
-
             stmt.bind("payment_attempt_id", paymentAttempt.getPaymentAttemptId().toString());
-            stmt.bind("payment_id", paymentAttempt.getPaymentId());
+            stmt.bind("invoice_id", paymentAttempt.getInvoiceId().toString());
+            stmt.bind("account_id", paymentAttempt.getAccountId().toString());
+            stmt.bind("amount", paymentAttempt.getAmount()); //TODO: suppport partial payments
+            stmt.bind("currency", paymentAttempt.getCurrency().toString());
+            stmt.bind("invoice_dt", getDate(paymentAttempt.getInvoiceDate()));
             stmt.bind("payment_attempt_dt", getDate(paymentAttempt.getPaymentAttemptDate()));
-            stmt.bind("invoice_id", invoice.getId().toString());
-            stmt.bind("payment_attempt_amount", invoice.getAmountOutstanding()); //TODO: suppport partial payments
-            stmt.bind("account_id", invoice.getAccountId().toString());
-            stmt.bind("invoice_dt", getDate(invoice.getInvoiceDate()));
-            stmt.bind("target_dt", getDate(invoice.getTargetDate()));
-            stmt.bind("amount_paid", invoice.getAmountPaid());
-            stmt.bind("amount_outstanding", invoice.getAmountOutstanding());
-            stmt.bind("last_payment_attempt", getDate(invoice.getLastPaymentAttempt()));
-            stmt.bind("currency", invoice.getCurrency().toString());
+            stmt.bind("payment_id", paymentAttempt.getPaymentId());
         }
     }
 
@@ -102,17 +94,13 @@ public interface PaymentSqlDao extends Transactional<PaymentSqlDao>, CloseMe, Tr
             UUID paymentAttemptId = UUID.fromString(rs.getString("payment_attempt_id"));
             UUID invoiceId = UUID.fromString(rs.getString("invoice_id"));
             UUID accountId = UUID.fromString(rs.getString("account_id"));
-            String paymentId = rs.getString("payment_id");
-            BigDecimal amountPaid = rs.getBigDecimal("amount_paid");
+            BigDecimal amount = rs.getBigDecimal("amount");
             Currency currency = Currency.valueOf(rs.getString("currency"));
-            DateTime targetDate = getDate(rs, "target_dt");
             DateTime invoiceDate = getDate(rs, "invoice_dt");
             DateTime paymentAttemptDate = getDate(rs, "payment_attempt_dt");
-            DateTime lastPaymentAttempt = getDate(rs, "last_payment_attempt");
-
-            Invoice invoice = new DefaultInvoice(invoiceId, accountId, invoiceDate, targetDate, currency, lastPaymentAttempt, amountPaid);
+            String paymentId = rs.getString("payment_id");
 
-            return new PaymentAttempt(paymentAttemptId, invoice, paymentId, paymentAttemptDate);
+            return new PaymentAttempt(paymentAttemptId, invoiceId, accountId, amount, currency, invoiceDate, paymentAttemptDate, paymentId);
         }
     }
 
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 af172e5..3860c58 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
@@ -4,7 +4,7 @@ paymentAttemptFields(prefix) ::= <<
     <prefix>payment_attempt_id,
     <prefix>account_id,
     <prefix>invoice_id,
-    <prefix>payment_attempt_amount,
+    <prefix>amount,
     <prefix>payment_attempt_dt,
     <prefix>created_dt,
     <prefix>updated_dt
@@ -26,7 +26,7 @@ paymentInfoFields(prefix) ::= <<
 
 insertPaymentAttempt() ::= <<
     INSERT INTO payment_attempts (<paymentAttemptFields()>)
-    VALUES (:payment_attempt_id, :account_id, :invoice_id, :payment_attempt_amount, :payment_attempt_dt, NOW(), NOW());
+    VALUES (:payment_attempt_id, :account_id, :invoice_id, :amount, :payment_attempt_dt, NOW(), NOW());
 >>
 
 getPaymentAttemptForPaymentId() ::= <<
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 a118254..c87cae9 100644
--- a/payment/src/main/resources/com/ning/billing/payment/ddl.sql
+++ b/payment/src/main/resources/com/ning/billing/payment/ddl.sql
@@ -1,11 +1,11 @@
 DROP TABLE IF EXISTS payment_attempts;
 CREATE TABLE payment_attempts (
       payment_attempt_id varchar(36) COLLATE utf8_bin NOT NULL,
-      payment_id varchar(36) COLLATE utf8_bin,
       account_id varchar(36) COLLATE utf8_bin NOT NULL,
       invoice_id varchar(36) COLLATE utf8_bin NOT NULL,
-      payment_attempt_amount decimal(8,2) NOT NULL,
+      amount decimal(8,2),
       payment_attempt_dt datetime NOT NULL,
+      payment_id varchar(36) COLLATE utf8_bin,
       created_dt datetime NOT NULL,
       updated_dt datetime NOT NULL,
       PRIMARY KEY (payment_attempt_id)
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 d3196b7..74d8552 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
@@ -53,18 +53,17 @@ public class MockPaymentDao implements PaymentDao {
     @Override
     public void updatePaymentAttemptWithPaymentId(UUID paymentAttemptId, String paymentId) {
         PaymentAttempt existingPaymentAttempt = paymentAttempts.get(paymentAttemptId);
+
         if (existingPaymentAttempt != null) {
             paymentAttempts.put(existingPaymentAttempt.getPaymentAttemptId(),
-                                new PaymentAttempt(existingPaymentAttempt.getPaymentAttemptId(),
-                                                   existingPaymentAttempt.getInvoice(),
-                                                   paymentId));
+                                existingPaymentAttempt.cloner().setPaymentId(paymentId).build());
         }
     }
 
     @Override
     public PaymentAttempt getPaymentAttemptForInvoiceId(String invoiceId) {
         for (PaymentAttempt paymentAttempt : paymentAttempts.values()) {
-            if (invoiceId.equals(paymentAttempt.getInvoice().getId())) {
+            if (invoiceId.equals(paymentAttempt.getInvoiceId())) {
                 return paymentAttempt;
             }
         }
diff --git a/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java b/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
index af319c5..55d5114 100644
--- a/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
+++ b/payment/src/test/java/com/ning/billing/payment/TestNotifyInvoicePaymentApi.java
@@ -37,7 +37,8 @@ public class TestNotifyInvoicePaymentApi extends TestPaymentProvider {
         final Invoice invoice = createTestInvoice(account);
 
         PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
-        invoicePaymentApi.paymentSuccessful(invoice.getId(),
+
+        invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
                                      invoice.getAmountOutstanding(),
                                      invoice.getCurrency(),
                                      paymentAttempt.getPaymentAttemptId(),
@@ -54,9 +55,9 @@ public class TestNotifyInvoicePaymentApi extends TestPaymentProvider {
         final Invoice invoice = createTestInvoice(account);
 
         PaymentAttempt paymentAttempt = new PaymentAttempt(UUID.randomUUID(), invoice);
-        invoicePaymentApi.paymentFailed(invoice.getId(),
-                                 paymentAttempt.getPaymentAttemptId(),
-                                 paymentAttempt.getPaymentAttemptDate());
+        invoicePaymentApi.notifyOfPaymentAttempt(invoice.getId(),
+                                                 paymentAttempt.getPaymentAttemptId(),
+                                                 paymentAttempt.getPaymentAttemptDate());
 
         InvoicePayment invoicePayment = invoicePaymentApi.getInvoicePayment(paymentAttempt.getPaymentAttemptId());