killbill-memoizeit

Details

diff --git a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
index 2c774e8..999f11b 100644
--- a/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
+++ b/analytics/src/main/java/com/ning/billing/analytics/BusinessAccountRecorder.java
@@ -207,8 +207,9 @@ public class BusinessAccountRecorder {
                 lastPaymentStatus = payment.getStatus();
                 paymentMethod = payment.getPaymentMethod();
                 creditCardType = payment.getCardType();
+                billingAddressCountry = payment.getCardCountry();
             }
-            billingAddressCountry = payment.getCardCountry();
+            
 
             bac.setLastPaymentStatus(lastPaymentStatus);
             bac.setPaymentMethod(paymentMethod);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
index ede4788..d7cfa17 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
@@ -103,7 +103,9 @@ public class AccountTimelineJson {
             String status = cur.getPaymentId() != null ? "Success" : "Failed";
             BigDecimal paidAmount = cur.getPaymentId() != null ? cur.getAmount() : BigDecimal.ZERO;
             
-            this.payments.add(new PaymentJsonWithBundleKeys(cur.getAmount(), paidAmount, cur.getInvoiceId(), cur.getPaymentId(), cur.getCreatedDate(), cur.getUpdatedDate(),
+            this.payments.add(new PaymentJsonWithBundleKeys(cur.getAmount(), paidAmount, account.getId().toString(),
+                    cur.getInvoiceId().toString(), cur.getPaymentId().toString(), 
+                    cur.getCreatedDate(), cur.getUpdatedDate(),
                     cur.getRetryCount(), cur.getCurrency().toString(), status,
                     getBundleExternalKey(cur.getInvoiceId(), invoices, bundles)));
           }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
index c0a6d7c..bc2b6f9 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonSimple.java
@@ -24,6 +24,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
 import org.codehaus.jackson.map.annotate.JsonView;
 import org.joda.time.DateTime;
 
+import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.util.clock.DefaultClock;
 
 public class PaymentJsonSimple {
@@ -32,9 +33,11 @@ public class PaymentJsonSimple {
 
     private final BigDecimal amount;
 
-    private final UUID invoiceId;
+    private final String accountId;
     
-    private final UUID paymentId;
+    private final String invoiceId;
+    
+    private final String paymentId;
     
     private final DateTime requestedDate;
     
@@ -50,6 +53,7 @@ public class PaymentJsonSimple {
         this.amount = null;
         this.paidAmount = null;
         this.invoiceId = null;
+        this.accountId = null;
         this.paymentId = null;
         this.requestedDate = null;
         this.effectiveDate = null;
@@ -61,8 +65,9 @@ public class PaymentJsonSimple {
     @JsonCreator
     public PaymentJsonSimple(@JsonProperty("amount") BigDecimal amount,
             @JsonProperty("paidAmount") BigDecimal paidAmount,
-            @JsonProperty("invoiceId") UUID invoiceId,
-            @JsonProperty("paymentId") UUID paymentId,
+            @JsonProperty("accountId") String accountId,            
+            @JsonProperty("invoiceId") String invoiceId,
+            @JsonProperty("paymentId") String paymentId,
             @JsonProperty("requestedDate") DateTime requestedDate,
             @JsonProperty("effectiveDate") DateTime effectiveDate,
             @JsonProperty("retryCount") Integer retryCount,
@@ -72,6 +77,7 @@ public class PaymentJsonSimple {
         this.amount = amount;
         this.paidAmount = paidAmount;
         this.invoiceId = invoiceId;
+        this.accountId = accountId;        
         this.paymentId = paymentId;
         this.requestedDate = DefaultClock.toUTCDateTime(requestedDate);
         this.effectiveDate = DefaultClock.toUTCDateTime(effectiveDate);
@@ -80,15 +86,32 @@ public class PaymentJsonSimple {
         this.status = status;
     }
 
+    public PaymentJsonSimple(PaymentInfoEvent src) {
+        this.amount = src.getAmount();
+        this.paidAmount = src.getAmount(); // STEPH ?
+        this.invoiceId = src.getInvoiceId().toString();
+        this.accountId = src.getAccountId().toString();
+        this.paymentId = src.getId().toString();
+        this.requestedDate = src.getCreatedDate();
+        this.effectiveDate = src.getEffectiveDate();
+        this.currency = null; // Should it really be part of the payment object since this is per account?
+        this.retryCount = null; // do we need that?
+        this.status = src.getStatus();
+    }
+
     public BigDecimal getPaidAmount() {
         return paidAmount;
     }
 
-    public UUID getInvoiceId() {
+    public String getInvoiceId() {
         return invoiceId;
     }
 
-    public UUID getPaymentId() {
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public String getPaymentId() {
         return paymentId;
     }
 
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java
index e322a59..c68befd 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/PaymentJsonWithBundleKeys.java
@@ -35,15 +35,16 @@ public class PaymentJsonWithBundleKeys extends PaymentJsonSimple {
     @JsonCreator
     public PaymentJsonWithBundleKeys(@JsonProperty("amount") BigDecimal amount,
             @JsonProperty("paidAmount") BigDecimal paidAmount,
-            @JsonProperty("invoiceId") UUID invoiceId,
-            @JsonProperty("paymentId") UUID paymentId,
+            @JsonProperty("accountId") String accountId,
+            @JsonProperty("invoiceId") String invoiceId,
+            @JsonProperty("paymentId") String paymentId,
             @JsonProperty("requestedDt") DateTime requestedDate,
             @JsonProperty("effectiveDt") DateTime effectiveDate,
             @JsonProperty("retryCount") Integer retryCount,
             @JsonProperty("currency") String currency,            
             @JsonProperty("status") String status,
             @JsonProperty("externalBundleKeys") String bundleKeys) {
-        super(amount, paidAmount, invoiceId, paymentId, requestedDate, effectiveDate, retryCount, currency, status);
+        super(amount, paidAmount, accountId, invoiceId, paymentId, requestedDate, effectiveDate, retryCount, currency, status);
         this.bundleKeys = bundleKeys;
     }
     
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
index 8dae3be..7631405 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/AccountResource.java
@@ -29,6 +29,7 @@ import java.util.UUID;
 
 import javax.ws.rs.Consumes;
 import javax.ws.rs.DELETE;
+import javax.ws.rs.DefaultValue;
 import javax.ws.rs.GET;
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
@@ -66,12 +67,14 @@ import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.AccountTimelineJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
 import com.ning.billing.jaxrs.util.TagHelper;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
 import com.ning.billing.payment.api.PaymentAttempt;
+import com.ning.billing.payment.api.PaymentInfoEvent;
 import com.ning.billing.util.api.TagDefinitionApiException;
 import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.customfield.CustomField;
@@ -275,6 +278,33 @@ public class AccountResource implements BaseJaxrsResource {
         }
     }
     
+    /*****************************  PAYMENTS *********************************/
+    
+    @GET
+    @Path("/{accountId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENTS)
+    @Produces(APPLICATION_JSON)
+    public Response getPayments(@PathParam("accountId") String accountId,
+            @QueryParam(QUERY_PAYMENT_LAST4_CC) final String last4CC,
+            @QueryParam(QUERY_PAYMENT_NAME_ON_CC) final String nameOnCC) {
+        try {
+            List<Invoice> invoices =  invoiceApi.getInvoicesByAccount(UUID.fromString(accountId));
+            List<UUID> invoicesId = new ArrayList<UUID>(Collections2.transform(invoices, new Function<Invoice, UUID>() {
+                @Override
+                public UUID apply(Invoice input) {
+                    return input.getId();
+                }
+            }));
+            List<PaymentInfoEvent> payments = paymentApi.getPaymentInfo(invoicesId); 
+            List<PaymentJsonSimple> result =  new ArrayList<PaymentJsonSimple>(payments.size());
+            for (PaymentInfoEvent cur : payments) {
+                result.add(new PaymentJsonSimple(cur));
+            }
+            return Response.status(Status.OK).entity(result).build();
+        } catch (PaymentApiException e) {
+            return Response.status(Status.NOT_FOUND).build();     
+        }
+    }
+
     
     /****************************      TAGS     ******************************/
     
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java
index 2a9e2ee..5eaaf4f 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/BaseJaxrsResource.java
@@ -47,7 +47,12 @@ public interface BaseJaxrsResource {
 	public static final String QUERY_CALL_TIMEOUT = "call_timeout_sec";    
 	public static final String QUERY_DRY_RUN = "dry_run";      
 	public static final String QUERY_TARGET_DATE = "target_date";          
-	public static final String QUERY_ACCOUNT_ID = "account_id";           	
+	
+	public static final String QUERY_ACCOUNT_ID = "account_id";
+
+	public static final String QUERY_PAYMENT_EXTERNAL = "external_payment";
+	public static final String QUERY_PAYMENT_LAST4_CC = "last4_cc";
+	public static final String QUERY_PAYMENT_NAME_ON_CC= "name_on_cc";	
 	
 	public static final String QUERY_TAGS = "tag_list";    
 	public static final String QUERY_CUSTOM_FIELDS = "custom_field_list";    	
@@ -67,6 +72,7 @@ public interface BaseJaxrsResource {
     public static final String INVOICES = "invoices";     
     public static final String INVOICES_PATH = PREFIX + "/" + INVOICES;
 
+    public static final String PAYMENTS = "payments";     
     
     public static final String TAGS = "tags";
     public static final String CUSTOM_FIELDS = "custom_fields";    
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
index fd2ec57..c684b00 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/InvoiceResource.java
@@ -18,6 +18,8 @@ package com.ning.billing.jaxrs.resources;
 
 import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.UUID;
@@ -43,6 +45,7 @@ import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Preconditions;
 import com.google.inject.Inject;
+import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.invoice.api.Invoice;
@@ -50,8 +53,12 @@ import com.ning.billing.invoice.api.InvoiceApiException;
 import com.ning.billing.invoice.api.InvoiceUserApi;
 
 import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.util.Context;
 import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.payment.api.PaymentApi;
+import com.ning.billing.payment.api.PaymentApiException;
+import com.ning.billing.payment.api.PaymentInfoEvent;
 
 
 @Path(BaseJaxrsResource.INVOICES_PATH)
@@ -64,16 +71,19 @@ public class InvoiceResource implements BaseJaxrsResource {
     
     private final AccountUserApi accountApi;
     private final InvoiceUserApi invoiceApi;
+    private final PaymentApi paymentApi;
     private final Context context;
     private final JaxrsUriBuilder uriBuilder;
     
     @Inject
     public InvoiceResource(final AccountUserApi accountApi,
             final InvoiceUserApi invoiceApi,
+            final PaymentApi paymentApi,            
             final Context context,
             final JaxrsUriBuilder uriBuilder) {
         this.accountApi = accountApi;
         this.invoiceApi = invoiceApi;
+        this.paymentApi = paymentApi;
         this.context = context;
         this.uriBuilder = uriBuilder;
     }
@@ -141,4 +151,45 @@ public class InvoiceResource implements BaseJaxrsResource {
             return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();            
         }
     }
+    
+    @GET
+    @Path("/{invoiceId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENTS)
+    @Produces(APPLICATION_JSON)
+    public Response getPayments(@PathParam("invoiceId") String invoiceId) {
+        try {
+            List<PaymentInfoEvent> payments = paymentApi.getPaymentInfo(Collections.singletonList(UUID.fromString(invoiceId)));
+            List<PaymentJsonSimple> result =  new ArrayList<PaymentJsonSimple>(payments.size());
+            for (PaymentInfoEvent cur : payments) {
+                result.add(new PaymentJsonSimple(cur));
+            }
+            return Response.status(Status.OK).entity(result).build();
+        } catch (PaymentApiException e) {
+            return Response.status(Status.NOT_FOUND).build();     
+        }
+    }
+
+    @POST
+    @Produces(APPLICATION_JSON)
+    @Consumes(APPLICATION_JSON)
+    @Path("/{invoiceId:\\w+-\\w+-\\w+-\\w+-\\w+}/" + PAYMENTS)
+    public Response createInstantPayment(PaymentJsonSimple payment,
+            @QueryParam(QUERY_PAYMENT_EXTERNAL) @DefaultValue("false") final Boolean externalPayment,
+            @HeaderParam(HDR_CREATED_BY) final String createdBy,
+            @HeaderParam(HDR_REASON) final String reason,
+            @HeaderParam(HDR_COMMENT) final String comment) {
+        try {
+            Account account = accountApi.getAccountById(UUID.fromString(payment.getAccountId()));
+            paymentApi.createPayment(account, UUID.fromString(payment.getInvoiceId()), context.createContext(createdBy, reason, comment));
+            Response response = uriBuilder.buildResponse(InvoiceResource.class, "getPayments", payment.getInvoiceId());
+            return response;
+        } catch (PaymentApiException e) {
+            final String error = String.format("Failed to create payment %s", e.getMessage());
+            return Response.status(Status.BAD_REQUEST).entity(error).build();
+        } catch (AccountApiException e) {
+            final String error = String.format("Failed to create payment, can't find account %s", payment.getAccountId());
+            return Response.status(Status.BAD_REQUEST).entity(error).build();
+        } catch (IllegalArgumentException e) {
+            return Response.status(Status.BAD_REQUEST).entity(e.getMessage()).build();
+        }
+    }
 }
diff --git a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
index e19b92d..e3335df 100644
--- a/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
+++ b/payment/src/main/java/com/ning/billing/payment/RequestProcessor.java
@@ -16,12 +16,8 @@
 
 package com.ning.billing.payment;
 
-import java.util.Arrays;
-import java.util.List;
+import java.util.Map;
 import java.util.UUID;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ThreadFactory;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -32,24 +28,18 @@ import com.ning.billing.account.api.Account;
 import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.account.api.AccountUserApi;
 import com.ning.billing.invoice.api.InvoiceCreationEvent;
-import com.ning.billing.payment.api.DefaultPaymentErrorEvent;
 import com.ning.billing.payment.api.PaymentApi;
 import com.ning.billing.payment.api.PaymentApiException;
-import com.ning.billing.payment.api.PaymentErrorEvent;
-import com.ning.billing.payment.api.PaymentInfoEvent;
 
-import com.ning.billing.util.bus.Bus;
-import com.ning.billing.util.bus.Bus.EventBusException;
-import com.ning.billing.util.bus.BusEvent;
+import com.ning.billing.util.api.TagUserApi;
 import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.CallOrigin;
 import com.ning.billing.util.callcontext.DefaultCallContext;
 import com.ning.billing.util.callcontext.UserType;
 import com.ning.billing.util.clock.Clock;
-import com.ning.billing.util.globallocker.GlobalLock;
-import com.ning.billing.util.globallocker.GlobalLocker;
-import com.ning.billing.util.globallocker.LockFailedException;
-import com.ning.billing.util.globallocker.GlobalLocker.LockerService;
+import com.ning.billing.util.dao.ObjectType;
+import com.ning.billing.util.tag.ControlTagType;
+import com.ning.billing.util.tag.Tag;
 
 public class RequestProcessor {
 
@@ -64,17 +54,20 @@ public class RequestProcessor {
     private final AccountUserApi accountUserApi;
     private final PaymentApi paymentApi;
     private final Clock clock;
+    private final TagUserApi tagUserApi;
+    
 
     private static final Logger log = LoggerFactory.getLogger(RequestProcessor.class);
 
     @Inject
     public RequestProcessor(final Clock clock,
             final AccountUserApi accountUserApi,
-            final PaymentApi paymentApi,           
-            final GlobalLocker locker) {
+            final PaymentApi paymentApi,
+            final TagUserApi tagUserApi) {        
         this.clock = clock;
         this.accountUserApi = accountUserApi;
         this.paymentApi = paymentApi;
+        this.tagUserApi = tagUserApi;
 
         /*
         this.executor = Executors.newFixedThreadPool(NB_PAYMENT_THREADS, new ThreadFactory() {
@@ -91,7 +84,9 @@ public class RequestProcessor {
 
     @Subscribe
     public void processInvoiceEvent(InvoiceCreationEvent event) {
-        log.info("Received invoice creation notification for account {} and invoice {}", event.getAccountId(), event.getInvoiceId());
+        
+        log.info("Received invoice creation notification for account {} and invoice {}",
+                    event.getAccountId(), event.getInvoiceId());
 
         Account account = null;        
         try {
@@ -100,7 +95,9 @@ public class RequestProcessor {
                 log.error("Failed to process invoice, account {} does not exist!", event.getAccountId());
                 return;
             }
-
+            if (isAccountAutoPayOff(account.getId())) {
+                return;
+            }
             CallContext context = new DefaultCallContext("PaymentRequestProcessor", CallOrigin.INTERNAL, UserType.SYSTEM, event.getUserToken(), clock);
             paymentApi.createPayment(account, event.getInvoiceId(), context);
         } catch(AccountApiException e) {
@@ -109,6 +106,16 @@ public class RequestProcessor {
             log.error("Failed to process invoice payment", e);            
         }
     }
+    
+    private boolean isAccountAutoPayOff(UUID accountId) {
+        Map<String, Tag> accountTags =  tagUserApi.getTags(accountId, ObjectType.ACCOUNT);
+        for (Tag cur : accountTags.values()) {
+            if (cur.getTagDefinitionName().equals(ControlTagType.AUTO_PAY_OFF.toString())) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
 
 
diff --git a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
index fd9d2a2..ccd5b51 100644
--- a/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
+++ b/server/src/main/java/com/ning/billing/server/modules/KillbillServerModule.java
@@ -32,7 +32,6 @@ import com.ning.billing.invoice.glue.DefaultInvoiceModule;
 import com.ning.billing.jaxrs.resources.AccountResource;
 import com.ning.billing.jaxrs.resources.BundleResource;
 import com.ning.billing.jaxrs.resources.InvoiceResource;
-import com.ning.billing.jaxrs.resources.PaymentResource;
 import com.ning.billing.jaxrs.resources.SubscriptionResource;
 import com.ning.billing.jaxrs.resources.TagResource;
 import com.ning.billing.jaxrs.util.KillbillEventHandler;
@@ -67,7 +66,6 @@ public class KillbillServerModule extends AbstractModule
         bind(BundleResource.class).asEagerSingleton();
         bind(SubscriptionResource.class).asEagerSingleton();
         bind(InvoiceResource.class).asEagerSingleton();
-        bind(PaymentResource.class).asEagerSingleton();
         bind(TagResource.class).asEagerSingleton();
         bind(KillbillEventHandler.class).asEagerSingleton();
     }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
index 414f2a0..1f4100c 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestAccount.java
@@ -38,12 +38,15 @@ import org.testng.Assert;
 import org.testng.annotations.Test;
 
 
+import com.fasterxml.jackson.core.type.TypeReference;
 import com.ning.billing.catalog.api.BillingPeriod;
 import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.AccountTimelineJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
 import com.ning.billing.jaxrs.json.CustomFieldJson;
+import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.json.TagDefinitionJson;
 import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
@@ -52,118 +55,150 @@ import com.ning.http.client.Response;
 
 public class TestAccount extends TestJaxrsBase {
 
-	private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
-
-
-	
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountOk() throws Exception {
-		
-		AccountJson input = createAccount("xoxo", "shdgfhwe", "xoxo@yahoo.com");
-		
-		// Retrieves by external key
-		Map<String, String> queryParams = new HashMap<String, String>();
-		queryParams.put(BaseJaxrsResource.QUERY_EXTERNAL_KEY, "shdgfhwe");
-		Response response = doGet(BaseJaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		String baseJson = response.getResponseBody();
-		AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
-		Assert.assertTrue(objFromJson.equals(input));
-		
-		// Update Account
-		AccountJson newInput = new AccountJson(objFromJson.getAccountId(),
-				"zozo", 4, objFromJson.getExternalKey(), "rr@google.com", 18, "EUR", "none", "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
-		baseJson = mapper.writeValueAsString(newInput);
-		final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + objFromJson.getAccountId();
-		response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-		baseJson = response.getResponseBody();
-		objFromJson = mapper.readValue(baseJson, AccountJson.class);
-		Assert.assertTrue(objFromJson.equals(newInput));
-	}
-
-
-	@Test(groups="slow", enabled=true)
-	public void testUpdateNonExistentAccount() throws Exception {
-		AccountJson input = getAccountJson("xoxo", "shghaahwe", "xoxo@yahoo.com");
-		String baseJson = mapper.writeValueAsString(input);
-		final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId();
-		Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-		String body = response.getResponseBody();
-		Assert.assertEquals(body, "");
-	}
-	
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountNonExistent() throws Exception {
-		final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
-	}
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountBadAccountId() throws Exception {
-		final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/yo";
-		Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-		Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
-	}
-	
-	@Test(groups="slow", enabled=true)
-	public void testAccountTimeline() throws Exception {
-	    
+    private static final Logger log = LoggerFactory.getLogger(TestAccount.class);
+
+
+
+
+    @Test(groups="slow", enabled=true)
+    public void testAccountOk() throws Exception {
+
+        AccountJson input = createAccount("xoxo", "shdgfhwe", "xoxo@yahoo.com");
+
+        // Retrieves by external key
+        Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(BaseJaxrsResource.QUERY_EXTERNAL_KEY, "shdgfhwe");
+        Response response = doGet(BaseJaxrsResource.ACCOUNTS_PATH, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        String baseJson = response.getResponseBody();
+        AccountJson objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertTrue(objFromJson.equals(input));
+
+        // Update Account
+        AccountJson newInput = new AccountJson(objFromJson.getAccountId(),
+                "zozo", 4, objFromJson.getExternalKey(), "rr@google.com", 18, "EUR", "none", "UTC", "bl1", "bh2", "", "ca", "usa", "415-255-2991");
+        baseJson = mapper.writeValueAsString(newInput);
+        final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + objFromJson.getAccountId();
+        response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        baseJson = response.getResponseBody();
+        objFromJson = mapper.readValue(baseJson, AccountJson.class);
+        Assert.assertTrue(objFromJson.equals(newInput));
+    }
+
+
+    @Test(groups="slow", enabled=true)
+    public void testUpdateNonExistentAccount() throws Exception {
+        AccountJson input = getAccountJson("xoxo", "shghaahwe", "xoxo@yahoo.com");
+        String baseJson = mapper.writeValueAsString(input);
+        final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + input.getAccountId();
+        Response response = doPut(uri, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+        String body = response.getResponseBody();
+        Assert.assertEquals(body, "");
+    }
+
+
+    @Test(groups="slow", enabled=true)
+    public void testAccountNonExistent() throws Exception {
+        final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/99999999-b103-42f3-8b6e-dd244f1d0747";
+        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NO_CONTENT.getStatusCode());
+    }
+
+    @Test(groups="slow", enabled=true)
+    public void testAccountBadAccountId() throws Exception {
+        final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/yo";
+        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.NOT_FOUND.getStatusCode());
+    }
+
+    @Test(groups="slow", enabled=true)
+    public void testAccountTimeline() throws Exception {
+
         clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
-        
-        
-	    AccountJson accountJson = createAccount("poney", "shdddqgfhwe", "poney@yahoo.com");
-	    assertNotNull(accountJson);
-	    
-	    BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAccountId(), "996599");
-	    assertNotNull(bundleJson);
-	    
+
+
+        AccountJson accountJson = createAccount("poney", "shdddqgfhwe", "poney@yahoo.com");
+        assertNotNull(accountJson);
+
+        BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAccountId(), "996599");
+        assertNotNull(bundleJson);
+
         SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
-        
+
         // MOVE AFTER TRIAL
         clock.addMonths(3);
 
         crappyWaitForLackOfProperSynchonization();
-        
-        
+
+
         final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + BaseJaxrsResource.TIMELINE;
-        
+
         Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
         AccountTimelineJson objFromJson = mapper.readValue(baseJson, AccountTimelineJson.class);
         assertNotNull(objFromJson);
         log.info(baseJson);
-        
-            Assert.assertEquals(objFromJson.getPayments().size(), 3);
+
+        Assert.assertEquals(objFromJson.getPayments().size(), 3);
         Assert.assertEquals(objFromJson.getInvoices().size(), 4);   
         Assert.assertEquals(objFromJson.getBundles().size(), 1); 
         Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().size(), 1);
         Assert.assertEquals(objFromJson.getBundles().get(0).getSubscriptions().get(0).getEvents().size(), 2);        
- 	}
-
-	@Test(groups="slow", enabled=false)
-	public void testAccountWithTags() throws Exception {
-	    //Create Tag definition
-	    TagDefinitionJson input = new TagDefinitionJson("yoyo", "nothing more to say");
-	    String baseJson = mapper.writeValueAsString(input);
-	    Response response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
-	    assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-	    
-	    AccountJson accountJson = createAccount("couroucoucou", "shdwdsqgfhwe", "couroucoucou@yahoo.com");
-	    assertNotNull(accountJson);
-	        
-	    Map<String, String> queryParams = new HashMap<String, String>();
+    }
+
+
+    @Test(groups="slow", enabled=true)
+    public void testAccountPayments() throws Exception {
+
+        clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
+
+
+        AccountJson accountJson = createAccount("ermenehildo", "shtyrgfhwe", "ermenehildo@yahoo.com");
+        assertNotNull(accountJson);
+
+        BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAccountId(), "396199");
+        assertNotNull(bundleJson);
+
+        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+
+        // MOVE AFTER TRIAL
+        clock.addMonths(3);
+
+        crappyWaitForLackOfProperSynchonization();
+
+
+        final String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + accountJson.getAccountId() + "/" + BaseJaxrsResource.PAYMENTS;
+
+        Response response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        String baseJson = response.getResponseBody();
+        List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+        Assert.assertEquals(objFromJson.size(), 3);
+    }
+
+
+    @Test(groups="slow", enabled=false)
+    public void testAccountWithTags() throws Exception {
+        //Create Tag definition
+        TagDefinitionJson input = new TagDefinitionJson("yoyo", "nothing more to say");
+        String baseJson = mapper.writeValueAsString(input);
+        Response response = doPost(BaseJaxrsResource.TAG_DEFINITIONS_PATH, baseJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
+
+        AccountJson accountJson = createAccount("couroucoucou", "shdwdsqgfhwe", "couroucoucou@yahoo.com");
+        assertNotNull(accountJson);
+
+        Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(BaseJaxrsResource.QUERY_TAGS, input.getName());
         String uri = BaseJaxrsResource.ACCOUNTS_PATH + "/" + BaseJaxrsResource.TAGS + "/" + accountJson.getAccountId() ;
-	    response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-        
+
         /*
          * STEPH Some how Location returns the ID twice (confused) :
          * Location: http://127.0.0.1:8080/1.0/kb/accounts/tags/ebb5f830-6f0a-4521-9553-521d173169be/ebb5f830-6f0a-4521-9553-521d173169be
@@ -174,16 +209,16 @@ public class TestAccount extends TestJaxrsBase {
         // Retrieves by Id based on Location returned
         response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        */
+         */
+
+    }
 
-	}
-	
     @Test(groups="slow", enabled=false)
-	public void testAccountWithCustomFields() throws Exception {
-        
+    public void testAccountWithCustomFields() throws Exception {
+
         AccountJson accountJson = createAccount("carafe", "shdwhwgaz", "carafe@yahoo.com");
         assertNotNull(accountJson);
-        
+
         List<CustomFieldJson> customFields =  new LinkedList<CustomFieldJson>();
         customFields.add(new CustomFieldJson("1", "value1"));
         customFields.add(new CustomFieldJson("2", "value2"));
@@ -199,6 +234,6 @@ public class TestAccount extends TestJaxrsBase {
         // Retrieves by Id based on Location returned
         response = doGetWithUrl(location, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
-        
-	}
+
+    }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
index aba67b8..59753e3 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestInvoice.java
@@ -17,7 +17,9 @@ package com.ning.billing.jaxrs;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
 
+import java.math.BigDecimal;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -39,6 +41,7 @@ import com.ning.billing.catalog.api.ProductCategory;
 import com.ning.billing.jaxrs.json.AccountJson;
 import com.ning.billing.jaxrs.json.BundleJsonNoSubsciptions;
 import com.ning.billing.jaxrs.json.InvoiceJsonSimple;
+import com.ning.billing.jaxrs.json.PaymentJsonSimple;
 import com.ning.billing.jaxrs.json.SubscriptionJsonNoEvents;
 import com.ning.billing.jaxrs.resources.BaseJaxrsResource;
 import com.ning.http.client.Response;
@@ -46,36 +49,36 @@ import com.ning.http.client.Response;
 public class TestInvoice extends TestJaxrsBase  {
 
     private final DateTimeFormatter DATE_TIME_FORMATTER = ISODateTimeFormat.dateTime();
-    
+
     private static final Logger log = LoggerFactory.getLogger(TestInvoice.class);
 
 
     @Test(groups="slow", enabled=true)
     public void testInvoiceOk() throws Exception {
-        
+
         DateTime initialDate = new DateTime(2012, 4, 25, 0, 3, 42, 0);
         clock.setDeltaFromReality(initialDate.getMillis() - clock.getUTCNow().getMillis());
-        
-        
+
+
         AccountJson accountJson = createAccount("poupou", "qhddffrwe", "poupou@yahoo.com");
         assertNotNull(accountJson);
-        
+
         BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAccountId(), "9967599");
         assertNotNull(bundleJson);
-        
+
         SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
         assertNotNull(subscriptionJson);
-        
+
         // MOVE AFTER TRIAL
         Interval it = new Interval(clock.getUTCNow(), clock.getUTCNow().plusMonths(3).plusDays(1));
         clock.addDeltaFromReality(it.toDurationMillis());
 
         crappyWaitForLackOfProperSynchonization();
-        
+
         String uri = BaseJaxrsResource.INVOICES_PATH;
         Map<String, String> queryParams = new HashMap<String, String>();
         queryParams.put(BaseJaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
-        
+
         Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
         String baseJson = response.getResponseBody();
@@ -83,7 +86,7 @@ public class TestInvoice extends TestJaxrsBase  {
         assertNotNull(objFromJson);
         log.info(baseJson);
         assertEquals(objFromJson.size(), 4);
-        
+
         // Check we can retrieve an individual invoice
         uri = BaseJaxrsResource.INVOICES_PATH + "/" + objFromJson.get(0).getInvoiceId();
         response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -92,7 +95,7 @@ public class TestInvoice extends TestJaxrsBase  {
         InvoiceJsonSimple firstInvoiceJson = mapper.readValue(baseJson, InvoiceJsonSimple.class);
         assertNotNull(objFromJson);    
         assertEquals(firstInvoiceJson, objFromJson.get(0));
-        
+
         // Then create a dryRun Invoice
         DateTime futureDate = clock.getUTCNow().plusMonths(1).plusDays(3);
         uri = BaseJaxrsResource.INVOICES_PATH;
@@ -104,15 +107,15 @@ public class TestInvoice extends TestJaxrsBase  {
         InvoiceJsonSimple futureInvoice = mapper.readValue(baseJson, InvoiceJsonSimple.class);
         assertNotNull(futureInvoice);    
         log.info(baseJson);
-        
+
         // The one more time with no DryRun
         queryParams.remove(BaseJaxrsResource.QUERY_DRY_RUN);
         response = doPost(uri, null, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
         Assert.assertEquals(response.getStatusCode(), Status.CREATED.getStatusCode());
-        
+
         String location = response.getHeader("Location");
         Assert.assertNotNull(location);
-        
+
         // Check again # invoices, should be 5 this time
         uri = BaseJaxrsResource.INVOICES_PATH;
         response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
@@ -123,4 +126,115 @@ public class TestInvoice extends TestJaxrsBase  {
         log.info(baseJson);
         assertEquals(objFromJson.size(), 5);
     }
+
+    @Test(groups="slow", enabled=true)
+    public void testInvoicePayments() throws Exception {
+
+        clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
+
+        AccountJson accountJson = createAccount("nohup", "shtergyhwF", "nohup@yahoo.com");
+        assertNotNull(accountJson);
+
+        BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
+        assertNotNull(bundleJson);
+
+        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+
+        // MOVE AFTER TRIAL
+        clock.addMonths(3);
+
+        crappyWaitForLackOfProperSynchonization();
+
+        Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(BaseJaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
+        String uri = BaseJaxrsResource.INVOICES_PATH;
+        Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        String baseJson = response.getResponseBody();
+        List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        assertNotNull(invoices);
+        log.info(baseJson);
+        assertEquals(invoices.size(), 4);
+
+
+        for (InvoiceJsonSimple cur : invoices) {
+
+            uri = BaseJaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + BaseJaxrsResource.PAYMENTS;    
+            response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+            Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+            baseJson = response.getResponseBody();
+            List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+            assertNotNull(objFromJson);
+            log.info(cur.getAmount().toString());
+            if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
+                assertEquals(objFromJson.size(), 0);
+            } else {
+                assertEquals(objFromJson.size(), 1);
+                assertTrue(cur.getAmount().compareTo(objFromJson.get(0).getAmount()) == 0);
+            }
+        }
+    }
+
+
+
+    @Test(groups="slow", enabled=true)
+    public void testInvoiceCreatePayment() throws Exception {
+
+        clock.setTime(new DateTime(2012, 4, 25, 0, 3, 42, 0));
+
+        AccountJson accountJson = createAccount("nohup", "shtergyhwF", "nohup@yahoo.com");
+        assertNotNull(accountJson);
+
+
+        // STEPH MISSING SET ACCOUNT AUTO_PAY_OFF
+
+
+        BundleJsonNoSubsciptions bundleJson = createBundle(accountJson.getAccountId(), "391193");
+        assertNotNull(bundleJson);
+
+        SubscriptionJsonNoEvents subscriptionJson = createSubscription(bundleJson.getBundleId(), "Shotgun", ProductCategory.BASE.toString(), BillingPeriod.MONTHLY.toString(), true);
+        assertNotNull(subscriptionJson);
+
+        // MOVE AFTER TRIAL
+        clock.addDays(31);
+
+        crappyWaitForLackOfProperSynchonization();
+
+        Map<String, String> queryParams = new HashMap<String, String>();
+        queryParams.put(BaseJaxrsResource.QUERY_ACCOUNT_ID, accountJson.getAccountId());
+        String uri = BaseJaxrsResource.INVOICES_PATH;
+        Response response = doGet(uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+        assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+        String baseJson = response.getResponseBody();
+        List<InvoiceJsonSimple> invoices = mapper.readValue(baseJson, new TypeReference<List<InvoiceJsonSimple>>() {});
+        assertNotNull(invoices);
+        log.info(baseJson);
+        assertEquals(invoices.size(), 2);
+
+
+        for (InvoiceJsonSimple cur : invoices) {
+            if (cur.getAmount().compareTo(BigDecimal.ZERO) == 0) {
+                continue;
+            }
+
+            // CREATE INSTA PAYMENT
+            PaymentJsonSimple payment = new PaymentJsonSimple(cur.getAmount(), BigDecimal.ZERO, accountJson.getAccountId(), cur.getInvoiceId(), null, null, null, 0, null, null);
+            String postJson = mapper.writeValueAsString(payment);
+            
+            uri = BaseJaxrsResource.INVOICES_PATH + "/" + cur.getInvoiceId() + "/" + BaseJaxrsResource.PAYMENTS;    
+            response = doPost(uri, postJson, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+            response = doGet(uri, DEFAULT_EMPTY_QUERY, DEFAULT_HTTP_TIMEOUT_SEC);
+
+            Assert.assertEquals(response.getStatusCode(), Status.OK.getStatusCode());
+            baseJson = response.getResponseBody();
+            List<PaymentJsonSimple> objFromJson = mapper.readValue(baseJson, new TypeReference<List<PaymentJsonSimple>>() {});
+            assertNotNull(objFromJson);
+            log.info(cur.getAmount().toString());
+            assertEquals(objFromJson.size(), 1);
+            assertTrue(cur.getAmount().compareTo(objFromJson.get(0).getAmount()) == 0);
+        }
+    }
 }