killbill-uncached

invoice: allow to set the metadata field on item adjustments

3/14/2018 7:28:03 AM

Changes

pom.xml 2(+1 -1)

Details

diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
index c6ec872..3ddda2b 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/overdue/TestOverdueIntegration.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -36,7 +36,6 @@ import org.killbill.billing.beatrix.util.InvoiceChecker.ExpectedInvoiceItemCheck
 import org.killbill.billing.catalog.api.BillingPeriod;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
 import org.killbill.billing.catalog.api.PriceListSet;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.entitlement.api.BlockingApiException;
@@ -47,7 +46,6 @@ import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.invoice.api.InvoicePayment;
-import org.killbill.billing.invoice.generator.InvoiceWithMetadata;
 import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
 import org.killbill.billing.overdue.config.DefaultOverdueConfig;
 import org.killbill.billing.overdue.wrapper.OverdueWrapper;
@@ -1147,7 +1145,7 @@ public class TestOverdueIntegration extends TestOverdueBase {
         final BigDecimal accountBalance = invoiceUserApi.getAccountBalance(account.getId(), callContext);
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.BLOCK);
-        invoiceUserApi.insertCredit(account.getId(), accountBalance, new LocalDate(2012, 06, 30), account.getCurrency(), true, "credit invoice", callContext);
+        invoiceUserApi.insertCredit(account.getId(), accountBalance, new LocalDate(2012, 06, 30), account.getCurrency(), true, "credit invoice", null, callContext);
         assertListenerStatus();
 
     }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
index dc48f98..91ee466 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationBase.java
@@ -55,7 +55,6 @@ import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.catalog.api.PhaseType;
 import org.killbill.billing.catalog.api.PlanPhasePriceOverride;
 import org.killbill.billing.catalog.api.PlanPhaseSpecifier;
-import org.killbill.billing.catalog.api.PlanSpecifier;
 import org.killbill.billing.catalog.api.PriceListSet;
 import org.killbill.billing.catalog.api.ProductCategory;
 import org.killbill.billing.entitlement.api.BlockingState;
@@ -119,7 +118,6 @@ import org.killbill.billing.util.config.definition.PaymentConfig;
 import org.killbill.billing.util.dao.NonEntityDao;
 import org.killbill.billing.util.nodes.KillbillNodesApi;
 import org.killbill.billing.util.tag.ControlTagType;
-import org.killbill.billing.util.tag.Tag;
 import org.killbill.bus.api.PersistentBus;
 import org.skife.config.ConfigurationObjectFactory;
 import org.skife.config.TimeSpan;
@@ -792,6 +790,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
                                                                    invoiceItem.getId(),
                                                                    invoice.getInvoiceDate(),
                                                                    null,
+                                                                   null,
                                                                    callContext);
                     }
 
@@ -809,7 +808,7 @@ public class TestIntegrationBase extends BeatrixTestSuiteWithEmbeddedDB implemen
             public Void apply(@Nullable final Void input) {
                 try {
                     invoiceUserApi.insertInvoiceItemAdjustment(account.getId(), invoice.getId(), invoice.getInvoiceItems().get(itemNb - 1).getId(),
-                                                               invoice.getInvoiceDate(), null, callContext);
+                                                               invoice.getInvoiceDate(), null, null, callContext);
                 } catch (final InvoiceApiException e) {
                     fail(e.toString());
                 }
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
index 1c3a68b..5f92da5 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoice.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -84,7 +84,7 @@ public class TestIntegrationInvoice extends TestIntegrationBase {
         assertTrue(accountBalance1.compareTo(new BigDecimal("249.95")) == 0);
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
-        invoiceUserApi.insertCredit(account.getId(), new BigDecimal("300"), new LocalDate(clock.getUTCNow(), account.getTimeZone()), account.getCurrency(), true, null, callContext);
+        invoiceUserApi.insertCredit(account.getId(), new BigDecimal("300"), new LocalDate(clock.getUTCNow(), account.getTimeZone()), account.getCurrency(), true, null, null, callContext);
         assertListenerStatus();
 
         final BigDecimal accountBalance2 = invoiceUserApi.getAccountBalance(account.getId(), callContext);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java
index 70666e2..34b5650 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationInvoiceWithRepairLogic.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -112,7 +112,7 @@ public class TestIntegrationInvoiceWithRepairLogic extends TestIntegrationBase {
         //
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
         invoiceUserApi.insertInvoiceItemAdjustment(account.getId(), invoices.get(1).getId(), invoices.get(1).getInvoiceItems().get(0).getId(), clock.getUTCToday(),
-                                                   BigDecimal.TEN, account.getCurrency(), null, callContext);
+                                                   BigDecimal.TEN, account.getCurrency(), null, null, callContext);
         assertListenerStatus();
 
         invoices = invoiceUserApi.getInvoicesByAccount(account.getId(), false, false, callContext);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java
index e30bbf2..3b5f501 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestIntegrationParentInvoice.java
@@ -262,7 +262,7 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
 
         // add credit to child account when invoice is still unpaid
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
-        invoiceUserApi.insertCredit(childAccount.getId(), BigDecimal.TEN, clock.getUTCToday(), Currency.USD, true, "test", callContext);
+        invoiceUserApi.insertCredit(childAccount.getId(), BigDecimal.TEN, clock.getUTCToday(), Currency.USD, true, "test", null, callContext);
         assertListenerStatus();
 
         final List<Invoice> childInvoices = invoiceUserApi.getInvoicesByAccount(childAccount.getId(), false, false, callContext);
@@ -343,7 +343,7 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
 
         // add credit to child account after invoice has been paid
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
-        invoiceUserApi.insertCredit(childAccount.getId(), BigDecimal.TEN, clock.getUTCToday(), Currency.USD, true, "test", callContext);
+        invoiceUserApi.insertCredit(childAccount.getId(), BigDecimal.TEN, clock.getUTCToday(), Currency.USD, true, "test", null, callContext);
         assertListenerStatus();
 
         List<Invoice> childInvoices = invoiceUserApi.getInvoicesByAccount(childAccount.getId(), false, false, callContext);
@@ -422,7 +422,7 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
         invoiceUserApi.insertInvoiceItemAdjustment(childAccount.getId(), childInvoice.getId(),
                                                    childInvoice.getInvoiceItems().get(0).getId(),
                                                    clock.getToday(childAccount.getTimeZone()), BigDecimal.TEN,
-                                                   childAccount.getCurrency(), "test adjustment", callContext);
+                                                   childAccount.getCurrency(), "test adjustment", null, callContext);
         assertListenerStatus();
 
         // expected child invoice
@@ -580,7 +580,7 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
         invoiceUserApi.insertInvoiceItemAdjustment(childAccount.getId(), childInvoice.getId(),
                                                    childInvoice.getInvoiceItems().get(0).getId(),
                                                    clock.getToday(childAccount.getTimeZone()), amount,
-                                                   childAccount.getCurrency(), "test adjustment", callContext);
+                                                   childAccount.getCurrency(), "test adjustment", null, callContext);
         assertListenerStatus();
     }
 
@@ -640,7 +640,7 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
                                                    childInvoice.getInvoiceItems().get(0).getId(),
                                                    clock.getToday(childAccount.getTimeZone()),
                                                    BigDecimal.TEN,
-                                                   childAccount.getCurrency(), "test adjustment", callContext);
+                                                   childAccount.getCurrency(), "test adjustment", null, callContext);
         assertListenerStatus();
 
         // expected child invoice
@@ -983,7 +983,7 @@ public class TestIntegrationParentInvoice extends TestIntegrationBase {
         final Account childAccount = createAccountWithNonOsgiPaymentMethod(getChildAccountData(billingDay, parentAccount.getId(), true));
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
-        invoiceUserApi.insertCredit(childAccount.getId(), new BigDecimal("250"), new LocalDate(clock.getUTCNow(), childAccount.getTimeZone()), childAccount.getCurrency(), true, null, callContext);
+        invoiceUserApi.insertCredit(childAccount.getId(), new BigDecimal("250"), new LocalDate(clock.getUTCNow(), childAccount.getTimeZone()), childAccount.getCurrency(), true, null, null, callContext);
         assertListenerStatus();
 
         BigDecimal childAccountCBA = invoiceUserApi.getAccountCBA(childAccount.getId(), callContext);
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java
index 2d71497..0679a98 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestInvoicePayment.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -118,7 +118,7 @@ public class TestInvoicePayment extends TestIntegrationBase {
         Assert.assertNotNull(itemForBPEntitlement1);
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE_ADJUSTMENT);
-        invoiceUserApi.insertInvoiceItemAdjustment(account.getId(), thirdInvoice.getId(), itemForBPEntitlement1.getId(), new LocalDate(2016, 10, 2), UUID.randomUUID().toString(), callContext);
+        invoiceUserApi.insertInvoiceItemAdjustment(account.getId(), thirdInvoice.getId(), itemForBPEntitlement1.getId(), new LocalDate(2016, 10, 2), UUID.randomUUID().toString(), UUID.randomUUID().toString(), callContext);
         assertListenerStatus();
 
         // Expect also payment for previous invoice
diff --git a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java
index 94c20fc..c02877a 100644
--- a/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java
+++ b/beatrix/src/test/java/org/killbill/billing/beatrix/integration/TestWithTaxItems.java
@@ -22,7 +22,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
 import javax.inject.Inject;
 
 import org.joda.time.LocalDate;
@@ -45,11 +44,7 @@ import org.killbill.billing.invoice.plugin.api.InvoicePluginApi;
 import org.killbill.billing.osgi.api.OSGIServiceDescriptor;
 import org.killbill.billing.osgi.api.OSGIServiceRegistration;
 import org.killbill.billing.payment.api.PluginProperty;
-import org.killbill.billing.util.api.TagApiException;
-import org.killbill.billing.util.api.TagDefinitionApiException;
 import org.killbill.billing.util.callcontext.CallContext;
-import org.killbill.billing.util.tag.ControlTagType;
-import org.killbill.billing.util.tag.Tag;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -211,7 +206,7 @@ public class TestWithTaxItems extends TestIntegrationBase {
         subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
 
         busHandler.pushExpectedEvents(NextEvent.INVOICE);
-        invoiceUserApi.insertCredit(account.getId(), new BigDecimal("100"), clock.getUTCToday(), account.getCurrency(), true, "VIP", callContext);
+        invoiceUserApi.insertCredit(account.getId(), new BigDecimal("100"), clock.getUTCToday(), account.getCurrency(), true, "VIP", null, callContext);
         assertListenerStatus();
 
         invoiceChecker.checkInvoice(account.getId(), 2, callContext,
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
index 32cdd27..c4e791f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/InvoiceApiHelper.java
@@ -127,6 +127,7 @@ public class InvoiceApiHelper {
                                             @Nullable final Currency currency,
                                             final LocalDate effectiveDate,
                                             final String description,
+                                            @Nullable final String itemDetails,
                                             final InternalCallContext context) throws InvoiceApiException {
         final InvoiceItem invoiceItemToBeAdjusted = Iterables.<InvoiceItem>tryFind(invoiceToBeAdjusted.getInvoiceItems(),
                                                                                    new Predicate<InvoiceItem>() {
@@ -168,7 +169,7 @@ public class InvoiceApiHelper {
                                       amountToAdjust,
                                       currencyForAdjustment,
                                       invoiceItemToBeAdjusted.getId(),
-                                      null);
+                                      itemDetails);
     }
 
     private List<InvoiceItem> fromInvoiceItemModelDao(final Collection<InvoiceItemModelDao> invoiceItemModelDaos) {
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
index 43d1eb9..29784f4 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/api/user/DefaultInvoiceUserApi.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -356,23 +356,23 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
         }
 
         return new CreditAdjInvoiceItem(creditItem.getId(), creditItem.getCreatedDate(), creditItem.getInvoiceId(), creditItem.getAccountId(),
-                                        creditItem.getStartDate(), creditItem.getDescription(), creditItem.getAmount().negate(), creditItem.getCurrency());
+                                        creditItem.getStartDate(), creditItem.getDescription(), creditItem.getAmount().negate(), creditItem.getCurrency(), creditItem.getItemDetails());
     }
 
     @Override
     public InvoiceItem insertCredit(final UUID accountId, final BigDecimal amount, final LocalDate effectiveDate,
-                                    final Currency currency, final boolean autoCommit, final String description, final CallContext context) throws InvoiceApiException {
-        return insertCreditForInvoice(accountId, null, amount, effectiveDate, currency, autoCommit, description, context);
+                                    final Currency currency, final boolean autoCommit, final String description, final String itemDetails, final CallContext context) throws InvoiceApiException {
+        return insertCreditForInvoice(accountId, null, amount, effectiveDate, currency, autoCommit, description, itemDetails, context);
     }
 
     @Override
     public InvoiceItem insertCreditForInvoice(final UUID accountId, final UUID invoiceId, final BigDecimal amount,
-                                              final LocalDate effectiveDate, final Currency currency, final String description, final CallContext context) throws InvoiceApiException {
-        return insertCreditForInvoice(accountId, invoiceId, amount, effectiveDate, currency, false, description, context);
+                                              final LocalDate effectiveDate, final Currency currency, final String description, final String itemDetails, final CallContext context) throws InvoiceApiException {
+        return insertCreditForInvoice(accountId, invoiceId, amount, effectiveDate, currency, false, description, itemDetails, context);
     }
 
     private InvoiceItem insertCreditForInvoice(final UUID accountId, final UUID invoiceId, final BigDecimal amount, final LocalDate effectiveDate,
-                                               final Currency currency, final boolean autoCommit, final String description, final CallContext context) throws InvoiceApiException {
+                                               final Currency currency, final boolean autoCommit, final String description, final String itemDetails, final CallContext context) throws InvoiceApiException {
         if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
             throw new InvoiceApiException(ErrorCode.CREDIT_AMOUNT_INVALID, amount);
         }
@@ -407,7 +407,8 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                                       description,
                                                       // Note! The amount is negated here!
                                                       amount.negate(),
-                                                      currency);
+                                                      currency,
+                                                      itemDetails);
                 invoiceForCredit.addInvoiceItem(creditItem);
 
                 return ImmutableList.<Invoice>of(invoiceForCredit);
@@ -428,14 +429,14 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
 
     @Override
     public InvoiceItem insertInvoiceItemAdjustment(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId,
-                                                   final LocalDate effectiveDate, final String description, final CallContext context) throws InvoiceApiException {
-        return insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItemId, effectiveDate, null, null, description, context);
+                                                   final LocalDate effectiveDate, final String description, final String itemDetails, final CallContext context) throws InvoiceApiException {
+        return insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItemId, effectiveDate, null, null, description, itemDetails, context);
     }
 
     @Override
     public InvoiceItem insertInvoiceItemAdjustment(final UUID accountId, final UUID invoiceId, final UUID invoiceItemId,
                                                    final LocalDate effectiveDate, @Nullable final BigDecimal amount,
-                                                   @Nullable final Currency currency, final String description, final CallContext context) throws InvoiceApiException {
+                                                   @Nullable final Currency currency, final String description, final String itemDetails, final CallContext context) throws InvoiceApiException {
         if (amount != null && amount.compareTo(BigDecimal.ZERO) <= 0) {
             throw new InvoiceApiException(ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_SHOULD_BE_POSITIVE, amount);
         }
@@ -450,6 +451,7 @@ public class DefaultInvoiceUserApi implements InvoiceUserApi {
                                                                                          currency,
                                                                                          effectiveDate,
                                                                                          description,
+                                                                                         itemDetails,
                                                                                          internalCallContextFactory.createInternalCallContext(accountId, context));
                 if (adjustmentItem != null) {
                     invoice.addInvoiceItem(adjustmentItem);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
index 51d646b..c51221b 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/dao/DefaultInvoiceDao.java
@@ -1270,7 +1270,8 @@ public class DefaultInvoiceDao extends EntityDaoBase<InvoiceModelDao, Invoice, I
                                                                         creditDescription,
                                                                         // Note! The amount is negated here!
                                                                         accountCBA.negate(),
-                                                                        childAccount.getCurrency());
+                                                                        childAccount.getCurrency(),
+                                                                        null);
                 invoiceForCredit.addInvoiceItem(creditItem);
 
                 // save invoices and invoice items
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java b/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java
index 68ef0d8..3962abd 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/CreditAdjInvoiceItem.java
@@ -34,13 +34,13 @@ import com.google.common.base.MoreObjects;
 public class CreditAdjInvoiceItem extends AdjInvoiceItem {
 
     public CreditAdjInvoiceItem(final UUID invoiceId, final UUID accountId, final LocalDate date,
-                                @Nullable final String description, final BigDecimal amount, final Currency currency) {
-        this(UUIDs.randomUUID(), null, invoiceId, accountId, date, description, amount, currency);
+                                @Nullable final String description, final BigDecimal amount, final Currency currency, @Nullable final String itemDetails) {
+        this(UUIDs.randomUUID(), null, invoiceId, accountId, date, description, amount, currency, itemDetails);
     }
 
     public CreditAdjInvoiceItem(final UUID id, @Nullable final DateTime createdDate, final UUID invoiceId, final UUID accountId, final LocalDate date,
-                                @Nullable final String description, final BigDecimal amount, final Currency currency) {
-        super(id, createdDate, invoiceId, accountId, date, date, description, amount, currency, null, InvoiceItemType.CREDIT_ADJ);
+                                @Nullable final String description, final BigDecimal amount, final Currency currency, @Nullable final String itemDetails) {
+        super(id, createdDate, invoiceId, accountId, date, date, description, amount, currency, null, itemDetails, InvoiceItemType.CREDIT_ADJ);
     }
 
     @Override
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
index b56e6ac..2495061 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/DefaultInvoice.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
index a8865b7..00f3d2f 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/model/InvoiceItemFactory.java
@@ -94,7 +94,7 @@ public class InvoiceItemFactory {
                 item = new CreditBalanceAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, linkedItemId, description, amount, currency);
                 break;
             case CREDIT_ADJ:
-                item = new CreditAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, description, amount, currency);
+                item = new CreditAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, description, amount, currency, itemDetails);
                 break;
             case REPAIR_ADJ:
                 item = new RepairAdjInvoiceItem(id, createdDate, invoiceId, accountId, startDate, endDate, description, amount, currency, linkedItemId);
diff --git a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
index f913ce3..aa7fc28 100644
--- a/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
+++ b/invoice/src/main/java/org/killbill/billing/invoice/template/formatters/DefaultInvoiceFormatter.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -146,7 +146,7 @@ public class DefaultInvoiceFormatter implements InvoiceFormatter {
                 invoiceItems.add(item);
             } else {
                 mergedInvoiceAdjustment = new CreditAdjInvoiceItem(invoice.getId(), invoice.getAccountId(), invoice.getInvoiceDate(), mergedInvoiceAdjustment.getDescription(),
-                                                                   mergedInvoiceAdjustment.getAmount().add(item.getAmount()), mergedInvoiceAdjustment.getCurrency());
+                                                                   mergedInvoiceAdjustment.getAmount().add(item.getAmount()), mergedInvoiceAdjustment.getCurrency(), mergedInvoiceAdjustment.getItemDetails());
             }
         }
         return mergedInvoiceAdjustment;
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
index 3d5e624..d289ef3 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestDefaultInvoiceUserApi.java
@@ -28,8 +28,6 @@ import org.joda.time.DateTime;
 import org.killbill.billing.ErrorCode;
 import org.killbill.billing.ObjectType;
 import org.killbill.billing.account.api.Account;
-import org.killbill.billing.api.TestApiListener.NextEvent;
-import org.killbill.billing.callcontext.DefaultCallContext;
 import org.killbill.billing.callcontext.InternalCallContext;
 import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.InvoiceTestSuiteWithEmbeddedDB;
@@ -41,15 +39,12 @@ import org.killbill.billing.invoice.api.InvoiceItemType;
 import org.killbill.billing.invoice.api.InvoicePayment;
 import org.killbill.billing.invoice.api.InvoicePaymentType;
 import org.killbill.billing.invoice.api.InvoiceStatus;
-import org.killbill.billing.invoice.api.InvoiceUserApi;
 import org.killbill.billing.invoice.model.DefaultInvoicePayment;
 import org.killbill.billing.invoice.model.ExternalChargeInvoiceItem;
 import org.killbill.billing.util.api.TagApiException;
-import org.killbill.billing.util.callcontext.CallContext;
 import org.killbill.billing.util.currency.KillBillMoney;
 import org.killbill.billing.util.tag.ControlTagType;
 import org.killbill.billing.util.tag.Tag;
-import org.killbill.clock.ClockMock;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -176,7 +171,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
 
         // Adjust the invoice for the full amount
         final InvoiceItem creditInvoiceItem = invoiceUserApi.insertCreditForInvoice(accountId, invoiceId, invoiceBalance,
-                                                                                    clock.getUTCToday(), accountCurrency, "some description", callContext);
+                                                                                    clock.getUTCToday(), accountCurrency, "some description", null, callContext);
         Assert.assertEquals(creditInvoiceItem.getInvoiceId(), invoiceId);
         Assert.assertEquals(creditInvoiceItem.getInvoiceItemType(), InvoiceItemType.CREDIT_ADJ);
         Assert.assertEquals(creditInvoiceItem.getAccountId(), accountId);
@@ -198,7 +193,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
     public void testCantAdjustInvoiceWithNegativeAmount() throws Exception {
         try {
             invoiceUserApi.insertCreditForInvoice(accountId, invoiceId, BigDecimal.TEN.negate(), clock.getUTCToday(), accountCurrency,
-                                                  null, callContext);
+                                                  null, null, callContext);
             Assert.fail("Should not have been able to adjust an invoice with a negative amount");
         } catch (InvoiceApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.CREDIT_AMOUNT_INVALID.getCode());
@@ -221,7 +216,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
 
         // Adjust the invoice for the full amount
         final InvoiceItem adjInvoiceItem = invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(),
-                                                                                      clock.getUTCToday(), null, callContext);
+                                                                                      clock.getUTCToday(), null, null, callContext);
         Assert.assertEquals(adjInvoiceItem.getInvoiceId(), invoiceId);
         Assert.assertEquals(adjInvoiceItem.getInvoiceItemType(), InvoiceItemType.ITEM_ADJ);
         Assert.assertEquals(adjInvoiceItem.getAccountId(), accountId);
@@ -238,7 +233,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
         Assert.assertEquals(adjustedAccountBalance, adjustedInvoiceBalance);
 
         // Verify idempotency
-        Assert.assertNull(invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(), null, callContext));
+        Assert.assertNull(invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(), null, null, callContext));
     }
 
     @Test(groups = "slow")
@@ -274,7 +269,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
         final BigDecimal adjAmount = invoiceItem.getAmount().subtract(new BigDecimal("0.01"));
         final InvoiceItem adjInvoiceItem = invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(),
                                                                                       clock.getUTCToday(), adjAmount, accountCurrency,
-                                                                                      null, callContext);
+                                                                                      null, null, callContext);
         Assert.assertEquals(adjInvoiceItem.getInvoiceId(), invoiceId);
         Assert.assertEquals(adjInvoiceItem.getInvoiceItemType(), InvoiceItemType.ITEM_ADJ);
         Assert.assertEquals(adjInvoiceItem.getAccountId(), accountId);
@@ -301,7 +296,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
 
         try {
             invoiceUserApi.insertInvoiceItemAdjustment(accountId, invoiceId, invoiceItem.getId(), clock.getUTCToday(),
-                                                       BigDecimal.TEN.negate(), accountCurrency, null, callContext);
+                                                       BigDecimal.TEN.negate(), accountCurrency, null, null, callContext);
             Assert.fail("Should not have been able to adjust an item with a negative amount");
         } catch (InvoiceApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_ITEM_ADJUSTMENT_AMOUNT_SHOULD_BE_POSITIVE.getCode());
@@ -350,7 +345,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
         // Adjust the invoice for the full amount
         final BigDecimal creditAmount = BigDecimal.TEN;
         final InvoiceItem creditInvoiceItem = invoiceUserApi.insertCreditForInvoice(accountId, null, creditAmount,
-                                                                                    clock.getUTCToday(), accountCurrency, null, callContext);
+                                                                                    clock.getUTCToday(), accountCurrency, null, null, callContext);
 
         final UUID invoiceId = creditInvoiceItem.getInvoiceId();
         Invoice creditInvoice = invoiceUserApi.getInvoice(invoiceId, callContext);
@@ -376,7 +371,7 @@ public class TestDefaultInvoiceUserApi extends InvoiceTestSuiteWithEmbeddedDB {
 
         try {
             invoiceUserApi.insertCreditForInvoice(accountId, invoiceId, creditAmount,
-                                                  clock.getUTCToday(), accountCurrency, null, callContext);
+                                                  clock.getUTCToday(), accountCurrency, null, null, callContext);
             Assert.fail("Should fail to add credit on already committed invoice");
         } catch (final InvoiceApiException e) {
             Assert.assertEquals(e.getCode(), ErrorCode.INVOICE_ALREADY_COMMITTED.getCode());
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java
index 63b366c..4ca8023 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/api/user/TestInvoiceFlagBehaviors.java
@@ -1,6 +1,6 @@
 /*
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -81,7 +81,7 @@ public class TestInvoiceFlagBehaviors extends InvoiceTestSuiteWithEmbeddedDB {
         assertEquals(accountCBA1.compareTo(BigDecimal.ZERO), 0);
 
         // Add credit on the account
-        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, null, callContext);
 
         final Invoice invoice2 = invoiceUserApi.getInvoice(invoiceId, callContext);
         assertEquals(invoice2.getBalance().compareTo(BigDecimal.ZERO), 0);
@@ -100,7 +100,7 @@ public class TestInvoiceFlagBehaviors extends InvoiceTestSuiteWithEmbeddedDB {
     public void testWrittenOffInvoiceWithAccountCredit() throws Exception {
 
         // Add credit on the account
-        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, null, callContext);
 
         final BigDecimal accountBalance0 = invoiceUserApi.getAccountBalance(accountId, callContext);
         assertEquals(accountBalance0.compareTo(new BigDecimal("-10.0")), 0);
@@ -133,7 +133,7 @@ public class TestInvoiceFlagBehaviors extends InvoiceTestSuiteWithEmbeddedDB {
     public void testMigratedInvoiceWithAccountCredit() throws Exception {
 
         // Add credit on the account
-        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, null, callContext);
 
         final UUID invoiceId = invoiceUserApi.createMigrationInvoice(accountId, null, ImmutableList.<InvoiceItem>of(new FixedPriceInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, "foo", "bar", null, null, BigDecimal.ONE, accountCurrency)), callContext);
 
@@ -153,7 +153,7 @@ public class TestInvoiceFlagBehaviors extends InvoiceTestSuiteWithEmbeddedDB {
     public void testDraftInvoiceWithAccountCredit() throws Exception {
 
         // Add credit on the account
-        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, callContext);
+        invoiceUserApi.insertCredit(accountId, BigDecimal.TEN, null, accountCurrency, true, null, null, callContext);
 
         // Create new invoice with one charge and expect account credit to be used
         final List<InvoiceItem> items = invoiceUserApi.insertExternalCharges(accountId, clock.getUTCToday(), ImmutableList.<InvoiceItem>of(new ExternalChargeInvoiceItem(UUID.randomUUID(), clock.getUTCNow(), null, accountId, null, null, null, null, new BigDecimal("4.0"), accountCurrency, null)), false, callContext);
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
index 9e2e1a8..d4cdc26 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/dao/TestInvoiceDao.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -549,7 +549,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                     endDate, rate1, rate1, Currency.USD);
         invoiceUtil.createInvoiceItem(item1, context);
 
-        final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), null, rate1.negate(), Currency.USD);
+        final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice1.getId(), accountId, new LocalDate(), null, rate1.negate(), Currency.USD, null);
         invoiceUtil.createInvoiceItem(creditItem, context);
 
         final BigDecimal balance = invoiceDao.getAccountBalance(accountId, context);
@@ -963,7 +963,7 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
         assertEquals(cba.compareTo(new BigDecimal("0.00")), 0);
 
         // FINALLY ISSUE A CREDIT ADJ
-        final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice2.getId(), accountId, new LocalDate(), null, rate2.negate(), Currency.USD);
+        final CreditAdjInvoiceItem creditItem = new CreditAdjInvoiceItem(invoice2.getId(), accountId, new LocalDate(), null, rate2.negate(), Currency.USD, null);
         invoiceUtil.createInvoiceItem(creditItem, context);
         balance = invoiceDao.getAccountBalance(accountId, context);
         assertEquals(balance.compareTo(new BigDecimal("0.00")), 0);
@@ -1769,7 +1769,8 @@ public class TestInvoiceDao extends InvoiceTestSuiteWithEmbeddedDB {
                                                                           null,
                                                                           // Note! The amount is negated here!
                                                                           creditAmount.negate(),
-                                                                          invoiceModelDao.getCurrency());
+                                                                          invoiceModelDao.getCurrency(),
+                                                                          null);
         invoiceModelDao.addInvoiceItem(new InvoiceItemModelDao(invoiceItem));
         return invoiceDao.createInvoices(ImmutableList.<InvoiceModelDao>of(invoiceModelDao), context).get(0);
     }
diff --git a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
index f072706..d31887a 100644
--- a/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
+++ b/invoice/src/test/java/org/killbill/billing/invoice/template/formatters/TestDefaultInvoiceFormatter.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -117,7 +117,7 @@ public class TestDefaultInvoiceFormatter extends InvoiceTestSuiteNoDB {
                                                                                                         fixedItem.getStartDate(), fixedItem.getAmount(),
                                                                                                         fixedItem.getCurrency());
         final CreditAdjInvoiceItem creditAdjInvoiceItem = new CreditAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(),
-                                                                                   fixedItem.getStartDate(), null, BigDecimal.ONE.negate(), fixedItem.getCurrency());
+                                                                                   fixedItem.getStartDate(), null, BigDecimal.ONE.negate(), fixedItem.getCurrency(), null);
         final CreditBalanceAdjInvoiceItem creditBalanceAdjInvoiceItem2 = new CreditBalanceAdjInvoiceItem(fixedItem.getInvoiceId(), fixedItem.getAccountId(),
                                                                                                          fixedItem.getStartDate(), creditAdjInvoiceItem.getAmount().negate(),
                                                                                                          fixedItem.getCurrency());
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java
index a65fda4..ee41c5d 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/CreditJson.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -23,7 +25,6 @@ import java.util.UUID;
 import javax.annotation.Nullable;
 
 import org.joda.time.LocalDate;
-import org.killbill.billing.catalog.api.Currency;
 import org.killbill.billing.invoice.api.Invoice;
 import org.killbill.billing.invoice.api.InvoiceItem;
 import org.killbill.billing.util.audit.AuditLog;
@@ -33,7 +34,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
-@ApiModel(value="Credit")
+@ApiModel(value = "Credit")
 public class CreditJson extends JsonBase {
 
     @ApiModelProperty(required = true)
@@ -44,9 +45,9 @@ public class CreditJson extends JsonBase {
     @ApiModelProperty(required = true)
     private final UUID accountId;
     private final String description;
+    private final String itemDetails;
     private final String currency;
 
-
     @JsonCreator
     public CreditJson(@JsonProperty("creditAmount") final BigDecimal creditAmount,
                       @JsonProperty("currency") final String currency,
@@ -55,6 +56,7 @@ public class CreditJson extends JsonBase {
                       @JsonProperty("effectiveDate") final LocalDate effectiveDate,
                       @JsonProperty("accountId") final UUID accountId,
                       @JsonProperty("description") final String description,
+                      @JsonProperty("itemDetails") final String itemDetails,
                       @JsonProperty("auditLogs") @Nullable final List<AuditLogJson> auditLogs) {
         super(auditLogs);
         this.creditAmount = creditAmount;
@@ -63,6 +65,7 @@ public class CreditJson extends JsonBase {
         this.invoiceNumber = invoiceNumber;
         this.effectiveDate = effectiveDate;
         this.description = description;
+        this.itemDetails = itemDetails;
         this.accountId = accountId;
     }
 
@@ -75,6 +78,7 @@ public class CreditJson extends JsonBase {
         this.invoiceNumber = invoice.getInvoiceNumber().toString();
         this.effectiveDate = credit.getStartDate();
         this.description = credit.getDescription();
+        this.itemDetails = credit.getItemDetails();
     }
 
     public CreditJson(final Invoice invoice, final InvoiceItem credit) {
@@ -105,6 +109,10 @@ public class CreditJson extends JsonBase {
         return description;
     }
 
+    public String getItemDetails() {
+        return itemDetails;
+    }
+
     public String getCurrency() {
         return currency;
     }
@@ -119,6 +127,7 @@ public class CreditJson extends JsonBase {
         sb.append(", invoiceNumber='").append(invoiceNumber).append('\'');
         sb.append(", effectiveDate=").append(effectiveDate);
         sb.append(", description=").append(description);
+        sb.append(", itemDetails=").append(itemDetails);
         sb.append(", accountId=").append(accountId);
         sb.append('}');
         return sb.toString();
@@ -151,6 +160,9 @@ public class CreditJson extends JsonBase {
         if (description != null ? !description.equals(that.description) : that.description != null) {
             return false;
         }
+        if (itemDetails != null ? !itemDetails.equals(that.itemDetails) : that.itemDetails != null) {
+            return false;
+        }
         if (!((effectiveDate == null && that.effectiveDate == null) ||
               (effectiveDate != null && that.effectiveDate != null && effectiveDate.compareTo(that.effectiveDate) == 0))) {
             return false;
@@ -165,6 +177,7 @@ public class CreditJson extends JsonBase {
         result = 31 * result + (currency != null ? currency.hashCode() : 0);
         result = 31 * result + (invoiceId != null ? invoiceId.hashCode() : 0);
         result = 31 * result + (description != null ? description.hashCode() : 0);
+        result = 31 * result + (itemDetails != null ? itemDetails.hashCode() : 0);
         result = 31 * result + (invoiceNumber != null ? invoiceNumber.hashCode() : 0);
         result = 31 * result + (effectiveDate != null ? effectiveDate.hashCode() : 0);
         return result;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 23aa22f..01a673e 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2017 Groupon, Inc
- * Copyright 2014-2017 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -449,7 +449,7 @@ public class AccountResource extends JaxRsResourceBase {
             for (final Invoice invoice : unpaidInvoices) {
                 for (final InvoiceItem item : invoice.getInvoiceItems()) {
                     if (ADJUSTABLE_TYPES.contains(item.getInvoiceItemType())) {
-                        invoiceApi.insertInvoiceItemAdjustment(accountId, invoice.getId(), item.getId(), clock.getUTCToday(), description, callContext);
+                        invoiceApi.insertInvoiceItemAdjustment(accountId, invoice.getId(), item.getId(), clock.getUTCToday(), description, null, callContext);
                     }
                 }
             }
@@ -793,7 +793,7 @@ public class AccountResource extends JaxRsResourceBase {
         // then we apply some credit on the account.
         //
         if (externalPayment && remainingRequestPayment.compareTo(BigDecimal.ZERO) > 0) {
-            invoiceApi.insertCredit(account.getId(), remainingRequestPayment, clock.getUTCToday(), account.getCurrency(), true, "pay all invoices", callContext);
+            invoiceApi.insertCredit(account.getId(), remainingRequestPayment, clock.getUTCToday(), account.getCurrency(), true, "pay all invoices", null, callContext);
         }
         return Response.status(Status.OK).build();
     }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
index d560165..27558a0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -124,11 +126,11 @@ public class CreditResource extends JaxRsResourceBase {
         if (json.getInvoiceId() != null) {
             // Apply an invoice level credit
             credit = invoiceUserApi.insertCreditForInvoice(account.getId(), json.getInvoiceId(), json.getCreditAmount(),
-                                                           effectiveDate, account.getCurrency(), json.getDescription(), callContext);
+                                                           effectiveDate, account.getCurrency(), json.getDescription(), json.getItemDetails(), callContext);
         } else {
             // Apply a account level credit
             credit = invoiceUserApi.insertCredit(account.getId(), json.getCreditAmount(), effectiveDate,
-                                                 account.getCurrency(), autoCommit, json.getDescription(), callContext);
+                                                 account.getCurrency(), autoCommit, json.getDescription(), json.getItemDetails(), callContext);
         }
 
         return uriBuilder.buildResponse(uriInfo, CreditResource.class, "getCredit", credit.getId(), request);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 8855d34..4726dc4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014 Groupon, Inc
- * Copyright 2014 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -459,6 +459,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                                     json.getInvoiceItemId(),
                                                                     requestedDate,
                                                                     json.getDescription(),
+                                                                    json.getItemDetails(),
                                                                     callContext);
         } else {
             adjustmentItem = invoiceApi.insertInvoiceItemAdjustment(accountId,
@@ -468,6 +469,7 @@ public class InvoiceResource extends JaxRsResourceBase {
                                                                     json.getAmount(),
                                                                     Currency.valueOf(json.getCurrency()),
                                                                     json.getDescription(),
+                                                                    json.getItemDetails(),
                                                                     callContext);
         }
 
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java
index 265c3e4..ad245f5 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestCreditJson.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -20,14 +22,12 @@ import java.math.BigDecimal;
 import java.util.List;
 import java.util.UUID;
 
-import org.joda.time.DateTime;
 import org.joda.time.LocalDate;
 import org.killbill.billing.catalog.api.Currency;
+import org.killbill.billing.jaxrs.JaxrsTestSuiteNoDB;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-import org.killbill.billing.jaxrs.JaxrsTestSuiteNoDB;
-
 import static org.killbill.billing.jaxrs.JaxrsTestUtils.createAuditLogsJson;
 
 public class TestCreditJson extends JaxrsTestSuiteNoDB {
@@ -42,7 +42,7 @@ public class TestCreditJson extends JaxrsTestSuiteNoDB {
         final UUID accountId = UUID.randomUUID();
         final List<AuditLogJson> auditLogs = createAuditLogsJson(clock.getUTCNow());
         final CreditJson creditJson = new CreditJson(creditAmount, currency.name(), invoiceId, invoiceNumber, effectiveDate,
-                                                     accountId, null, auditLogs);
+                                                     accountId, null, null, auditLogs);
         Assert.assertEquals(creditJson.getEffectiveDate(), effectiveDate);
         Assert.assertEquals(creditJson.getCreditAmount(), creditAmount);
         Assert.assertEquals(creditJson.getInvoiceId(), invoiceId);
diff --git a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
index 5dcbc4e..67df93d 100644
--- a/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
+++ b/jaxrs/src/test/java/org/killbill/billing/jaxrs/json/TestInvoiceJsonWithBundleKeys.java
@@ -1,7 +1,9 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
- * Ning licenses this file to you under the Apache License, version 2.0
+ * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
  * License.  You may obtain a copy of the License at:
  *
@@ -117,6 +119,6 @@ public class TestInvoiceJsonWithBundleKeys extends JaxrsTestSuiteNoDB {
         final String invoiceNumber = UUID.randomUUID().toString();
         final LocalDate effectiveDate = clock.getUTCToday();
         final UUID accountId = UUID.randomUUID();
-        return new CreditJson(creditAmount, currency.name(), invoiceId, invoiceNumber, effectiveDate,  accountId, null, null);
+        return new CreditJson(creditAmount, currency.name(), invoiceId, invoiceNumber, effectiveDate,  accountId, null, null, null);
     }
 }

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index c1933c2..7544fc9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <artifactId>killbill-oss-parent</artifactId>
         <groupId>org.kill-bill.billing</groupId>
-        <version>0.141.43</version>
+        <version>0.141.44-SNAPSHOT</version>
     </parent>
     <artifactId>killbill</artifactId>
     <version>0.19.6-SNAPSHOT</version>
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCredit.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCredit.java
index e323ac2..c7562dd 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCredit.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestCredit.java
@@ -1,7 +1,7 @@
 /*
  * Copyright 2010-2013 Ning, Inc.
- * Copyright 2014-2016 Groupon, Inc
- * Copyright 2014-2016 The Billing Project, LLC
+ * Copyright 2014-2018 Groupon, Inc
+ * Copyright 2014-2018 The Billing Project, LLC
  *
  * The Billing Project licenses this file to you under the Apache License, version 2.0
  * (the "License"); you may not use this file except in compliance with the
@@ -52,6 +52,7 @@ public class TestCredit extends TestJaxrsBase {
         credit.setAccountId(accountJson.getAccountId());
         credit.setCreditAmount(creditAmount);
         credit.setDescription("description");
+        credit.setItemDetails("itemDetails");
         Credit objFromJson = killBillClient.createCredit(credit, false, createdBy, reason, comment);
 
         final UUID invoiceId = objFromJson.getInvoiceId();
diff --git a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
index be7db70..a476775 100644
--- a/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
+++ b/profiles/killbill/src/test/java/org/killbill/billing/jaxrs/TestInvoice.java
@@ -359,12 +359,25 @@ public class TestInvoice extends TestJaxrsBase {
         adjustmentInvoiceItem.setAccountId(accountJson.getAccountId());
         adjustmentInvoiceItem.setInvoiceId(invoice.getInvoiceId());
         adjustmentInvoiceItem.setInvoiceItemId(invoiceItem.getInvoiceItemId());
-        killBillClient.adjustInvoiceItem(invoiceItem, requestOptions);
+        final String itemDetails = "{\n" +
+                                   "  \"user\": \"admin\",\n" +
+                                   "  \"reason\": \"SLA not met\"\n" +
+                                   "}";
+        adjustmentInvoiceItem.setItemDetails(itemDetails);
+        killBillClient.adjustInvoiceItem(adjustmentInvoiceItem, requestOptions);
 
         // Verify the new invoice balance is zero
         final Invoice adjustedInvoice = killBillClient.getInvoice(invoice.getInvoiceId(), true, false, AuditLevel.FULL, requestOptions);
         assertEquals(adjustedInvoice.getAmount().compareTo(BigDecimal.ZERO), 0);
 
+        final InvoiceItem createdAdjustment = Iterables.find(adjustedInvoice.getItems(), new Predicate<InvoiceItem>() {
+            @Override
+            public boolean apply(final InvoiceItem input) {
+                return InvoiceItemType.ITEM_ADJ.toString().equals(input.getItemType());
+            }
+        });
+        assertEquals(createdAdjustment.getItemDetails(), itemDetails);
+
         // Verify invoice audit logs
         Assert.assertEquals(adjustedInvoice.getAuditLogs().size(), 1);
         final AuditLog invoiceAuditLogJson = adjustedInvoice.getAuditLogs().get(0);