Invoice

An invoice is a bill provided to a customer for charges that are payable on the customer's account. A single invoice consolidates charges for all subscriptions held by that customer for a specified time period. Invoices may be set to be paid automatically, or may be paid manually by the customer.

An invoice contains a list of InvoiceItems. The system will always invoice at the Account level, and will therefore create as many items on a given invoice as there are things to invoice. Given an active Subscription, one could see multiple items for that subscription on a single invoice including recurring items, usage items, fixed price items, etc. There can also be items for different subscriptions on the same invoice, as well as items that are unrelated to subscriptions such as adjustments and taxes.

An invoice can be generated manually if there are any outstanding charges. In addition, charges can be explicitly added that will also result in an invoice being generated. Invoices can also be automatically generated by the system when there are existing active subscriptions for the Account. In the latter case, the targetDate will determine up to which point to invoice, and the billing mode (IN_ADVANCE or IN_ARREAR) will determine which period to charge for.

An invoice can have one of the following status values: DRAFT, COMMITTED, or VOID.

Invoice Resource

An Invoice resource represents an invoice associated with a specific account. The attributes contained in this resource are the following:

Name Type Generated by Description
invoiceId string system UUID for the invoice
accountId string system UUID for the account
amount number user or system Sum of all item amounts
currency string user or system Currency associated with the account
status string system Status of the invoice: DRAFT, COMMITTED or VOID
creditAdj number system Invoice credit (amount that we owe to the customer). It is calculated as the sum of CBA_ADJ invoice items
refundAdj number system Refund amount associated with an invoice. It is calculated as the sum of all invoice payment amounts of type REFUND and CHARGED_BACK.
invoiceDate date system Date when this invoice was generated
targetDate date user or system Date up to which the account has been invoiced
invoiceNumber number system Invoice number
balance number system Invoice balance (amount that a customer owes as part of an invoice). At a high level, it is calculated as the sum of all item amounts minus the payment amount. See Invoice Balance for further details.
bundleKeys list system List of bundles invoiced. Deprecated.
credits list system List of credits associated with this invoice. Deprecated.
items list system List of invoice items on this invoice
isParentInvoice boolean system If true, this invoice is the parent in the hierarchical model
parentInvoiceId string system In the hierarchical model, UUID of the parent invoice
parentAccountId string system In the hierarchical model, UUID of the parent account

InvoiceItem Resource

An InvoiceItem resource represents a single item charged on an invoice. The attributes contained in this resource are the following:

Name Type Generated by Description
invoiceItemId string system UUID for the invoice item
invoiceId string system UUID for the invoice
linkedInvoiceItemId string system UUID for the linked item, if any (see below)
accountId string system UUID for the account
childAccountId string system In the hierarchical model, the UUID of the child account
bundleId string system UUID for the bundle
subscriptionId string system UUID for the subscription (present only if invoice item corresponds to a subscription)
planName string system Name of the Plan for this subscription if any
phaseName string system Name of the PlanPhase for this subscription if any
usageName string system Name of the Usage section for this subscription if any
prettyPlanName string system Pretty name of the Plan for this subscription if any
prettyPhaseName string system Pretty name of the PlanPhase for this subscription if any
prettyUsageName string system Pretty name of the Usage section for this subscription if any
itemType string system Item type (see below)
description string user or system Optional description of the item
startDate date user or system Start date of the period invoiced
endDate date user or system End date of the period invoiced
amount number user or system Amount being invoiced
quantity number user or system Rate associated with the Plan
currency string user or system Currency associated with the account
itemDetails string user or system In usage mode, details about what was invoiced.
childItems list user or system In the hierarchical model, the items for the children.

linkedInvoiceItemId: This ID is used to link to another item. For example, an item representing an adjustment would link to the item being adjusted.

itemType: The following invoice item types are currently supported:

Refer to the Subscription Billing document for further details.

InvoiceDryRun Resource

An InvoiceDryRun object represents an invoice preview generated to determine what would be in the invoice scheduled on a certain date, or if certain changes are made. A dry run has no actual effect on the system. The attributes contained in this resource are the following:

Name Type Generated by Description
dryRunType string user Category for this dry run (see notes below)
dryRunAction string user Action on which the dry run should be based, if any (see notes below)
phaseType string user Type of the plan phase (see notes below)
productName string user Name of the product subscribed
productCategory string user Product category (see notes below)
billingPeriod string user Billing period (see notes below)
priceListName string user Name of the applicable price list
subscriptiontId string system UUID for a subscription. If specified, only this subscription is used for the dry run
bundleId string system UUID for a bundle. If specified, only this subscription is used for the dry run
effectiveDate date user The date the change takes effect
billingPolicy string user The billing policy (see notes below)
priceOverrides list user list of prices if this subscription has price overrides
planName string user Name of the plan subscribed

dryRunType: possible values are:

dryRunAction: possible values are: START_BILLING, CHANGE (of Plan), or STOP_BILLING

phaseType: possible values are: TRIAL, DISCOUNT, FIXEDTERM, or EVERGREEN

productCategory: possible values are BASE, ADD_ON, or STANDALONE

billingPeriod: possible values are DAILY, WEEKLY, BIWEEKLY, THIRTY_DAYS, SIXTY_DAYS, NINETY_DAYS, MONTHLY, BIMESTRIAL (bimonthly), QUARTERLY, TRIANNUAL, BIANNUAL, ANNUAL, BIENNIAL, or NO_BILLING_PERIOD

billingPolicy: possible values are START_OF_TERM, END_OF_TERM, or IMMEDIATE

Note that either the planName or a combination of productName, productCategory and billingPeriod needs to be specified for the START_BILLING, CHANGE dryRunAction.

Invoice

These endpoints provide basic operations on invoices.

Trigger an invoice run

Create an invoice run for the associated account. This may result in the creation of a new invoice if there is anything to invoice for, or nothing, if the account is up to date. If an invoice is created, all necessary attributes are determined by the system.

Also refer to our subscription manual for more examples

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices?accountId=29fd0a00-f08b-4886-849b-3f4b98c8df27"  
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("34a65013-2dd1-480e-b4b8-7999bb15ebce");
LocalDate targetDate = LocalDate.parse("2023-07-15");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;

Invoice invoice = invoiceApi.createFutureInvoice(accountId, targetDate, NULL_PLUGIN_PROPERTIES, requestOptions);
account_id = "3ee3aa82-1d45-4bbc-b36b-74d628e095d0"
target_date = nil

KillBillClient::Model::Invoice.trigger_invoice(account_id, 
                                               target_date, 
                                               user, 
                                               reason, 
                                               comment, 
                                               options)
invoiceApi = killbill.api.InvoiceApi()
target_date = datetime.date(2018, 6, 11)

invoiceApi.create_future_invoice(account_id, 
                                 created_by, 
                                 api_key, 
                                 api_secret, 
                                 target_date=target_date)

Query Parameters

Name Type Required Default Description
accountId string yes none account id
targetDate string no current date target date (date up to which the account should be invoiced)
pluginProperty array of strings no omit list of plugin properties, if any. Should be in the format key%3Dvalue

Response

If successful, returns a status code of 201 and an empty body. A location item is also returned in the header, giving the UUID of the generated invoice (if any). If there is nothing to invoice for, returns a 404 status code.

Create a migration invoice

This endpoint is used to insert existing invoices that are being migrated from either a third party system or an in-house billing system into Kill Bill.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/migration/{accountId}

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '[ { "invoiceItemId": "f38505c9-d673-4f0b-b7d4-9125cac2a567", "invoiceId": "f38505c9-d673-4f0b-b7d4-9125cac2a567", "linkedInvoiceItemId": "f38505c9-d673-4f0b-b7d4-9125cac2a567", "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "itemType": "EXTERNAL_CHARGE", "amount": 10, "rate": 0, "currency": "USD" }]' \
    "http://127.0.0.1:8080/1.0/kb/invoices/migration/2ad52f53-85ae-408a-9879-32a7e59dd03d"  
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("fe1a6f86-9ec5-4ac3-8d39-15f024cc8339");

BigDecimal chargeAmount = BigDecimal.TEN;
InvoiceItem externalCharge = new InvoiceItem();
externalCharge.setStartDate(new LocalDate());
externalCharge.setAccountId(accountId);
externalCharge.setAmount(chargeAmount);
externalCharge.setItemType(InvoiceItemType.EXTERNAL_CHARGE);
externalCharge.setCurrency(Currency.USD);
InvoiceItems inputInvoice = new InvoiceItems();
inputInvoice.add(externalCharge);

LocalDate targetDate = null;

Invoice migrationInvoice = invoiceApi.createMigrationInvoice(accountId, 
                                                             inputInvoice, 
                                                             targetDate,
                                                             requestOptions);
account_id = "be19b229-c076-47aa-aa4d-f53bec505dc7"
invoices = "external_invoice_list"
target_date = "2018-03-15"
KillBillClient::Model::Invoice.create_migration_invoice(account_id, 
                                                        invoices, 
                                                        target_date, 
                                                        user, 
                                                        reason, 
                                                        comment, 
                                                        options)
invoiceApi = killbill.api.InvoiceApi()
body = 'external_invoice_list'
target_date = datetime.date(2018, 6, 11)

invoiceApi.create_migration_invoice(account_id,
                                    [body],
                                    created_by,
                                    api_key,
                                    api_secret,
                                    target_date)

Request Body

An invoice resource object with all fields filled in representing the invoice to be migrated. At least the following fields need to be specified: itemType=EXTERNAL_CHARGE, amount.

Query Parameters

Name Type Required Default Description
targetDate string no current date target date

Response

If successful, returns a status code of 201 and an empty body. A location item is also returned in the header, giving the UUID of the generated invoice (if any).

Create external charge(s)

Create a charge for a given account. This will result in the creation of a new invoice.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/charges/{accountId}

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '[ { "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "description": "My charge", "amount": 50, "currency": "USD" }]'    \
    "http://127.0.0.1:8080/1.0/kb/invoices/charges/2ad52f53-85ae-408a-9879-32a7e59dd03d"
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("616789aa-4004-4681-b38c-b95871d534fc");

InvoiceItem externalCharge = new InvoiceItem();
externalCharge.setAccountId(accountId);
externalCharge.setAmount(BigDecimal.TEN);
externalCharge.setDescription("My charge");

InvoiceItems externalCharges = new InvoiceItems();
externalCharges.add(externalCharge);

LocalDate requestedDate = null;
Map<String, String> pluginProperty = null;
Boolean autoCommit = true;

List<InvoiceItem> createdExternalCharges = invoiceApi.createExternalCharges(accountId, 
                                                                            externalCharges, 
                                                                            requestedDate,
                                                                            autoCommit,
                                                                            pluginProperty, 
                                                                            requestOptions);
invoice_item             = KillBillClient::Model::InvoiceItem.new()
invoice_item.account_id  = "83e5e82d-fe72-4873-9b8b-946f4d250b0d"
invoice_item.amount      = '50.0'
invoice_item.currency    = 'USD'
invoice_item.description = 'My charge'

auto_commit = true

invoice_item.create(auto_commit, 
                    user, 
                    reason, 
                    comment, 
                    options)
invoiceApi = killbill.api.InvoiceApi()
body = InvoiceItem(account_id=account_id,
                   amount=50.0,
                   currency='USD',
                   description='My charge')

invoiceApi.create_external_charges(account_id,
                                   [body],
                                   created_by,
                                   api_key,
                                   api_secret,
                                   auto_commit=True)

Example Response:

[
  {
    "invoiceItemId": "3aaadeeb-5ffe-4226-a8b6-57723f1f8c12",
    "invoiceId": "c6fe2246-62e2-450d-b9fc-a27003771535",
    "linkedInvoiceItemId": null,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "childAccountId": null,
    "bundleId": null,
    "subscriptionId": null,
    "productName": null,
    "planName": null,
    "phaseName": null,
    "usageName": null,
    "prettyProductName": null,
    "prettyPlanName": null,
    "prettyPhaseName": null,
    "prettyUsageName": null,
    "itemType": "EXTERNAL_CHARGE",
    "description": "My charge",
    "startDate": "2018-07-20",
    "endDate": null,
    "amount": 50,
    "rate": null,
    "currency": "USD",
    "quantity": null,
    "itemDetails": null,
    "childItems": null,
    "auditLogs": []
  }
]

Request Body

An invoice item resource object with at least the amount attribute. If multiple invoice items are specified, a single invoice is created with all the invoice items.

Query Parameters

Name Type Required Default Description
requestedDate string no current date requested date
autoCommit boolean no false If true, the resulting invoice should be COMMITTED.

Response

If successful, returns a status code of 201 and an invoice item object.

Create tax items

Normally, tax items are added to an invoice by a plugin, which intercepts the invoice during its creation and adds the required tax items on the fly. However, sometimes you may want to add tax items directly. This API adds a tax item to an account, which will result in the creation of a new invoice. Also, it is worth noting, that the tax items are not linked to any existing invoiceItems. Consequently, specifying fields like linkedInvoiceItemId, subscriptionId while creating the tax item has no effect. These fields do not get saved on the database and will not be returned in subsequent GET requests.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/taxes/{accountId}

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '[ { "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "amount": 50, "currency": "USD" }]' \
    "http://127.0.0.1:8080/1.0/kb/invoices/taxes/2ad52f53-85ae-408a-9879-32a7e59dd03d"
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("eb36c64c-b575-4538-b26f-a89c473984da");
UID bundleId = UUID.fromString("28723cec-5510-49be-9e87-3a36d246f25e");

InvoiceItem taxItem = new InvoiceItem();
taxItem.setAccountId(accountId);
taxItem.setAmount(BigDecimal.TEN);
taxItem.setCurrency(Currency.USD);
taxItem.setBundleId(bundleId);
final InvoiceItems input = new InvoiceItems();
input.add(taxItem);

Boolean autoCommit = true;
LocalDate requestedDate = clock.getUTCToday();
Map<String, String> pluginProperty = null;

List<InvoiceItem> createdTaxItems = invoiceApi.createTaxItems(accountId, 
                                                                     input,
                                                                     autoCommit,
                                                                     requestedDate,
                                                                     pluginProperty,
                                                                     requestOptions);
invoice_item             = KillBillClient::Model::InvoiceItem.new()
invoice_item.account_id  = "29ef0d50-90d1-4163-bb46-ef1b82675ae6"
invoice_item.amount      = '50.0'
invoice_item.currency    = 'USD'
invoice_item.description = 'My charge'

auto_commit = true

invoice_item.create_tax_items(auto_commit, 
                              user, 
                              reason, 
                              comment, 
                              options)
invoiceApi = killbill.api.InvoiceApi()
body = InvoiceItem(account_id=account_id,
                   amount=50.0,
                   currency='USD',
                   description='My charge')

invoiceApi.create_tax_items(account_id,
                            [body],
                            created_by,
                            api_key,
                            api_secret,
                            auto_commit=True)

Example Response:

[
  {
    "invoiceItemId": "e91e8d48-d8de-4931-9758-6cfff86cb2f4",
    "invoiceId": "434dd357-099d-45f8-9b48-79dcd20c61ce",
    "linkedInvoiceItemId": null,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "childAccountId": null,
    "bundleId": null,
    "subscriptionId": null,
    "productName": null,
    "planName": null,
    "phaseName": null,
    "usageName": null,
    "prettyProductName": null,
    "prettyPlanName": null,
    "prettyPhaseName": null,
    "prettyUsageName": null,
    "itemType": "TAX",
    "description": "Tax",
    "startDate": "2018-07-20",
    "endDate": null,
    "amount": 50,
    "rate": null,
    "currency": "USD",
    "quantity": null,
    "itemDetails": null,
    "childItems": null,
    "auditLogs": []
  }
]

Request Body

An invoice item resource object with at least the amount attribute.

Query Parameters

Name Type Required Default Description
requestedDate string no current date requested date
autoCommit boolean no false If true, the resulting invoice should be COMMITTED.

Response

If successful, returns a status code of 201 and an invoice item object.

Retrieve an invoice by id

Retrieves an invoice based on the invoiceId.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/903e55d3-8072-47f1-80fc-32857dbdbcc5"    
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("922a83f4-ae08-4732-9dd9-35e13c332393");
Boolean withChildrenItems = false; //  Will include children items

Invoice invoiceWithItems = invoiceApi.getInvoice(invoiceId, 
                                                 withChildrenItems, 
                                                 AuditLevel.NONE, 
                                                 requestOptions);
invoice_id = "31db9f9a-91ff-49f4-b5a1-5e4fce59a197"
with_items = true
audit = 'NONE'

KillBillClient::Model::Invoice.find_by_id(invoice_id, 
                                          with_items, 
                                          audit, 
                                          options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '43da4e9c-03c6-4f15-8943-b9a3af3ecacb'

invoiceApi.get_invoice(invoice_id, api_key, api_secret)

Example Response:

{
  "amount": 0,
  "currency": "USD",
  "status": "DRAFT",
  "creditAdj": 50,
  "refundAdj": 0,
  "invoiceId": "903e55d3-8072-47f1-80fc-32857dbdbcc5",
  "invoiceDate": "2018-07-20",
  "targetDate": "2018-07-20",
  "invoiceNumber": "310",
  "balance": 0,
  "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
  "bundleKeys": null,
  "credits": null,
  "items": [],
  "isParentInvoice": false,
  "parentInvoiceId": null,
  "parentAccountId": null,
  "auditLogs": []
}

Query Parameters

Name Type Required Default Description
withChildrenItems boolean no false If true, include children items
audit string no "NONE" Level of audit information to return

Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".

Returns

If successful, returns a status code of 200 and an invoice resource object.

Retrieve an invoice by number

Retrieves an invoice based on the invoiceNumber.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/byNumber/{invoiceNumber

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/byNumber/310"
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

Integer invoiceNumber = 1;
Boolean withChildrenItems = false; //  Will include children items

Invoice invoiceByNumber = invoiceApi.getInvoiceByNumber(invoiceNumber, 
                                                        withChildrenItems, 
                                                        AuditLevel.FULL, 
                                                        requestOptions);
invoice_number = "1913"
with_items = true
audit = 'NONE'

KillBillClient::Model::Invoice.find_by_number(invoice_number, 
                                              with_items, 
                                              audit, 
                                              options)
invoiceApi = killbill.api.InvoiceApi()
invoice_number = '972'

invoiceApi.get_invoice_by_number(invoice_number, api_key, api_secret)

Example Response:

{
  "amount": 0,
  "currency": "USD",
  "status": "DRAFT",
  "creditAdj": 50,
  "refundAdj": 0,
  "invoiceId": "903e55d3-8072-47f1-80fc-32857dbdbcc5",
  "invoiceDate": "2018-07-20",
  "targetDate": "2018-07-20",
  "invoiceNumber": "310",
  "balance": 0,
  "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
  "bundleKeys": null,
  "credits": null,
  "items": [],
  "isParentInvoice": false,
  "parentInvoiceId": null,
  "parentAccountId": null,
  "auditLogs": []
}

Query Parameters

Name Type Required Default Description
withChildrenItems boolean no false If true, include children items
audit string no "NONE" Level of audit information to return

Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".

Returns

If successful, returns a status code of 200 and an invoice resource object.

Retrieve an invoice by invoice item id

Retrieves an invoice based on the invoiceItemId for an invoice item.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/byItemId/{itemId}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/byItemId/3f0aa8f7-ca75-40cc-8c78-15a15cdbb977"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceItemId = UUID.fromString("111732ad-196d-423f-8ccd-de44109dc944")
Boolean withChildrenItems = false; //  Will include children items

Invoice invoiceByItemId = invoiceApi.getInvoiceByItemId(invoiceItemId, 
                                                        withChildrenItems, 
                                                        AuditLevel.NONE, 
                                                        requestOptions);
invoice_item_id = "f641ce8a-a874-4e98-ada5-2bd8fdb74945"
with_items = true
with_children_items = false
audit = 'NONE'

KillBillClient::Model::Invoice.find_by_invoice_item_id(invoice_item_id, 
                                                       with_items,
                                                       with_children_items, 
                                                       audit, 
                                                       options)
invoiceApi = killbill.api.InvoiceApi()
invoice_item_id = '8fae6721-3ebc-4103-85f5-aa13dde0e4f5'

invoiceApi.get_invoice_by_item_id(invoice_item_id, 
                                  api_key, 
                                  api_secret, 
                                  with_items=True)

Example Response:

{
  "amount": 0,
  "currency": "USD",
  "status": "DRAFT",
  "creditAdj": 50,
  "refundAdj": 0,
  "invoiceId": "18e9b3d9-9083-4725-9e8a-27d3a57c2e88",
  "invoiceDate": "2018-07-20",
  "targetDate": "2018-07-20",
  "invoiceNumber": "311",
  "balance": 0,
  "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
  "bundleKeys": null,
  "credits": null,
  "items": [],
  "isParentInvoice": false,
  "parentInvoiceId": null,
  "parentAccountId": null,
  "auditLogs": []
}

Query Parameters

Name Type Required Default Description
withChildrenItems boolean no false If true, include children items
audit string no "NONE" Level of audit information to return

Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".

Response

If successful, returns a status code of 200 and an invoice resource object.

Render an invoice as HTML

This API formats an invoice as an HTML page, that can be displayed or printed for a customer.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/html

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: text/html" \
    "http://127.0.0.1:8080/1.0/kb/invoices/903e55d3-8072-47f1-80fc-32857dbdbcc5/html"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");

String htmlInvoice = invoiceApi.getInvoiceAsHTML(invoiceId, requestOptions);
invoice_id = invoice.invoice_id
KillBillClient::Model::Invoice.as_html(invoice_id, @options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '2c98cfa2-7929-4cc2-9397-1624fb72c6d5'

invoiceApi.get_invoice_as_html(invoice_id, api_key, api_secret)

Example Response:

<html>
    <head>
        <style type="text/css">
            th {align=left; width=225px; border-bottom: solid 2px black;}
        </style>
    </head>
    <body>
        <h1>invoiceTitle</h1>
        <table>
            <tr>
                <td rowspan=3 width=350px>Insert image here</td>
                <td width=100px/>
                <td width=225px/>
                <td width=225px/>
            </tr>
            <tr>
                <td />
                <td align=right>invoiceDate</td>
                <td>Jul 20, 2018</td>
            </tr>
            <tr>
                <td />
                <td align=right>invoiceNumber</td>
                <td>310</td>
            </tr>
            <tr>
                <td>companyName</td>
                <td></td>
                <td align=right>accountOwnerName</td>
                <td>Another Name</td>
            </tr>
            <tr>
                <td>companyAddress</td>
                <td />
                <td />
                <td>john@127.0.0.1:8080</td>
            </tr>
            <tr>
                <td>companyCityProvincePostalCode</td>
                <td />
                <td />
                <td></td>
            </tr>
            <tr>
                <td>companyCountry</td>
                <td />
                <td />
                <td />
            </tr>
            <tr>
                <td><companyUrl</td>
                <td />
                <td />
                <td />
            </tr>
        </table>
        <br />
        <br />
        <br />
        <table>
            <tr>
                <th>invoiceItemBundleName</td>
                <th>invoiceItemDescription</td>
                <th>invoiceItemServicePeriod</td>
                <th>invoiceItemAmount</td>
            </tr>

            <tr>
                <td>Adjustment (account credit)</td>
                <td></td>
                <td>Jul 20, 2018 - Jul 20, 2018</td>
                <td>USD 50.00</td>
            </tr>

            <tr>
                <td>example</td>
                <td></td>
                <td>Jul 20, 2018 - Jul 20, 2018</td>
                <td>USD -50.00</td>
            </tr>

            <tr>
                <td colspan=4 />
            </tr>
            <tr>
                <td colspan=2 />
                <td align=right><strong>invoiceAmount</strong></td>
                <td align=right><strong>0.00</strong></td>
            </tr>
            <tr>
                <td colspan=2 />
                <td align=right><strong>invoiceAmountPaid</strong></td>
                <td align=right><strong>0.00</strong></td>
            </tr>
            <tr>
                <td colspan=2 />
                <td align=right><strong>invoiceBalance</strong></td>
                <td align=right><strong>0</strong></td>
            </tr>
        </table>
    </body>
</html>

Query Parameters

None.

Response

If successful, returns a status code of 200 and an invoice rendered as HTML.

Change invoice status from DRAFT to COMMITTED

Commit a DRAFT invoice by changing its staus to COMMITTED. The invoice becomes immutable and its balance is now included in account totals.

HTTP Request

PUT http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/commitInvoice

Example Request:

curl -v \
    -X PUT \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices/903e55d3-8072-47f1-80fc-32857dbdbcc5/commitInvoice"  
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("ca09d09a-59b2-4ada-8c15-597c9efde46c");

invoiceApi.commitInvoice(invoiceId, requestOptions);
invoice = KillBillClient::Model::Invoice.new
invoice.invoice_id = "2c98cfa2-7929-4cc2-9397-1624fb72c6d5"

invoice.commit(user, 
               reason, 
               comment, 
               options)
invoiceApi = killbill.api.InvoiceApi()

invoiceApi.commit_invoice(invoice_id, 
                          created_by, 
                          api_key, 
                          api_secret)

Query Parameters

None.

Response

If successful, returns a status code of 204 and an empty body.

Void an invoice

Change the status of an invoice to VOID. A void invoice is ignored by the rest of the system. There are some restrictions for this operation:

HTTP Request

PUT http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/voidInvoice

Example Request:

curl -v \
    -X PUT \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices/18e9b3d9-9083-4725-9e8a-27d3a57c2e88/voidInvoice"    
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("e659f0f3-745c-46d5-953c-28fe9282fc7d");

invoiceApi.voidInvoice(invoiceId, requestOptions);
TODO
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '28af3cb9-275b-4ac4-a55d-a0536e479069'

invoiceApi.void_invoice(invoice_id, 
                        created_by, 
                        api_key, 
                        api_secret)

Query Parameters

None.

Response

If successful, returns a status code of 204 and an empty body.

Adjust an invoice item

Adjust the amount for an invoice item

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "invoiceItemId": "903e55d3-8072-47f1-80fc-32857dbdbcc5", "invoiceId": "903e55d3-8072-47f1-80fc-32857dbdbcc5", "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "description": "Free adjustment: good customer", "amount": 50, "currency": "USD"}' \
    "http://127.0.0.1:8080/1.0/kb/invoices/903e55d3-8072-47f1-80fc-32857dbdbcc5"    
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("53805dbc-720a-4eaf-9072-ade723ee860f");
UUID invoiceId = UUID.fromString("4be08988-35a1-4fce-bebc-699af2a95b18");
UUID invoiceItemId = UUID.fromString("5f1e9142-b4de-4409-9366-9920cc1683e9");
BigDecimal adjustedAmount = BigDecimal.TEN;

InvoiceItem adjustmentInvoiceItem = new InvoiceItem();
adjustmentInvoiceItem.setAccountId(accountId);
adjustmentInvoiceItem.setInvoiceId(invoiceItemId);
adjustmentInvoiceItem.setInvoiceItemId(invoiceItemId);
adjustmentInvoiceItem.setAmount(adjustedAmount);
adjustmentInvoiceItem.setCurrency(Currency.USD);

LocalDate requestedDate = null;
Map<String, String> pluginProperty = null;

Invoice result = invoiceApi.adjustInvoiceItem(invoiceId, 
                                              adjustmentInvoiceItem, 
                                              requestedDate,
                                              pluginProperty,
                                              requestOptions);
invoice_item                 = KillBillClient::Model::InvoiceItem.new
invoice_item.account_id      = "3ee3aa82-1d45-4bbc-b36b-74d628e095d0"
invoice_item.invoice_id      = "2c98cfa2-7929-4cc2-9397-1624fb72c6d5"
invoice_item.invoice_item_id = "b311f709-ad51-4f67-8722-18ce04334c31"
invoice_item.amount          = 100.00
invoice_item.currency        = 'USD'
invoice_item.description     = 'Free adjustment: good customer'

invoice_item.update(user, 
                    reason, 
                    comment, 
                    options)
invoiceApi = killbill.api.InvoiceApi()
body = InvoiceItem(account_id='3ee3aa82-1d45-4bbc-b36b-74d628e095d0',
                   invoice_id='2c98cfa2-7929-4cc2-9397-1624fb72c6d5',
                   invoice_item_id='b311f709-ad51-4f67-8722-18ce04334c31',
                   amount=100,
                   currency='USD',
                   description='Free adjustment: good customer')

invoiceApi.adjust_invoice_item(invoice_id,
                               body,
                               created_by,
                               api_key,
                               api_secret)

Request Body

An invoice item resource object with at least invoiceItemId, invoiceId, and amount attributes.

Query Parameters

Name Type Required Default Description
requestedDate string no current date requested date

Returns

If successful, returns a status code of 201 and an empty body. In addition, a Location header containing the invoice id is returned.

Delete a CBA item

Delete a Credit Balance Adjust (CBA_ADJ) invoice item. There are some limitations and side effects with this api:

  1. Deleting a positive CBA_ADJ (credit generation), may lead the system to reclaim portion of the used credit, possibly leaving some invoices with a balance. Example:

Given an invoice, I1, where user added some credit ($12), we would see the following items: {CREDIT_ADJ: -12, CBA_ADJ: +12}. Given another invoice, I2, where the system invoiced for a recurring subscription, and where some of this credit was consumed, we would see the following items: {RECURRING: +10, CBA_ADJ: -10}. Deleting the CBA_ADJ from I1, would lead to the following resulting invoices: I1 {CREDIT_ADJ: 0, CBA_ADJ: 0} and I2 {RECURRING: +10, CBA_ADJ: 0}. The system zeroed-out the credit generation and the part that was used, and as a result I2 would be left with a balance of +10. Deleting the CBA_ADJ from I2 on the other hand would lead to the following invoice: I2 {RECURRING: +20, CBA_ADJ: 0} .

  1. System generated credit

In an in-advanced scenario where the system first invoiced for a recurring subscription ($20), and then repaired ($-8) for instance as a result of an early cancelation, we would have the following invoices: I1 {RECURRING: +20} and I2 {REPAIR_ADJ: -8, CBA_ADJ: +8}. Attempting to delete the CBA_ADJ on I2 would fail as the generation of credit was system generated, i.e it happened as a result of a subscription change.

HTTP Request

DELETE http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/{invoiceItemId}/cba

Example Request:

curl -v \
    -X DELETE \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices/404a98a8-4dd8-4737-a39f-be871e916a8c/a35fb7b5-aec8-489e-aadf-c86107aa1d92/cba?accountId=8785164f-b5d7-4da1-9495-33f5105e8d80"    
UUID invoiceId = UUID.fromString("c0c2d79d-8b2e-4830-a05b-b9a43b38482c");
UUID invoiceItemId = UUID.fromString("29a8933a-2e5c-409c-97be-7a5964dbf708");
UUID accountId = UUID.fromString("41e61312-cfb1-4300-afc7-64bc5cb29e85");
invoiceApi.deleteCBA(invoiceId, invoiceItemId, accountId, requestOptions);
invoice_item                 = KillBillClient::Model::InvoiceItem.new
invoice_item.account_id      = "3ee3aa82-1d45-4bbc-b36b-74d628e095d0"
invoice_item.invoice_id      = "2c98cfa2-7929-4cc2-9397-1624fb72c6d5"
invoice_item.invoice_item_id = "b311f709-ad51-4f67-8722-18ce04334c31"

invoice_item.delete(user, 
                    reason, 
                    comment, 
                    options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id='2c98cfa2-7929-4cc2-9397-1624fb72c6d5',
invoice_item_id='b311f709-ad51-4f67-8722-18ce04334c31'
account_id = '3ee3aa82-1d45-4bbc-b36b-74d628e095d0',

invoiceApi.delete_cba(invoice_id,
                      invoice_item_id,
                      account_id,
                      created_by,
                      api_key,
                      api_secret)

Query Parameters

Name Type Required Default Description
accountId string yes none account id

Response

If successful, returns a status code of 204 and an empty body.

Dry-run

In some situations, it is necessary to preview what a given customer will be invoiced for before making changes, or to verify what the system will generate at a future date. Kill Bill provides a dry-run invoice API to accomplish these goals. This API can be used to answer several distinct questions:

A dry run is based on a dry run resource object.

Generate a dry run invoice

This endpoint creates a dry-run invoice. Based on its parameters you can obtain answers to the different questions listed above.

Note: This endpoint is rather expensive, as it creates a full invoice run for the designated account, but no invoice will be created or persisted in the system.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/dryRun

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "dryRunType": "TARGET_DATE"}' \
    "http://localhost:8080/1.0/kb/invoices/dryRun?accountId=60a47168-7d36-4380-8ec7-e48cfe4e65d6&targetDate=2022-02-28"   

OR 

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "dryRunType": "UPCOMING_INVOICE"}' \
    "http://localhost:8080/1.0/kb/invoices/dryRun?accountId=2ad52f53-85ae-408a-9879-32a7e59dd03d"   

OR

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "dryRunType": "SUBSCRIPTION_ACTION","dryRunAction":"CHANGE","productName":"Standard", "productCategory":"BASE","billingPeriod":"MONTHLY","subscriptionId":"0b9efead-d5e4-40a9-8178-2286dee0fe48","bundleId":" 6ebcc573-c2c4-408a-b5c3-d6ae0dbae233"}' \
    "http://localhost:8080/1.0/kb/invoices/dryRun?accountId=60a47168-7d36-4380-8ec7-e48cfe4e65d6"  

OR

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "dryRunType": "SUBSCRIPTION_ACTION","dryRunAction":"STOP_BILLING","subscriptionId":"0b9efead-d5e4-40a9-8178-2286dee0fe48","bundleId":"    6ebcc573-c2c4-408a-b5c3-d6ae0dbae233","effectiveDate":"2022-02-10"}' \
    "http://localhost:8080/1.0/kb/invoices/dryRun?accountId=60a47168-7d36-4380-8ec7-e48cfe4e65d6"          

import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

DryRunType dryRunType = DryRunType.SUBSCRIPTION_ACTION;
SubscriptionEventType dryRunAction = SubscriptionEventType.START_BILLING;
PhaseType phaseType = null;
String productName = "Assault-Rifle";
ProductCategory productCategory = ProductCategory.BASE;
BillingPeriod billingPeriod = BillingPeriod.ANNUAL;
String priceListName = null;
UUID subscriptionId = null;
UUID bundleId = null;
LocalDate effectiveDate = null;
BillingActionPolicy billingPolicy = null;
List<PhasePrice> priceOverrides = null;

InvoiceDryRun dryRunArg = new InvoiceDryRun(dryRunType, 
                                            dryRunAction,
                                            phaseType, 
                                            productName, 
                                            productCategory, 
                                            billingPeriod, 
                                            priceListName, 
                                            subscriptionId, 
                                            bundleId, 
                                            effectiveDate, 
                                            billingPolicy,
                                            priceOverrides);


UUID accountId = UUID.fromString("fe1a6f86-9ec5-4ac3-8d39-15f024cc8339");
LocalDate targetDate = new LocalDate().plusDays(1);

Invoice dryRunInvoice = invoiceApi.generateDryRunInvoice(dryRunArg, 
                                                         accountId, 
                                                         targetDate, 
                                                         requestOptions);
#
# This case is when you create a dry-run invoice with UPCOMING_INVOICE, 
# to see what is the next invoice that the system will generate for this account 
# 
account_id = "5527abbc-d83d-447f-bf3d-ab9542ea631e"
target_date = nil
upcoming_invoice_target_date = true

KillBillClient::Model::Invoice.trigger_invoice_dry_run(account_id, 
                                                       target_date, 
                                                       upcoming_invoice_target_date, 
                                                       options)
#
# This case is when you create a dry-run invoice with UPCOMING_INVOICE, 
# to see what is the next invoice that the system will generate for this account 
# 
invoiceApi = killbill.api.InvoiceApi()
body = InvoiceDryRun(dry_run_type='UPCOMING_INVOICE')
account_id = '00e87495-92dc-4640-8490-e2c794748151'

invoiceApi.generate_dry_run_invoice(body,
                                    account_id,
                                    created_by,
                                    api_key,
                                    api_secret)

Example Response:

{
  "amount": 60,
  "currency": "USD",
  "status": "COMMITTED",
  "creditAdj": 0,
  "refundAdj": 0,
  "invoiceId": "cf4d1d3b-81cf-4054-96d7-bbdada2b9bc2",
  "invoiceDate": "2022-01-31",
  "targetDate": "2022-02-28",
  "invoiceNumber": null,
  "balance": 60,
  "accountId": "60a47168-7d36-4380-8ec7-e48cfe4e65d6",
  "bundleKeys": null,
  "credits": null,
  "items": [
    {
      "invoiceItemId": "8c453b1b-ba2c-4c05-894f-e02eb2ee834e",
      "invoiceId": "cf4d1d3b-81cf-4054-96d7-bbdada2b9bc2",
      "linkedInvoiceItemId": null,
      "accountId": "60a47168-7d36-4380-8ec7-e48cfe4e65d6",
      "childAccountId": null,
      "bundleId": "6ebcc573-c2c4-408a-b5c3-d6ae0dbae233",
      "subscriptionId": "0b9efead-d5e4-40a9-8178-2286dee0fe48",
      "productName": "Standard",
      "planName": "standard-monthly",
      "phaseName": "standard-monthly-evergreen",
      "usageName": null,
      "prettyProductName": null,
      "prettyPlanName": null,
      "prettyPhaseName": null,
      "prettyUsageName": null,
      "itemType": "RECURRING",
      "description": "standard-monthly-evergreen",
      "startDate": "2022-02-28",
      "endDate": "2022-03-31",
      "amount": 30,
      "rate": 30,
      "currency": "USD",
      "quantity": null,
      "itemDetails": null,
      "catalogEffectiveDate": "2019-01-01T00:00:00.000Z",
      "childItems": null,
      "auditLogs": []
    },
    {
      "invoiceItemId": "c1e83a72-ef8e-42d4-93e1-b5f9390294b4",
      "invoiceId": "cf4d1d3b-81cf-4054-96d7-bbdada2b9bc2",
      "linkedInvoiceItemId": null,
      "accountId": "60a47168-7d36-4380-8ec7-e48cfe4e65d6",
      "childAccountId": null,
      "bundleId": "c22936f6-5105-45b6-b418-ebba142a17aa",
      "subscriptionId": "9cce25a5-6ef2-40fe-8718-ca22529fe9d8",
      "productName": "Standard",
      "planName": "standard-monthly",
      "phaseName": "standard-monthly-evergreen",
      "usageName": null,
      "prettyProductName": null,
      "prettyPlanName": null,
      "prettyPhaseName": null,
      "prettyUsageName": null,
      "itemType": "RECURRING",
      "description": "standard-monthly-evergreen",
      "startDate": "2022-02-28",
      "endDate": "2022-03-31",
      "amount": 30,
      "rate": 30,
      "currency": "USD",
      "quantity": null,
      "itemDetails": null,
      "catalogEffectiveDate": "2019-01-01T00:00:00.000Z",
      "childItems": null,
      "auditLogs": []
    }
  ],
  "trackingIds": [],
  "isParentInvoice": false,
  "parentInvoiceId": null,
  "parentAccountId": null,
  "auditLogs": []
}

Request Body

A dry run resource object. The dryRunType and sometimes dryRunAction must be specified. Other attributes depend on these:

dryRunType dryRunAction Other Required Attributes Other Optional Attributes Description
TARGET_DATE N/A none none Preview the invoice as of the target date specified as a query parameter
UPCOMING_INVOICE N/A none subscriptionId or bundleId (When specified, computes the upcoming invoice for the specified subscription/bundle. Note that if there are other subscriptions invoiced on the same day, these will also be included in the upcoming invoice) Preview the next scheduled invoice. targetDate query parameter does not need to be specified, it is ignored even if specified
SUBSCRIPTION_ACTION START_BILLING Either a combination of productName, productCategory, billingPeriod or planName. If the dry run is being generated for an ADDON product, then the bundleId also needs to be specified effectiveDate, priceListName, billingPolicy Preview the invoice that would be generated if the START_BILLING action is taken
SUBSCRIPTION_ACTION CHANGE subscriptionId, bundleId and either a combination of productName, productCategory, billingPeriod or planName effectiveDate, priceListName, billingPolicy Preview the invoice that would be generated if the CHANGE action is taken
SUBSCRIPTION_ACTION STOP_BILLING subscriptionId, bundleId, effectiveDate - Preview the invoice that would be generated if the STOP_BILLING action is taken

Query Parameters

Name Type Required Default Description
accountId string yes none Account id
targetDate string No current date Target date is the invoicing target date

Note that for SUBSCRIPTION_ACTION, there are 2 dates to take into account:

Response

If successful, returns a status code of 200 and an invoice resource object.

Invoice Groups

An invoice group is a group of invoices. An invoice group plugin can be used to split an invoice into multiple invoices. Such split invoices belong to a single invoice group.

Note that Kill Bill does not provide any reference implementation for an invoice group plugin. So anyone wishing to use this feature would need to create an invoice plugin and implement the InvoicePluginApi#getInvoiceGrouping method. We provide a demo plugin that demonstrates how an invoice group plugin can be implemented. When such a plugin is configured, an invoice group run would result in the generation of multiple invoices.

Trigger an invoice group run

Triggers an invoice group run for the associated account. This would result in the creation of split invoices only if an invoice group plugin is configured. Otherwise, this endpoint behaves the same way as the Trigger an invoice run endpoint.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/group

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices/group?accountId=46897a8b-4ae8-45e2-b934-c4d00dba40a6" 
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("34a65013-2dd1-480e-b4b8-7999bb15ebce");
LocalDate targetDate = LocalDate.parse("2023-06-15");
Map<String, String> NULL_PLUGIN_PROPERTIES = null;

Invoices invoices = invoiceApi.createFutureInvoiceGroup(accountId, targetDate, NULL_PLUGIN_PROPERTIES, requestOptions);
TODO
TODO

Query Parameters

Name Type Required Default Description
accountId string yes none account id
targetDate string no current date target date (date up to which the account should be invoiced)
pluginProperty array of strings no omit list of plugin properties, if any. Should be in the format key%3Dvalue

Response

If successful, returns a status code of 201 and an empty body. A location header containing the UUID of the generated group (if any) is also included in the response. If there is nothing to invoice for, returns a 404 status code.

Retrieve an invoice group

Retrieves the invoices associated with the specified groupId.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{groupId}/group

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/e7fc3529-92e1-4987-b5f1-08e558a36698/group?accountId=40630170-e390-4cc7-9381-3788a894ba04" 
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID accountId = UUID.fromString("62dfaf14-34c6-4756-8411-89c93b1cfba3");
UUID groupId = UUID.fromString("f5ecf703-10b9-4019-8044-8db1163bef56");

Invoices invoices = invoiceApi.getInvoicesGroup(groupId, accountId, requestOptions);
TODO
TODO

Example Response:

[
  {
    "amount": 30,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "f5ecf703-10b9-4019-8044-8db1163bef56",
    "invoiceDate": "2023-02-16",
    "targetDate": "2023-08-16",
    "invoiceNumber": "428",
    "balance": 30,
    "accountId": "62dfaf14-34c6-4756-8411-89c93b1cfba3",
    "bundleKeys": null,
    "credits": null,
    "items": [
      {
        "invoiceItemId": "faf4f9a3-943b-42c4-9705-1365cfd91cc7",
        "invoiceId": "f5ecf703-10b9-4019-8044-8db1163bef56",
        "linkedInvoiceItemId": null,
        "accountId": "62dfaf14-34c6-4756-8411-89c93b1cfba3",
        "childAccountId": null,
        "bundleId": "30a3a9bf-3fc7-4334-ac2e-064cdd99c9dc",
        "subscriptionId": "5c463a1a-e884-4177-aa2c-cb09aa45e39b",
        "productName": "Standard",
        "planName": "standard-monthly",
        "phaseName": "standard-monthly-evergreen",
        "usageName": null,
        "prettyProductName": "Standard",
        "prettyPlanName": "standard-monthly",
        "prettyPhaseName": "standard-monthly-evergreen",
        "prettyUsageName": null,
        "itemType": "RECURRING",
        "description": "standard-monthly-evergreen",
        "startDate": "2023-08-16",
        "endDate": "2023-09-16",
        "amount": 30,
        "rate": 30,
        "currency": "USD",
        "quantity": null,
        "itemDetails": null,
        "catalogEffectiveDate": "2020-01-01T00:00:00.000Z",
        "childItems": null,
        "auditLogs": []
      }
    ],
    "trackingIds": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 30,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "b2f575d9-9bb8-4b5a-8595-da001381fd13",
    "invoiceDate": "2023-02-16",
    "targetDate": "2023-08-16",
    "invoiceNumber": "429",
    "balance": 30,
    "accountId": "62dfaf14-34c6-4756-8411-89c93b1cfba3",
    "bundleKeys": null,
    "credits": null,
    "items": [
      {
        "invoiceItemId": "42376d22-4b19-4a79-816b-b4896f9e8f48",
        "invoiceId": "b2f575d9-9bb8-4b5a-8595-da001381fd13",
        "linkedInvoiceItemId": null,
        "accountId": "62dfaf14-34c6-4756-8411-89c93b1cfba3",
        "childAccountId": null,
        "bundleId": "c176641f-2b6e-4bcf-8264-bfa120bcb337",
        "subscriptionId": "d424e7d9-e81a-45c7-9e84-77316bfe0c80",
        "productName": "Standard",
        "planName": "standard-monthly",
        "phaseName": "standard-monthly-evergreen",
        "usageName": null,
        "prettyProductName": "Standard",
        "prettyPlanName": "standard-monthly",
        "prettyPhaseName": "standard-monthly-evergreen",
        "prettyUsageName": null,
        "itemType": "RECURRING",
        "description": "standard-monthly-evergreen",
        "startDate": "2023-08-16",
        "endDate": "2023-09-16",
        "amount": 30,
        "rate": 30,
        "currency": "USD",
        "quantity": null,
        "itemDetails": null,
        "catalogEffectiveDate": "2020-01-01T00:00:00.000Z",
        "childItems": null,
        "auditLogs": []
      }
    ],
    "trackingIds": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  }
]

Query Parameters

Name Type Required Default Description
accountId string yes none accountId
withChildrenItems boolean no false If true, include children items
audit string no "NONE" Level of audit information to return

Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".

Returns If successful, returns a status code of 200 and a list of invoice objects for this group.

Payments

These endpoints relate to payments on an invoice. More information can be found at Invoice Payments.

Trigger a payment for an invoice

This API causes the system to generate a payment for an invoice.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/payments

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '{ "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d", "purchasedAmount": 50, "targetInvoiceId": "903e55d3-8072-47f1-80fc-32857dbdbcc5"}' \
    "http://localhost:8080/1.0/kb/invoices/903e55d3-8072-47f1-80fc-32857dbdbcc5/payments?externalPayment=false" 
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("4defec0a-3ecb-4d6f-9b97-c3842734d95f");
UUID accountId = UUID.fromString("14eadca7-dc35-4bbf-bb2b-fabad9bfebcf");

InvoicePayment invoicePayment = new InvoicePayment();
invoicePayment.setPurchasedAmount(BigDecimal.TEN);
invoicePayment.setAccountId(accountId);
invoicePayment.setTargetInvoiceId(invoiceId);

Boolean externalPayment = true; // Will use a external payment method
List<String> controlPluginNames = null;
Map<String, String> pluginProperty = null;
InvoicePayment result = invoiceApi.createInstantPayment(invoiceId, 
                                                        invoicePayment, 
                                                        externalPayment, 
                                                        controlPluginNames, 
                                                        pluginProperty, 
                                                        requestOptions);
payment                  = KillBillClient::Model::InvoicePayment.new
payment.account_id       = "3ee3aa82-1d45-4bbc-b36b-74d628e095d0"
payment.purchased_amount = '50.0'

external_payment = true

payment.create(external_payment, 
               user, 
               reason, 
               comment, 
               options)
invoiceApi = killbill.api.InvoiceApi()
body = InvoicePayment(account_id=account_id,
                      purchased_amount=50.0,
                      target_invoice_id=invoice_id)

invoiceApi.create_instant_payment(invoice_id,
                                  body,
                                  created_by,
                                  api_key,
                                  api_secret,
                                  external_payment=True)

Request Body

An invoicePayment resource object, with at least the following attributes: accountId, and purchasedAmount.

Query Parameters

Name Type Required Default Description
externalPayment boolean no false If true, the payment method should be defaulted to the (system provided) external payment method.

Response

If successful, returns a status code of 201 and an empty body.

Retrieve payments associated with an invoice

Retrieves a list of invoicePayment objects for payments associated with the invoice

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/payments

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/903e55d3-8072-47f1-80fc-32857dbdbcc5/payments"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("ca09d09a-59b2-4ada-8c15-597c9efde46c");
Boolean withPluginInfo = false; // Will not reflect plugin info
Boolean withAttempts = false; // Will not reflect payment attempts

InvoicePayments invoicePayments = invoiceApi.getPaymentsForInvoice(invoiceId,
                                                                   withPluginInfo,
                                                                   withAttempts,
                                                                   AuditLevel.NONE,
                                                                   inputOptions);
TODO
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '8291871e-b16e-45e6-a971-577d44727327'

invoiceApi.get_payments_for_invoice(invoice_id, api_key, api_secret)

Example Response:

{
  "targetInvoiceId": "903e55d3-8072-47f1-80fc-32857dbdbcc5",
  "accountId": "8b66b9f9-bfb4-463a-86c7-e267128a294a",
  "paymentId": "cc7fcd4d-e701-4679-9741-41289103db83",
  "paymentNumber": "19",
  "paymentExternalKey": "cc7fcd4d-e701-4679-9741-41289103db83",
  "authAmount": 0,
  "capturedAmount": 0,
  "purchasedAmount": 500,
  "refundedAmount": 0,
  "creditedAmount": 0,
  "currency": "USD",
  "paymentMethodId": "39f3461c-5357-42f7-a8a9-ec79502fdb6b",
  "transactions": [
    {
      "transactionId": "6787dc2d-4f5e-49b5-9764-0070fd1238c2",
      "transactionExternalKey": "6787dc2d-4f5e-49b5-9764-0070fd1238c2",
      "paymentId": "cc7fcd4d-e701-4679-9741-41289103db83",
      "paymentExternalKey": "cc7fcd4d-e701-4679-9741-41289103db83",
      "transactionType": "PURCHASE",
      "amount": 500,
      "currency": "USD",
      "effectiveDate": "2018-07-19T20:48:34.000Z",
      "processedAmount": 500,
      "processedCurrency": "USD",
      "status": "SUCCESS",
      "gatewayErrorCode": null,
      "gatewayErrorMsg": null,
      "firstPaymentReferenceId": null,
      "secondPaymentReferenceId": null,
      "properties": null,
      "auditLogs": []
    }
  ],
  "paymentAttempts": null,
  "auditLogs": []
}

Query Parameters

Name Type Required Default Description
withPluginInfo boolean no false If true, plugin info is included
withAttempts boolean no false If true, payment attempts are included
audit string no "NONE" Level of audit information to return

Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".

Response

If successful, returns a status code of 200 and a List of InvoicePayment resource objects.

Custom Fields

Custom fields are {key, value} attributes that can be attached to any customer resource. In particular they can be added to invoices. For details on Custom Fields see Custom Field.

Add custom fields to an invoice

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/customFields

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '[ { "objectType": "INVOICE", "name": "Test Custom Field", "value": "demo_test_value" }]' \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/customFields"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");

final List<AuditLog> EMPTY_AUDIT_LOGS = Collections.emptyList();

CustomFields customFields = new CustomFields();
customFields.add(new CustomField(null, 
                                 invoiceId, 
                                 ObjectType.INVOICE, 
                                 "Test Custom Field", 
                                 "test_value", 
                                 EMPTY_AUDIT_LOGS));

invoiceApi.createInvoiceCustomFields(invoiceId, 
                                     customFields, 
                                     requestOptions);
custom_field = KillBillClient::Model::CustomFieldAttributes.new
custom_field.object_type = 'INVOICE'
custom_field.name = 'Test Custom Field'
custom_field.value = 'test_value'

invoice.add_custom_field(custom_field, 
                         user,
                         reason,
                         comment,
                         options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '4927c1a2-3959-4f71-98e7-ce3ba19c92ac'
body = CustomField(name='Test Custom Field', value='test_value')

invoiceApi.create_invoice_custom_fields(invoice_id,
                                        [body],
                                        created_by,
                                        api_key,
                                        api_secret)

Request Body

A list of Custom Field objects. Each object should specify at least the the name and value attribute. For example:

[ { "name": "CF1", "value": "123" } ]

Query Parameters

None.

Response

If successful, returns a 201 status code. In addition, a Location header is returned with the URL to retrieve the custom fields associated with the invoice.

Retrieve invoice custom fields

Retrieve the custom fields associated with an invoice

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/customFields

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/customFields"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");

List<CustomField> customFields = invoiceApi.getInvoiceCustomFields(invoiceId,
                                                                   AuditLevel.NONE,
                                                                   requestOptions);
audit = 'NONE'

invoice.custom_fields(audit, options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '4927c1a2-3959-4f71-98e7-ce3ba19c92ac'

invoiceApi.get_invoice_custom_fields(invoice_id, api_key, api_secret)

Example Response:

[
  {
    "customFieldId": "349de10f-4bb1-4e1a-93f6-11b745200bf5",
    "objectId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
    "objectType": "INVOICE",
    "name": "Test Custom Field",
    "value": "demo_test_value",
    "auditLogs": []
  }
]

Query Parameters

Name Type Required Default Description
audit string no "NONE" Level of audit information to return:"NONE", "MINIMAL", or "FULL"

Response

If successful, returns a status code of 200 and a (possibly empty) list of custom field objects.

Modify custom fields for an invoice

Modify the custom fields associated with an invoice. Note that it is not possible to modify the name of a custom field, it is only possible to modify its value.

HTTP Request

PUT http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/customFields

Example Request:

curl -v \
    -X PUT \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '[ { "customFieldId": "349de10f-4bb1-4e1a-93f6-11b745200bf5", "objectId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d", "objectType": "INVOICE", "name": "Test Custom Field", "value": "test_modify_value", "auditLogs": [] }]' \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/customFields"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");

UUID customFieldsId = UUID.fromString("9913e0f6-b5ef-498b-ac47-60e1626eba8f");

CustomField customFieldModified = new CustomField();
customFieldModified.setCustomFieldId(customFieldsId);
customFieldModified.setValue("NewValue");

CustomFields customFields = new CustomFields();
customFields.add(customFieldModified);

invoiceApi.modifyInvoiceCustomFields(invoiceId, 
                                     customFields, 
                                     requestOptions);
custom_field.custom_field_id = '7fb3dde7-0911-4477-99e3-69d142509bb9'
custom_field.name = 'Test Modify'
custom_field.value = 'test_modify_value'

invoice.modify_custom_field(custom_field,                                                                                            
                            user, 
                            reason,
                            comment, 
                            options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '4927c1a2-3959-4f71-98e7-ce3ba19c92ac'
custom_field_id = '7fb3dde7-0911-4477-99e3-69d142509bb9'
body = CustomField(custom_field_id=custom_field_id, 
                   name='Test Custom Field', 
                   value='test_value')

invoiceApi.modify_invoice_custom_fields(invoice_id, 
                                        [body], 
                                        created_by, 
                                        api_key, 
                                        api_secret)

Requst Body

A list of Custom Field objects representing the fields to substitute for existing ones. Each object should specify at least the the customFieldId and value attribute. For example:

[ { "customFieldId": "6d4c073b-fd89-4e39-9802-eba65f42492f", "value": "123" } ]

Query Parameters

None.

Response

If successful, returns a status code of 204 and an empty body.

Remove custom fields from invoice

Remove a specified set of custom fields from the invoice

HTTP Request

DELETE http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/customFields

Example Request:

curl -v \
    -X DELETE \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/customFields?customField=349de10f-4bb1-4e1a-93f6-11b745200bf5"  
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("59860a0d-c032-456d-a35e-3a48fe8579e5");

UUID customFieldsId = UUID.fromString("9913e0f6-b5ef-498b-ac47-60e1626eba8f");
List<UUID> customFieldsList = List.of(customFieldsId);

invoiceApi.deleteInvoiceCustomFields(invoiceId, 
                                     customFieldsList, 
                                     requestOptions);
custom_field_id = custom_field.id

invoice.remove_custom_field(custom_field_id,                                                                                            
                            user, 
                            reason,
                            comment, 
                            options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '4927c1a2-3959-4f71-98e7-ce3ba19c92ac' 

invoiceApi.delete_invoice_custom_fields(invoice_id, 
                                        created_by, 
                                        api_key, 
                                        api_secret)

Query Parameters

Name Type Required Default Description
customField string yes none Custom field object ID that should be deleted. Multiple custom fields can be deleted by specifying a separate customField parameter corresponding to each field

Response

If successful, returns a status code of 204 and an empty body.

Tags

See Account Tags for an introduction.

The only system tag applicable for an Invoice is WRITTEN_OFF (00000000-0000-0000-0000-000000000004), which as it's name indicates, is used to write off an unpaid invoice, bringing its balance to $0.

Add tags to invoice

This API adds one or more tags to an invoice. The tag definitions must already exist.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/tags

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '[ "00000000-0000-0000-0000-000000000004"]' \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/tags"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("45d6f4c5-21be-49b1-99c5-7b0c3c985bf0");

UUID writtenOffId = UUID.fromString("00000000-0000-0000-0000-000000000004");

Tags result = invoiceApi.createInvoiceTags(invoiceId, 
                                           List.of(writtenOffId), 
                                           requestOptions);
tag_name = 'TEST'

invoice.add_tag(tag_name,
               user,
               reason,
               comment,
               options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '28af3cb9-275b-4ac4-a55d-a0536e479069'
tag = ["00000000-0000-0000-0000-000000000004"]

invoiceApi.create_invoice_tags(invoice_id, 
                               tag, 
                               created_by, 
                               api_key, 
                               api_secret)

Request Body

A JSON array containing one or more tag definition ids to be added as tags.

Query Parameters

None.

Returns

If successful, returns a 201 status code. In addition, a Location header is returned containing the URL to retrieve the tags associated with the invoice.

Retrieve invoice tags

Retrieve all tags attached to this invoice.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/tags

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/tags"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("e659f0f3-745c-46d5-953c-28fe9282fc7d");

Boolean includedDeleted = false; // Will not include deleted tags

List<Tag> tags = invoiceApi.getInvoiceTags(invoiceId, 
                                           includedDeleted, 
                                           AuditLevel.FULL, 
                                           requestOptions);
included_deleted = false
audit = 'NONE'

invoice.tags(included_deleted,
             audit,
             options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '3e94fccf-0f37-40aa-90a4-122a4f381ebc'

invoiceApi.get_invoice_tags(invoice_id, api_key, api_secret)

Example Response:

[
  {
    "tagId": "e054c84a-0518-4611-92a8-53e849f0affd",
    "objectType": "INVOICE",
    "objectId": "2cd2f4b5-a1c0-42a7-924f-64c7b791332d",
    "tagDefinitionId": "00000000-0000-0000-0000-000000000002",
    "tagDefinitionName": "AUTO_INVOICING_OFF",
    "auditLogs": []
  }
]

Query Parameters

Name Type Required Default Description
includedDeleted boolean no false If true, include deleted tags
audit string no "NONE" Level of audit information to return: "NONE", "MINIMAL", or "FULL"

Response

If successful, returns a status code of 200 and a list of tag objects.

Remove tags from invoice

Removes a list of tags attached to an invoice.

HTTP Request

DELETE http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/tags

Example Request:

curl -v \
    -X DELETE \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    "http://127.0.0.1:8080/1.0/kb/invoices/2cd2f4b5-a1c0-42a7-924f-64c7b791332d/tags?tagDef=00000000-0000-0000-0000-000000000002"   
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

UUID invoiceId = UUID.fromString("e659f0f3-745c-46d5-953c-28fe9282fc7d");
UUID autoPayOffId = UUID.fromString("00000000-0000-0000-0000-000000000001");

invoiceApi.deleteInvoiceTags(invoiceId, 
                             List.of(autoPayOffId), 
                             requestOptions);
tag_name = 'TEST'

invoice.remove_tag(tag_name,
                  user,
                  reason,
                  comment,
                  options)
invoiceApi = killbill.api.InvoiceApi()
invoice_id = '28af3cb9-275b-4ac4-a55d-a0536e479069'

invoiceApi.delete_invoice_tags(invoice_id, 
                               created_by, 
                               api_key, 
                               api_secret,
                               tag_def=tag)

Query Parameters

Name Type Required Default Description
tagDef array of string yes none A tag definition ID identifying the tag that should be removed. Multiple tags can be deleted by specifying a separate tagDef parameter corresponding to each tag.

Response

If successful, returns a status code of 204 and an empty body.

Translation

These endpoints support translation of invoices to a different language when required by the customer. Refer to our Internationalization manual for an introduction.

Translation replaces words and phrases in an invoice or catalog with the equivalent words or phrases in a different language. A tenant may upload translation tables for specific locales (e.g., locale fr_FR for French). When a customer accesses an invoice, that invoice will be generated from the system data, formatted using the appropriate template (see below), and translated according to the locale of the customer's account, if a translation table exists for that locale.

Upload the catalog translation for the tenant

Uploads a catalog translation table that will be saved under a specified locale. The translation table gives a translation for specific names in the current catalog.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/catalogTranslation/{locale}

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: text/plain" \
    -H "Accept: text/plain" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '"sports-monthly = Voiture Sport
silver-monthly = plan d'argent mensuel"' \
    "http://localhost:8080/1.0/kb/invoices/catalogTranslation/fr_FR"
String locale = "en_US";
String body = "gold-monthly=plan";
Boolean deleteIfExists = true;
invoiceApi.uploadCatalogTranslation(locale, body, deleteIfExists,requestOptions);
catalog_translation = 'sports-monthly = Voiture Sport'
locale = "fr_FR"
delete_if_exists = false

KillBillClient::Model::Invoice.upload_catalog_translation(catalog_translation, 
                                                          locale, 
                                                          delete_if_exists, 
                                                          user, 
                                                          reason, 
                                                          comment, 
                                                          options)
invoiceApi = killbill.api.InvoiceApi()
locale = 'fr_FR'
body = "sports-monthly = Voiture Sport"

invoiceApi.upload_catalog_translation(locale,
                                      body,
                                      created_by,
                                      api_key,
                                      api_secret)

Request Body

A table of translation items. For example:

gold-monthly = plan Or mensuel

silver-monthly = plan d'argent mensuel

Note that this table does not use a special syntax such as JSON. The equals sign is the only punctuation. There are no brackets or quotation marks.

The names translated would be primarily plan names, product names, and other items that may appear on an invoice.

Query Parameters

Name Type Required Default Description
deleteIfExists boolean no false if true, delete any existing translations

Response

If successful, returns a status code of 201 and a Location header which can be used to retrieve the catalog translation.

Retrieve the catalog translation for the tenant

Retrieves the catalog translation table that was previously uploaded for a particular locale, if any.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/catalogTranslation/{locale}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: text/plain" \
    "http://localhost:8080/1.0/kb/invoices/catalogTranslation/fr_FR"    
String locale = "en_US";
String translation = invoiceApi.getCatalogTranslation(locale, requestOptions);
locale = "fr_FR"
KillBillClient::Model::Invoice.get_catalog_translation(locale, 
                                                       options)
invoiceApi = killbill.api.InvoiceApi()
locale = 'fr_FR'

invoiceApi.get_catalog_translation(locale, api_key, api_secret)

Example Response:

{
    "sports-monthly = Voiture Sport"
}

Query Parameters

None.

Response

If successful, returns a status code of 200 and the translation table. A status code of 404 means no table was found for the specified locale.

Upload the invoice translation for the tenant

Uploads an invoice translation table that will be saved under a specified locale. The translation table gives a translation for specific names in the corresponding invoice template.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/translation/{locale}

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: text/plain" \
    -H "Accept: text/plain" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d "invoiceTitle=FACTURE
invoiceDate=Date:
invoiceNumber=Facture #" \
    "http://localhost:8080/1.0/kb/invoices/translation/fr_FR"
String locale = "en_US";
String body = "gold-monthly=plan";
Boolean deleteIfExists = true;
String translation = invoiceApi.uploadInvoiceTranslation(locale, body, deleteIfExists,requestOptions);
invoice_translation = get_resource_as_string("InvoiceTranslation_fr_FR.properties")
locale = "fr_FR"
delete_if_exists = false
KillBillClient::Model::Invoice.upload_invoice_translation(invoice_translation,
                                                          locale,
                                                          delete_if_exists, 
                                                          options)
invoiceApi = killbill.api.InvoiceApi()
locale = 'fr_FR'
body = "sports-monthly = Voiture Sport"

invoiceApi.upload_invoice_translation(locale,
                                      body,
                                      created_by,
                                      api_key,
                                      api_secret)

Request Body

A table of translation items. For example:

invoiceTitle=FACTURE

invoiceDate=Date:

invoiceNumber=Facture #

invoiceAmount=Montant à payer

Note that this table does not use a special syntax such as JSON. The equals sign is the only punctuation. There are no brackets or quotation marks.

Query Parameters

Name Type Required Default Description
deleteIfExists boolean no false delete translation if exists

Response

If successful, returns a status code of 201 and a Location header which can be used to retrieve the invoice translation.

Retrieve the invoice translation for the tenant

Retrieves the invoice translation table that was previously uploaded for a particular locale, if any.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/translation/{locale}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: text/plain" \
    "http://localhost:8080/1.0/kb/invoices/translation/fr_FR"   
String locale = "en_US";
String translation = invoiceApi.getInvoiceTranslation(locale, requestOptions);

locale = "fr_FR"
KillBillClient::Model::Invoice.get_invoice_translation(locale,
                                                       options)
invoiceApi = killbill.api.InvoiceApi()
locale = 'fr_FR'

invoiceApi.get_invoice_translation(locale, api_key, api_secret)

Example Response:


sports-monthly : Voiture Sport

Query Parameters

None.

Response

If successful, returns a status code of 200 and the translation table. A status code of 404 means no table was found for the specified locale.

Template

A template is a document based on mustache that provides the layout information for invoices. The template will be translated according to the translation table, if any, and the invoice data will be filled in by the Kill Bill system. Refer to our Internationalization manual for an introduction.

Upload the manualPay invoice template for the tenant

Uploads an invoice template based on the manual pay option, for accounts that have the MANUAL_PAY tag. These accounts manually pay their invoices (e.g. ACH). Typically, this template will contain extra information like the company bank account details, PO number, etc.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/manualPayTemplate

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: text/html" \
    -H "Accept: text/html" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d '"Some_HTML_String"' \
    "http://localhost:8080/1.0/kb/invoices/manualPayTemplate?deleteIfExists=false"  
String body = "Test HTML String";
Boolean deleteIfExists = true;
String template = invoiceApi.uploadInvoiceMPTemplate(body, deleteIfExists,requestOptions);

invoice_template = "Some_HTML_String"
is_manual_pay = true
delete_if_exists = false
KillBillClient::Model::Invoice.upload_invoice_template(invoice_template, 
                                                       is_manual_pay, 
                                                       delete_if_exists, 
                                                       user, 
                                                       reason, 
                                                       comment, 
                                                       options)
invoiceApi = killbill.api.InvoiceApi()
body = 'Some_HTML_String'

invoiceApi.upload_invoice_mp_template(body,
                                      created_by,
                                      api_key,
                                      api_secret)

Request Body

Contains a mustache manual pay template in HTML format.

Query Parameters

Name Type Required Default Description
deleteIfExists boolean no false if true, delete any existing manual pay template

Response

If successful, returns a status code of 200 and an empty body.

Retrieve the manualPay invoice template for the tenant

Retrieves the manual pay invoice template previously uploaded for this tenant, if any.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/manualPayTemplate

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: text/html" \
    "http://localhost:8080/1.0/kb/invoices/manualPayTemplate/"  
String locale = "fr_FR";
String template = invoiceApi.getInvoiceMPTemplate(locale, requestOptions);
is_manual_pay = true

KillBillClient::Model::Invoice.get_invoice_template(is_manual_pay,
                                                    options)
invoiceApi = killbill.api.InvoiceApi()

invoiceApi.get_invoice_mp_template(api_key, api_secret)

Query Parameters

None.

Response

If successful, returns a status code of 201 and the manual pay template.

Upload the invoice template for the tenant

Uploads an invoice template based on an automatic payment method. This is appropriate for accounts without the MANUAL_PAY tag.

HTTP Request

POST http://127.0.0.1:8080/1.0/kb/invoices/template

Example Request:

curl -v \
    -X POST \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Content-Type: text/html" \
    -H "Accept: text/html" \
    -H "X-Killbill-CreatedBy: demo" \
    -H "X-Killbill-Reason: demo" \
    -H "X-Killbill-Comment: demo" \
    -d "Some_HTML_String" \
    "http://localhost:8080/1.0/kb/invoices/template"    
String body = "Test HTML String";
Boolean deleteIfExists = true;
String template = invoiceApi.uploadInvoiceTemplate(body, deleteIfExists,requestOptions);
invoice_template = "Some_HTML_String"
is_manual_pay = false
delete_if_exists = false
KillBillClient::Model::Invoice.upload_invoice_template(invoice_template, 
                                                       is_manual_pay, 
                                                       delete_if_exists, 
                                                       user, 
                                                       reason, 
                                                       comment, 
                                                       options)
invoiceApi = killbill.api.InvoiceApi()
body = 'Some_HTML_String'

invoiceApi.upload_invoice_template(body,
                                   created_by,
                                   api_key,
                                   api_secret)

Request Body

Contains a mustache automatic pay template in HTML format.

Query Parameters

Name Type Required Default Description
deleteIfExists boolean no false if true, delete any existing manual pay template

Response

If successful, returns a status code of 200 and an empty body.

Retrieve the invoice template for the tenant

Retrieves the automatic pay invoice template previously uploaded for this tenant, if any.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/template

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: text/html" \
    "http://localhost:8080/1.0/kb/invoices/template"    
String template = invoiceApi.getInvoiceTemplate(requestOptions);
is_manual_pay = false

KillBillClient::Model::Invoice.get_invoice_template(is_manual_pay,
                                                    options)
invoiceApi = killbill.api.InvoiceApi()

invoiceApi.get_invoice_template(api_key, api_secret)

Query Parameters

None.

Response

If successful, returns a status code of 201 and the automatic pay template.

Example

The translation and templating process may seem a little complex. Here is a simple example for the use of a template with translation.

  1. To begin, a tenant should upload suitable manual pay and autopay templates reflecting her desired layout for the invoice. If this is not done a default template will be used.

  2. Suppose the tenant does business with German customers. She then should upload translation tables, perhaps provided by customers, designated for the German locale (de_DE). Tables are needed for both invoice items and catalog items. The invoice items to be translated are the names of the fields on the template, such as invoiceTitle, invoiceAmount, etc. The catalog items to be translated are the names for actual items such as product name and plan name. There can be translation tables for any number of distinct locales.

Catalog translation example (German):

gold plan = Goldplan sports car = Sportwagen

Invoice transaltion example (German):

invoiceTitle = Rechnung invoiceNumber = Rechnungsnumber invoiceBalance = Rechnungssaldo

  1. Each account has a designated locale. When an invoice is retrieved for an account, the appropriate translation tables, if any, are used to translate the invoice.

You can refer to the (Invoice Templates Tutorial)[https://docs.killbill.io/latest/invoice_templates.html] to know more about the how this works.

Audit Logs

Audit logs provide a record of events that occur involving various specific resources. For details on audit logs see Audit and History.

Retrieve invoice audit logs with history by invoice id

Retrieve a list of audit log records showing events that occurred involving changes to a specified invoice. History information is included with each record.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/{invoiceId}/auditLogsWithHistory

Example Request:

curl \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/d456a9b3-7e48-4f56-b387-1d65a492e75e/auditLogsWithHistory"
UUID invoiceId = UUID.fromString("8f6f3405-249f-4b66-a0c2-ee84e884e81d");
AuditLogs logs = invoiceApi.getInvoiceAuditLogsWithHistory(invoiceId, requestOptions);

Example Response:

[
  {
    "changeType": "INSERT",
    "changeDate": "2019-02-22T22:38:10.000Z",
    "objectType": "INVOICE",
    "objectId": "d456a9b3-7e48-4f56-b387-1d65a492e75e",
    "changedBy": "SubscriptionBaseTransition",
    "reasonCode": null,
    "comments": null,
    "userToken": "1f03e074-dea1-45c5-aee3-c9464886f476",
    "history": {
      "id": null,
      "createdDate": "2019-02-22T22:38:10.000Z",
      "updatedDate": null,
      "recordId": 2121,
      "accountRecordId": 10,
      "tenantRecordId": 1,
      "accountId": "7b3e14b1-6e76-46d3-bbfd-5a16e5b5eca2",
      "invoiceNumber": null,
      "invoiceDate": "2019-02-22",
      "targetDate": "2019-02-22",
      "currency": "USD",
      "migrated": false,
      "status": "COMMITTED",
      "invoiceItems": [],
      "invoicePayments": [],
      "processedCurrency": "USD",
      "parentInvoice": null,
      "isWrittenOff": false,
      "writtenOff": false,
      "tableName": "INVOICES",
      "historyTableName": "INVOICE_HISTORY"
    }
  }
]

Query Parameters

None.

Response

If successful, returns a status code of 200 and a list of audit logs with history.

Retrieve invoice item audit logs with history by invoice item id

Retrieve a list of audit log records showing events that occurred involving changes to a specified invoice item. History information is included with each record.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoiceItems/{invoiceItemId}/auditLogsWithHistory

Example Request:

curl \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoiceItems/b45ef2ac-e4b7-4e79-89d8-1c2e95838300/auditLogsWithHistory"

Example Response:

[
  {
    "changeType": "INSERT",
    "changeDate": "2019-02-22T22:38:10.000Z",
    "objectType": "INVOICE_ITEM",
    "objectId": "b45ef2ac-e4b7-4e79-89d8-1c2e95838300",
    "changedBy": "SubscriptionBaseTransition",
    "reasonCode": null,
    "comments": null,
    "userToken": "1f03e074-dea1-45c5-aee3-c9464886f476",
    "history": {
      "id": null,
      "createdDate": "2019-02-22T22:38:10.000Z",
      "updatedDate": null,
      "recordId": 2698,
      "accountRecordId": 10,
      "tenantRecordId": 1,
      "type": "RECURRING",
      "invoiceId": "d456a9b3-7e48-4f56-b387-1d65a492e75e",
      "accountId": "7b3e14b1-6e76-46d3-bbfd-5a16e5b5eca2",
      "childAccountId": null,
      "bundleId": "d1b329c7-7dcf-466c-aaca-47bff304dab0",
      "subscriptionId": "70b6856e-6938-495f-9ae9-0a8ec0571c37",
      "description": "foo-monthly-evergreen",
      "productName": "Foo",
      "planName": "foo-monthly",
      "phaseName": "foo-monthly-evergreen",
      "usageName": null,
      "startDate": "2019-02-22",
      "endDate": "2019-03-22",
      "amount": 10,
      "rate": 10,
      "currency": "USD",
      "linkedItemId": null,
      "quantity": null,
      "itemDetails": null,
      "tableName": "INVOICE_ITEMS",
      "historyTableName": "INVOICE_ITEM_HISTORY"
    }
  }
]

Query Parameters

None.

Response

If successful, returns a status code of 200 and a list of audit logs with history.

Retrieve invoice payment audit logs with history by invoice payment id

Retrieve a list of audit log records showing events that occurred involving changes to a specified invoice payment. History information is included with each record.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoicePayments/{invoicePaymentId}/auditLogsWithHistory

Example Request:

curl \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoicePayments/5eedf918-b418-4d14-8dba-51c977a3f700/auditLogsWithHistory"

Example Response:

[
  {
    "changeType": "INSERT",
    "changeDate": "2019-02-22T23:23:21.000Z",
    "objectType": "INVOICE_PAYMENT",
    "objectId": "5eedf918-b418-4d14-8dba-51c977a3f700",
    "changedBy": "admin",
    "reasonCode": null,
    "comments": null,
    "userToken": "39b3f8a2-d782-41cd-adcd-460b5f560192",
    "history": {
      "id": null,
      "createdDate": "2019-02-22T23:23:21.000Z",
      "updatedDate": null,
      "recordId": 219,
      "accountRecordId": 10,
      "tenantRecordId": 1,
      "type": "ATTEMPT",
      "invoiceId": "d456a9b3-7e48-4f56-b387-1d65a492e75e",
      "paymentId": null,
      "paymentDate": "2019-02-22T23:23:21.000Z",
      "amount": 10,
      "currency": "USD",
      "processedCurrency": "USD",
      "paymentCookieId": "4d83dd1b-b053-4a4d-99de-9a9e6e0405af",
      "linkedInvoicePaymentId": null,
      "success": false,
      "tableName": "INVOICE_PAYMENTS",
      "historyTableName": "INVOICE_PAYMENT_HISTORY"
    }
  },
  {
    "changeType": "UPDATE",
    "changeDate": "2019-02-22T23:23:21.000Z",
    "objectType": "INVOICE_PAYMENT",
    "objectId": "5eedf918-b418-4d14-8dba-51c977a3f700",
    "changedBy": "admin",
    "reasonCode": null,
    "comments": null,
    "userToken": "39b3f8a2-d782-41cd-adcd-460b5f560192",
    "history": {
      "id": null,
      "createdDate": "2019-02-22T23:23:21.000Z",
      "updatedDate": null,
      "recordId": 219,
      "accountRecordId": 10,
      "tenantRecordId": 1,
      "type": "ATTEMPT",
      "invoiceId": "d456a9b3-7e48-4f56-b387-1d65a492e75e",
      "paymentId": "3ac3de91-0d94-463d-8286-8060846f229d",
      "paymentDate": "2019-02-22T23:23:21.000Z",
      "amount": 10,
      "currency": "USD",
      "processedCurrency": "USD",
      "paymentCookieId": "4d83dd1b-b053-4a4d-99de-9a9e6e0405af",
      "linkedInvoicePaymentId": null,
      "success": true,
      "tableName": "INVOICE_PAYMENTS",
      "historyTableName": "INVOICE_PAYMENT_HISTORY"
    }
  }
]

Query Parameters

None.

Response

If successful, returns a status code of 200 and a list of audit logs with history.

These endpoints allow you to list all invoices or to search for a specific invoice. Note that these endpoints return shallow objects and thus the value 0 is returned for the amount, creditAdj, refundAdj and balance fields. In order to retrieve the actual data for these fields, additional endpoints (like retrieve invoice by id) would need to be invoked.

List invoices

Retrieve a list of all invoice records for this tenant.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/pagination

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/pagination"  
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

Long offset = 0L;
Long limit = 1L;
Invoices result = invoiceApi.getInvoices(offset, 
                                         limit, 
                                         AuditLevel.NONE, 
                                         requestOptions);
offset = 0
limit = 100

invoice.find_in_batches(offset,
                        limit,
                        options)
invoiceApi = killbill.api.InvoiceApi()

invoiceApi.get_invoices(api_key, api_secret)

Example Response:

[
  {
    "amount": 0,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "404a98a8-4dd8-4737-a39f-be871e916a8c",
    "invoiceDate": "2018-07-19",
    "targetDate": "2018-07-19",
    "invoiceNumber": "309",
    "balance": 0,
    "accountId": "8785164f-b5d7-4da1-9495-33f5105e8d80",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 0,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "903e55d3-8072-47f1-80fc-32857dbdbcc5",
    "invoiceDate": "2018-07-20",
    "targetDate": "2018-07-20",
    "invoiceNumber": "310",
    "balance": 0,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 0,
    "currency": "USD",
    "status": "VOID",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "18e9b3d9-9083-4725-9e8a-27d3a57c2e88",
    "invoiceDate": "2018-07-20",
    "targetDate": "2018-07-20",
    "invoiceNumber": "311",
    "balance": 0,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 0,
    "currency": "USD",
    "status": "DRAFT",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "c6fe2246-62e2-450d-b9fc-a27003771535",
    "invoiceDate": "2018-07-20",
    "targetDate": "2018-07-20",
    "invoiceNumber": "312",
    "balance": 0,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 0,
    "currency": "USD",
    "status": "DRAFT",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "d6c7b6b9-f048-4266-bde6-4c381e69f432",
    "invoiceDate": "2018-07-20",
    "targetDate": "2018-07-20",
    "invoiceNumber": "313",
    "balance": 0,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 0,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "71742c60-273f-4c91-8b8c-7555a3554b0a",
    "invoiceDate": "2018-07-20",
    "targetDate": "2018-07-20",
    "invoiceNumber": "314",
    "balance": 0,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  },
  {
    "amount": 0,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "e8032d7d-4354-46f7-82fa-8e635cc61fc5",
    "invoiceDate": "2018-07-20",
    "targetDate": "2018-07-20",
    "invoiceNumber": "315",
    "balance": 0,
    "accountId": "2ad52f53-85ae-408a-9879-32a7e59dd03d",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  }
]

Query Parameters

Name Type Required Default Description
offset long no 0 Starting index for items listed
limit long no 100 Maximum number of items to be listed
audit string no "NONE" Level of audit information to return: "NONE", "MINIMAL" (only inserts), or "FULL"

Response

If successful, returns a status code of 200 and a list of all invoices for this tenant.

Search invoices

Search for an invoice by a specified search string. If the search string is a number, it is compared to the invoiceNumber attribute. An exact match is required. Otherwise, it is compared to the following attributes: invoiceId, accountId, or currency. The operation returns all invoice records in which the search string matches all or part of any one of these attributes.

HTTP Request

GET http://127.0.0.1:8080/1.0/kb/invoices/search/{searchKey}

Example Request:

curl -v \
    -u admin:password \
    -H "X-Killbill-ApiKey: bob" \
    -H "X-Killbill-ApiSecret: lazar" \
    -H "Accept: application/json" \
    "http://127.0.0.1:8080/1.0/kb/invoices/search/404a98a8-4dd8-4737-a39f-be871e916a8c" 
import org.killbill.billing.client.api.gen.InvoiceApi;
protected InvoiceApi invoiceApi;

String searchKey = "1a49101b-305e-4b4d-8403-7377596407b6";

Long offset = 0L;
Long limit = 1L;

invoiceApi.searchInvoices(searchKey, 
                          offset,
                          limit, 
                          AuditLevel.NONE, 
                          requestOptions);
search_key = 'COMMITTED'
offset = 0
limit = 100

invoice.find_in_batches_by_search_key(search_key,
                                      offset,
                                      limit,
                                      options)
invoiceApi = killbill.api.InvoiceApi()
search_key = 'USD'

invoiceApi.search_invoices(search_key, api_key, api_secret)

Example Response:

[
  {
    "amount": 0,
    "currency": "USD",
    "status": "COMMITTED",
    "creditAdj": 0,
    "refundAdj": 0,
    "invoiceId": "404a98a8-4dd8-4737-a39f-be871e916a8c",
    "invoiceDate": "2018-07-19",
    "targetDate": "2018-07-19",
    "invoiceNumber": "309",
    "balance": 0,
    "accountId": "8785164f-b5d7-4da1-9495-33f5105e8d80",
    "bundleKeys": null,
    "credits": null,
    "items": [],
    "isParentInvoice": false,
    "parentInvoiceId": null,
    "parentAccountId": null,
    "auditLogs": []
  }
]

Query Parameters

Name Type Required Default Description
searchKey string yes none What you want to find
offset long none 0 Starting index for items listed
limit long none 100 Maximum number of items to return on this page
audit string no "NONE" Level of audit information to return

Audit information options are "NONE", "MINIMAL" (only inserts), or "FULL".

Response

If successful, returns a list of all invoices matched with the search key entered.